# Jane Street: June 2020
# Twenty Four Seven

# The grid is incomplete. Place numbers in some of the empty cells below so that in total the grid
# contains one 1, two 2’s, etc., up to seven 7’s. Furthermore, each row and column must contain
# exactly 4 numbers which sum to 20. Finally, the numbered cells must form a connected region*,
# but every 2-by-2 subsquare in the completed grid must contain at least one empty cell.

# The answer to this puzzle is the product of the areas of the connected groups of empty squares in the completed grid.

from z3 import *
from functools import reduce
import time

import constraints
import helper

tfs_array = (
    (0, 4, 0, 0, 0, 0, 0),
    (0, 0, 6, 3, 0, 0, 6),
    (0, 0, 0, 0, 0, 5, 5),
    (0, 0, 0, 4, 0, 0, 0),
    (4, 7, 0, 0, 0, 0, 0),
    (2, 0, 0, 7, 4, 0, 0),
    (0, 0, 0, 0, 0, 1, 0),
)

def one_to_seven(grid, c):
    s_grid_size = 7

    c.add(constraints.findNNs(grid,s_grid_size))

def row_col_four_twenty(grid, c):
    constraints.sum_of_rows(grid, c, 20)
    constraints.count_in_each_r_and_c(grid, c, 4)

s = Solver()

X = [[Int("x_%s_%s" % (i + 1, j + 1)) for j in range(7)] for i in range(7)]

one_to_seven(X, s)
row_col_four_twenty(X, s)

constraints.check_n_by_n_subgrid_empty_space(X, s, 2, 1)
constraints.check_within_range(X, s, 0, 7)

tfs_array_constr = [
    If(tfs_array[i][j] == 0, True, X[i][j] == tfs_array[i][j])
    for i in range(7)
    for j in range(7)
]

s.add(tfs_array_constr)

def calculate_answer(grid):
   print("Final Answer : ")
   print(reduce((lambda x,y: x*y), helper.count_region(grid, count_zero=True)))
   print("Execution Complete!!")

# enforce_cell_neighbours(X, s)
stats_to_print = ["decisions", "solve-eqs-steps",
                  "time", "num allocs", "memory"]
start_time = time.time_ns()
while True:
    if s.check() == sat:
        print("------------------------")
        # print(s.statistics().keys())
        m = s.model()
        print("stats for this run")
        stats = s.statistics()
        for stat in stats_to_print:
            if stat in stats.keys():
                print(stat, stats.get_key_value(stat))

        r = [[m.evaluate(X[i][j]).as_long() for j in range(7)] for i in range(7)]
        if len(helper.count_region(r, count_zero=False))==1:
            print("found solution")
            print_matrix(r)
            calculate_answer(r)
            break
        else:
            print("rerun")
            new_c = Not(And([X[i][j] == r[i][j]
                        for i in range(7) for j in range(7)]))
            s.add(new_c)

    else:
        print("failed to solve")
        break

end_time = time.time_ns()

print("elapsed time:", end_time-start_time)


from django.shortcuts import render, redirect, get_object_or_404
from django.views import View

from .cart_module import Cart
from .models import Order, OrderItem, DiscountCode
from product.models import Product

class CartDetailView(View):
    def get(self, request):
        cart = Cart(request)
        return render(request, "order/cart.html", {'cart':cart})

class CartAddView(View):
    def post(self, request, pk):
        product = get_object_or_404(Product, id=pk)
        size, color, quantity, price, discount_price = request.POST.get('size', '-'), \
            request.POST.get('color', '-'), request.POST.get('quantity'), \
            request.POST.get('price'), request.POST.get('discount_price')
        cart = Cart(request)
        cart.add(product, size, color, quantity, price, discount_price)
        return redirect('order:cart-detail')

class CartDeleteView(View):
    def get(self, request, id):
        cart = Cart(request)
        cart.delete(id)
        return redirect('order:cart-detail')

class OrderDetailView(View):
    def get(self, request, pk):
        order = get_object_or_404(Order, id=pk)
        return render(request, 'order/order-detail.html', {'order':order})

class OrderAddView(View):
    def get(self, request):
        cart = Cart(request)
        order = Order.objects.create(user=request.user, total_price=cart.total())
        for item in cart:
            OrderItem.objects.create(order=order, product=item['product'], size=item['size'], \
                color=item['color'], quantity=item['quantity'], price=item['price'])
        return redirect('order:order-detail', order.id)

class ApplyDiscountView(View):
    def post(self, request, pk):
        code = request.POST.get('discount_code')
        order = get_object_or_404(Order, id=pk)
        discount_code = get_object_or_404(DiscountCode, name=code)
        if discount_code.quantity == 0:
            return redirect('order:order-detail', order.id)
        order.total_price -= order.total_price*discount_code.discount/100
        order.save()
        discount_code.quantity -= 1
        discount_code.save()
        return redirect('order:order-detail', order.id)


import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
train = pd.read_csv("training.csv")
train = train.drop(['url'], axis=1)

x_train = train.iloc[:, 0:-1]
y_train = train.iloc[:, -1]

clf = RandomForestClassifier(n_estimators=100, random_state=0)
clf.fit(x_train, y_train)

test = pd.read_csv("testing.csv")
test = test.drop(['url'], axis=1)

x_test = test.iloc[:, 0:-1]
y_test = test.iloc[:, -1]
y_pred = clf.predict(x_test)

print("Number of test data points:", len(y_pred))
print("Accuracy: ",accuracy_score(y_test, y_pred))
print("Precision: ",precision_score(y_test, y_pred, pos_label='phishing'))
print("Recall: ",recall_score(y_test, y_pred, pos_label='phishing'))
print("F1 Score: ",f1_score(y_test, y_pred, pos_label='phishing'))


import tensorflow as tf
import kerastuner as kt
import os
import cv2
import random
import time
import numpy as np
import pickle
import h5py
import keras
from sklearn.model_selection import train_test_split
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, Activation, Flatten, MaxPooling2D, Dropout

DATADIR = "faces"
IMG_SIZE = 128
CATEGORIES = ["Akif", "Ali", "Ela", "Fatih", "Furkan"]
num_classes = 5

def create_training_data ():
    training_data = []
    for category in CATEGORIES:
        path = os.path.join (DATADIR, category)
        class_num = CATEGORIES.index (category)
        for img in os.listdir (path):
            try:
                img_array = cv2.imread (os.path.join (path, img), cv2.IMREAD_GRAYSCALE)
                new_array = cv2.resize (img_array, (IMG_SIZE, IMG_SIZE))
                training_data.append ([new_array, class_num])
            except Exception as e:
                print (e)
                pass
    random.shuffle (training_data)
    return training_data

training_data = create_training_data ()
[training_data, test_data] = train_test_split (training_data)
X = []
y = []

for features, label in training_data:
    X.append (features)
    y.append (label)
X_test = []
y_test = []
for features, label in test_data:
    X_test.append (features)
    y_test.append (label)
X = np.array (X).reshape (-1, IMG_SIZE, IMG_SIZE, 1)
X_test = np.array (X_test).reshape (-1, IMG_SIZE, IMG_SIZE, 1)
y = np.array (y)
y_test = np.array (y_test)

def build_model(hp):
    model=Sequential()
    input_kernel=hp.Choice('input_kernel',[3,5,11])
    input_activation= hp.Choice('input_activation',['softmax','softplus','softsign','relu','tanh','sigmoid','hard_sigmoid','linear'])
    input_units=hp.Choice('input_units',[20,32,64,128,256,384,512])
    input_stride=hp.Choice('input_stride',[1,2,3,4])
    #input_padding=hp.Choice('input_padding',['same','valid'])
    model.add(Conv2D(input_units,(input_kernel,input_kernel),strides=(input_stride,input_stride),padding='same',input_shape=(IMG_SIZE,IMG_SIZE,1),activation=input_activation))

    for i in range(hp.Int("Conv_Layer_Groups",min_value=1,max_value=2)):
        for j in range(hp.Int(f'Conv_Layer_Group_{i}_Layers',min_value=1,max_value=4)):
            conv_units=hp.Choice(f'Conv_Group_{i}_Layer_{j}_units',[20,32,64,128,256,384,512])
            conv_kernel=hp.Choice(f'Conv_Group_{i}_Layer_{j}_kernel',[3,5,11])
            conv_activation= hp.Choice(f'Conv_Group_{i}_Layer_{j}_activation',['softmax','softplus','softsign','relu','tanh','sigmoid','hard_sigmoid','linear'])
            conv_stride=hp.Choice(f'Conv_Group_{i}_Layer_{j}_stride',[1,2,3,4])
            model.add(Conv2D(conv_units,kernel_size=(conv_kernel,conv_kernel),strides=(conv_stride,conv_stride),activation=conv_activation,padding='same'))

        model.add(MaxPooling2D(pool_size=(2,2)))

    model.add(Flatten())

    for a in range(hp.Int('Dense_Layers',min_value=1,max_value=2)):
        dense_units=hp.Choice(f'Dense_Layer_{a}_units',[512,1024,2048,4096])
        dense_activation=hp.Choice(f'Dense_Layer_{a}_activation',['softmax','softplus','softsign','relu','tanh','sigmoid','hard_sigmoid','linear'])
        model.add(Dense(units=dense_units,activation=dense_activation))
        drop_rate= hp.Choice(f'Dense_Layer_{a}_dropout_droprate',  [ 0.05, 0.1, 0.15, 0.2,0.25, 0.3, 0.35, 0.40, 0.45, 0.50])
        model.add(Dropout(drop_rate))

    model.add(Dense(5))
    model.add(Activation('softmax'))

    loss='sparse_categorical_crossentropy'

    model.compile(optimizer=tf.keras.optimizers.Adam(hp.Float('learning_rate', 1e-4, 1e-2, sampling='log')),loss='sparse_categorical_crossentropy',metrics=['accuracy'])
    print(model.summary())
    return model

LOG_DIR = f"{int (time.time ())}"
tuner=kt.RandomSearch
tuner = kt.RandomSearch(
    build_model,
    objective='val_acc',
    max_trials=2,
    executions_per_trial=1,
    directory=LOG_DIR)

tuner.search(x=X,
             y=y,
             verbose=2, # just slapping this here bc jupyter notebook. The console out was getting messy.
             epochs=1,
             batch_size=64,
             validation_data=(X_test,y_test))

print (tuner.get_best_hyperparameters () [0].values)
print (tuner.results_summary ())
print (tuner.get_best_models () [0].summary ())
model=tuner.get_best_models()[0]
tf.keras.models.save_model(model,'mymodel.h5')
new_model=tf.keras.models.load_model('mymodel.h5')


import json
from urllib.parse import urlparse
from stark.codecs import BaseCodec
from stark.codecs.jsonschema import JSONSchemaEncoder
from stark.schema import (
    SchemaDefinitions,
    JSONSchema,
    String,
    Choice,
    Object,
    Any,
    Reference,
    Array,
    Boolean,
    is_schema
)
from stark.compat import dict_type
from stark.document import Document

SchemaRef = Object(
    properties={"$ref": String(pattern="^#/components/schemas/")}
)

RequestBodyRef = Object(
    properties={"$ref": String(pattern="^#/components/requestBodies/")}
)

ResponseRef = Object(
    properties={"$ref": String(pattern="^#/components/responses/")}
)

openapi_definitions = SchemaDefinitions()

OpenAPI = Object(
    title="OpenAPI",
    properties={
        "openapi": String(),
        "info": Reference("Info", definitions=openapi_definitions),
        "servers": Array(items=Reference("Server", definitions=openapi_definitions)),
        "paths": Reference("Paths", definitions=openapi_definitions),
        "components": Reference("Components", definitions=openapi_definitions),
        "security": Array(items=Reference("SecurityRequirement", definitions=openapi_definitions)),
        "tags": Array(items=Reference("Tag", definitions=openapi_definitions)),
        "externalDocs": Reference("ExternalDocumentation", definitions=openapi_definitions),
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
    required=["openapi", "info", "paths"]
)

openapi_definitions["JSONSchema"] = JSONSchema

openapi_definitions["Info"] = Object(
    properties={
        "title": String(allow_blank=True),
        "description": String(format="textarea", allow_blank=True),
        "termsOfService": String(format="url", allow_blank=True),
        "contact": Reference("Contact", definitions=openapi_definitions),
        "license": Reference("License", definitions=openapi_definitions),
        "version": String(allow_blank=True),
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
    required=["title", "version"]
)

openapi_definitions["Contact"] = Object(
    properties={
        "name": String(),
        "url": String(format="url"),
        "email": String(format="email"),
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
)

openapi_definitions["License"] = Object(
    properties={
        "name": String(),
        "url": String(format="url"),
    },
    required=["name"],
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
)

openapi_definitions["Server"] = Object(
    properties={
        "url": String(allow_blank=True),
        "description": String(format="textarea"),
        "variables": Object(additional_properties=Reference("ServerVariable", definitions=openapi_definitions)),
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
    required=["url"]
)

openapi_definitions["ServerVariable"] = Object(
    properties={
        "enum": Array(items=String()),
        "default": String(),
        "description": String(format="textarea"),
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
    required=["default"]
)

openapi_definitions["Paths"] = Object(
    pattern_properties={
        "^/": Reference("Path", definitions=openapi_definitions),
        "^x-": Any(),
    },
    additional_properties=False,
)

openapi_definitions["Path"] = Object(
    properties={
        "summary": String(),
        "description": String(format="textarea"),
        "get": Reference("Operation", definitions=openapi_definitions),
        "put": Reference("Operation", definitions=openapi_definitions),
        "post": Reference("Operation", definitions=openapi_definitions),
        "delete": Reference("Operation", definitions=openapi_definitions),
        "options": Reference("Operation", definitions=openapi_definitions),
        "head": Reference("Operation", definitions=openapi_definitions),
        "patch": Reference("Operation", definitions=openapi_definitions),
        "trace": Reference("Operation", definitions=openapi_definitions),
        "servers": Array(items=Reference("Server", definitions=openapi_definitions)),
        "parameters": Array(items=Reference("Parameter", definitions=openapi_definitions))  # TODO: | ReferenceObject
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
)

openapi_definitions["Operation"] = Object(
    properties={
        "tags": Array(items=String()),
        "summary": String(),
        "description": String(format="textarea"),
        "externalDocs": Reference("ExternalDocumentation", definitions=openapi_definitions),
        "operationId": String(),
        "parameters": Array(items=Reference("Parameter", definitions=openapi_definitions)),
        # TODO: | ReferenceObject
        "requestBody": RequestBodyRef | Reference("RequestBody", definitions=openapi_definitions),
        # TODO: RequestBody | ReferenceObject
        "responses": Reference("Responses", definitions=openapi_definitions),
        # TODO: "callbacks"
        "deprecated": Boolean(),
        "security": Array(Reference("SecurityRequirement", definitions=openapi_definitions)),
        "servers": Array(items=Reference("Server", definitions=openapi_definitions)),
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
)

openapi_definitions["ExternalDocumentation"] = Object(
    properties={
        "description": String(format="textarea"),
        "url": String(format="url"),
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
    required=["url"]
)

openapi_definitions["Parameter"] = Object(
    properties={
        "name": String(),
        "in": Choice(choices=["query", "header", "path", "cookie"]),
        "description": String(format="textarea"),
        "required": Boolean(),
        "deprecated": Boolean(),
        "allowEmptyValue": Boolean(),
        "style": String(),
        "schema": Reference("JSONSchema", definitions=openapi_definitions) | SchemaRef,
        "example": Any(),
        # TODO: Other fields
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
    required=["name", "in"]
)

openapi_definitions["RequestBody"] = Object(
    properties={
        "description": String(),
        "content": Object(additional_properties=Reference("MediaType", definitions=openapi_definitions)),
        "required": Boolean(),
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
)

openapi_definitions["Responses"] = Object(
    properties={
        "default": Reference("Response", definitions=openapi_definitions) | ResponseRef,
    },
    pattern_properties={
        "^([1-5][0-9][0-9]|[1-5]XX)$": Reference("Response", definitions=openapi_definitions) | ResponseRef,
        "^x-": Any(),
    },
    additional_properties=False,
)

openapi_definitions["Response"] = Object(
    properties={
        "description": String(),
        "content": Object(additional_properties=Reference("MediaType", definitions=openapi_definitions)),
        "headers": Object(additional_properties=Reference("Header", definitions=openapi_definitions)),
        # TODO: Header | ReferenceObject
        # TODO: links
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
)

openapi_definitions["MediaType"] = Object(
    properties={
        "schema": Reference("JSONSchema", definitions=openapi_definitions) | SchemaRef,
        "example": Any(),
        # TODO "examples", "encoding"
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
)

openapi_definitions["Header"] = Object(
    properties={
        "description": String(format="textarea"),
        "required": Boolean(),
        "deprecated": Boolean(),
        "allowEmptyValue": Boolean(),
        "style": String(),
        "schema": Reference("JSONSchema", definitions=openapi_definitions) | SchemaRef,
        "example": Any(),
        # TODO: Other fields
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False
)

openapi_definitions["Components"] = Object(
    properties={
        "schemas": Object(additional_properties=Reference("JSONSchema", definitions=openapi_definitions)),
        "responses": Object(additional_properties=Reference("Response", definitions=openapi_definitions)),
        "parameters": Object(additional_properties=Reference("Parameter", definitions=openapi_definitions)),
        "requestBodies": Object(additional_properties=Reference("RequestBody", definitions=openapi_definitions)),
        "securitySchemes": Object(additional_properties=Reference("SecurityScheme", definitions=openapi_definitions)),
        # TODO: Other fields
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
)

openapi_definitions["Tag"] = Object(
    properties={
        "name": String(),
        "description": String(format="textarea"),
        "externalDocs": Reference("ExternalDocumentation", definitions=openapi_definitions),
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
    required=["name"]
)

openapi_definitions["SecurityRequirement"] = Object(
    additional_properties=Array(items=String()),
)

openapi_definitions["SecurityScheme"] = Object(
    properties={
        "type": Choice(choices=["apiKey", "http", "oauth2", "openIdConnect"]),
        "description": String(format="textarea"),
        "name": String(),
        "in": Choice(choices=["query", "header", "cookie"]),
        "scheme": String(),
        "bearerFormat": String(),
        "flows": Any(),  # TODO: OAuthFlows
        "openIdConnectUrl": String(),
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
    required=["type"]
)

METHODS = [
    "get", "put", "post", "delete", "options", "head", "patch", "trace"
]

class OpenAPICodec(BaseCodec):
    media_type = "application/vnd.oai.openapi"
    format = "openapi"

    def encode(self, document, **options):
        if not isinstance(document, Document):
            error = "Document instance expected."
            raise TypeError(error)

        definitions = {}
        codec = JSONSchemaEncoder(
            definitions,
            definition_base="components/schemas"
        )
        paths = self.get_paths(document, codec=codec)
        data = self.validate_document(document, definitions, paths)
        kwargs = {
            "ensure_ascii": False,
            "indent": 4,
            "separators": (",", ": ")
        }
        return json.dumps(data, **kwargs).encode("utf-8")

    @staticmethod
    def validate_document(document, definitions, paths):
        openapi = OpenAPI.validate({
            "openapi": "3.0.0",
            "info": {
                "version": document.version,
                "title": document.title,
                "description": document.description
            },
            "servers": [{
                "url": document.url
            }],
            "paths": paths
        })

        if definitions:
            openapi["components"] = {"schemas": dict(definitions)}

        if not document.url:
            openapi.pop("servers")

        return openapi

    def get_paths(self, document, codec):
        paths = dict_type()

        for link, name, sections in document.walk_links():
            path = urlparse(link.url).path
            operation_id = link.name
            method = link.method.lower()

            if path not in paths:
                paths[path] = {}
            paths[path][method] = self.get_operation(link, operation_id, codec)

        return paths

    def get_operation(self, link, operation_id, codec):
        operation = {
            "operationId": operation_id
        }
        if link.title:
            operation["summary"] = link.title
        if link.description:
            operation["description"] = link.description
        tags = link.tags if link.tags else []
        if tags:
            operation["tags"] = tags
        if link.path_fields or link.query_fields:
            operation["parameters"] = [
                self.get_parameter(field, codec) for field in
                link.path_fields + link.query_fields
            ]
        if link.body_field:
            schema = link.body_field.schema
            if schema is None:
                content_info = {}
            else:
                content_info = {
                    "schema": codec.encode(Reference(to=schema))
                }
            operation["requestBody"] = {
                "content": {
                    link.encoding: content_info
                }
            }
        if link.response is not None:
            schema = link.response.schema
            if is_schema(schema):
                schema = Reference(to=schema)
            response = {
                "description": "",
            }
            if schema is not None:
                response["content"] = {
                    link.response.encoding: {
                        "schema": codec.encode(schema)
                    }
                }
            operation["responses"] = {
                str(link.response.status_code): response
            }
        return operation

    @staticmethod
    def get_parameter(field, codec):
        parameter = {
            "name": field.name,
            "in": field.location
        }
        if field.required:
            parameter["required"] = True
        if field.description:
            parameter["description"] = field.description
        if field.schema:
            parameter["schema"] = codec.encode(field.schema)
        return parameter


"""Initialize drone."""
import os
import sys
curDir = os.path.dirname(__file__)
# this will return parent directory.
parentDir = os.path.abspath(os.path.join(curDir, os.pardir))
# this will return parent directory.
superParentDir = os.path.abspath(os.path.join(parentDir, os.pardir))
sys.path.insert(0, superParentDir)

from flock_drone.mechanics.main import CENTRAL_SERVER, RES_CS, RES_DRONE, DRONE
from hydra import SCHEMA, Resource
from flock_drone.mechanics.main import get_drone, get_drone_default, update_drone, get_controller_location, update_drone_at_controller
from flock_drone.mechanics.datastream import gen_Datastream, add_datastream
from flock_drone.settings import CENTRAL_SERVER_URL

def init_drone_locally():
    """Initialize the drone locally with Negative identifier."""
    drone = get_drone_default()
    location = get_controller_location()["Location"]

    drone["State"]["Position"] = location
    add_drone_locally(drone)
    print("Drone initalized locally!")

def add_drone_locally(drone):
    """Add the drone object to the central server and return Id."""
    try:
        add_drone_ = RES_DRONE.find_suitable_operation(
            SCHEMA.AddAction, DRONE.Drone)
        resp, body = add_drone_(drone)
        assert resp.status in [200, 201], "%s %s" % (resp.status, resp.reason)
        drone_id = resp['location'].split("/")[-1]

        return drone_id
    except Exception as e:
        print(e)
        print("Using default id instead")
        return -1000

def add_drone(drone):
    """Add the drone object to the central server and return Id."""
    try:
        add_drone_ = RES_CS.find_suitable_operation(
            SCHEMA.AddAction, CENTRAL_SERVER.Drone)
        resp, body = add_drone_(drone)
        assert resp.status in [200, 201], "%s %s" % (resp.status, resp.reason)
        drone_id = resp['location'].split("/")[-1]
        print(drone_id)
        return drone_id
    except Exception as e:
        print(e)
        print("Using default id instead")
        return -1000

def remove_drone(drone_id):
    """Remove previous drone object from the central server."""
    try:
        i = Resource.from_iri(CENTRAL_SERVER_URL +
                              "/api/DroneCollection" + str(drone_id))
        resp, _ = i.find_suitable_operation(SCHEMA.DeleteAction, None)()
        if resp.status // 100 != 2:
            return "error deleting <%s>" % i.identifier
        else:
            return "successfully deleted <%s>" % i.identifier
    except Exception as e:
        print(e)
        return {404: "Resource with Id %s not found!" % (drone_id,)}

def init_drone():
    """Initialize drone."""
    # Add drone to the central_server and get identifier
    init_drone_locally()

    drone = get_drone()
    drone_id = drone["DroneID"]

    # If drone has default negative id initialize else remove old drone and then inintialize.
    if drone_id == -1000:
        drone_id = add_drone(drone)
    else:
        # Remove old drone
        remove_drone(drone_id)
        print("Previous drone successfully deleted from the central server.")
        drone_id = add_drone(drone)

    # Update the drone at localhost
    drone["DroneID"] = drone_id

    update_drone(drone)
    update_drone_at_controller(drone, drone_id)

    print("Drone initialized successfully!")

def init_datastream_locally():
    """Initialize the datasteam locally."""
    drone = get_drone()
    id_ = drone["DroneID"]
    position = drone["State"]["Position"]
    datastream = gen_Datastream("0", position, id_)
    add_datastream(datastream)
    print("Datastream initialized locally")

if __name__ == "__main__":
    init_drone()
    init_datastream_locally()


import re

from django.utils.text import compress_string
from django.utils.cache import patch_vary_headers

from django import http

try:
    import levelhub.settings as settings

    XS_SHARING_ALLOWED_ORIGINS = settings.XS_SHARING_ALLOWED_ORIGINS
    XS_SHARING_ALLOWED_METHODS = settings.XS_SHARING_ALLOWED_METHODS
except:
    XS_SHARING_ALLOWED_ORIGINS = '*'
    XS_SHARING_ALLOWED_METHODS = ['POST', 'GET', 'OPTIONS', 'PUT', 'DELETE']

class XsSharing(object):
    """
        This middleware allows cross-domain XHR using the html5 postMessage API.

        Access-Control-Allow-Origin: http://foo.example
        Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
    """

    def process_request(self, request):

        if 'HTTP_ORIGIN' in request.META:
            origin = request.META['HTTP_ORIGIN']
        elif 'HTTP_X_CLIENT_IP' in request.META:
            origin = request.META['HTTP_X_CLIENT_IP']
        else:
            origin = request.META['HTTP_HOST']

        if 'HTTP_ACCESS_CONTROL_REQUEST_METHOD' in request.META:
            response = http.HttpResponse()
            response['Access-Control-Allow-Origin'] = origin  # XS_SHARING_ALLOWED_ORIGINS
            response['Access-Control-Allow-Methods'] = ",".join(XS_SHARING_ALLOWED_METHODS)
            response['Access-Control-Allow-Credentials'] = 'true'
            if 'HTTP_ACCESS_CONTROL_REQUEST_HEADERS' in request.META:
                response['Access-Control-Allow-Headers'] = request.META['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']
            response['Access-Control-Max-Age'] = '0'

            return response

        return None

    def process_response(self, request, response):

        # Avoid unnecessary work
        if response.has_header('Access-Control-Allow-Origin'):
            return response

        if 'HTTP_ORIGIN' in request.META:
            origin = request.META['HTTP_ORIGIN']
        elif 'HTTP_X_CLIENT_IP' in request.META:
            origin = request.META['HTTP_X_CLIENT_IP']
        else:
            origin = request.META['HTTP_HOST']

        response['Access-Control-Allow-Origin'] = origin  # XS_SHARING_ALLOWED_ORIGINS
        response['Access-Control-Allow-Methods'] = ",".join(XS_SHARING_ALLOWED_METHODS)
        response['Access-Control-Allow-Credentials'] = 'true'
        if 'HTTP_ACCESS_CONTROL_REQUEST_HEADERS' in request.META:
            response['Access-Control-Allow-Headers'] = request.META['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']
        response['Access-Control-Max-Age'] = '0'

        return response


from stagesepx.cutter import VideoCutter
from stagesepx.classifier import SVMClassifier
from stagesepx.reporter import Reporter
from stagesepx.hook import (
    ExampleHook,
    IgnoreHook,
    CropHook,
    FrameSaveHook,
    RefineHook,
    InterestPointHook,
    TemplateCompareHook,
    InvalidFrameDetectHook,
    _AreaBaseHook,
)

import os

PROJECT_PATH = os.path.dirname(os.path.dirname(__file__))
VIDEO_PATH = os.path.join(PROJECT_PATH, "demo.mp4")
IMAGE_NAME = "demo.jpg"
IMAGE_PATH = os.path.join(PROJECT_PATH, IMAGE_NAME)
assert os.path.isfile(IMAGE_PATH)

def test_others():
    assert _AreaBaseHook.convert(200, 200, 100, 100) == (100, 100)
    try:
        InvalidFrameDetectHook()
    except DeprecationWarning:
        pass

def test_hook():
    # init hook
    hook = ExampleHook()
    hook1 = ExampleHook()
    hook2 = IgnoreHook(size=(0.5, 0.5))
    frame_home = os.path.join(PROJECT_PATH, "frame_save_dir")
    hook3 = FrameSaveHook(frame_home)
    hook4 = CropHook(size=(0.5, 0.5), offset=(0.0, 0.5))
    hook5 = RefineHook()
    hook6 = InterestPointHook()
    hook7 = TemplateCompareHook({"amazon": IMAGE_PATH})

    # --- cutter ---
    cutter = VideoCutter(compress_rate=0.9)
    # add hook
    cutter.add_hook(hook)
    cutter.add_hook(hook1)
    cutter.add_hook(hook2)
    cutter.add_hook(hook3)
    cutter.add_hook(hook4)
    cutter.add_hook(hook5)
    cutter.add_hook(hook6)
    cutter.add_hook(hook7)

    res = cutter.cut(VIDEO_PATH)
    stable, unstable = res.get_range()
    assert len(stable) == 2, "count of stable range is not correct"

    data_home = res.pick_and_save(stable, 5)
    assert os.path.isdir(data_home), "result dir not existed"

    # --- classify ---
    cl = SVMClassifier()
    cl.load(data_home)
    cl.train()
    classify_result = cl.classify(VIDEO_PATH, stable)

    # --- draw ---
    r = Reporter()
    report_path = os.path.join(data_home, "report.html")
    r.draw(classify_result, report_path=report_path, cut_result=res)
    assert os.path.isfile(report_path)

    # hook check
    assert os.path.isdir(frame_home)
    assert hook6.result
    assert hook7.result


import httphelper
import requests
import quandl, pandas as pd

quandl_partialurl = 'https://www.quandl.com/api/v3/datasets/WIKI/{}/data.json?start_date={}&api_key={}'
quandl_fullurl = 'https://www.quandl.com/api/v3/datasets/WIKI/{}/data.json?&api_key={}'

def load_historicdata(symbol):
    url = quandl_fullurl.format(symbol, quandl.ApiConfig.api_key)
    return __process_request(url)

def load_partialhistoricdata(symbol, startdate):
    url = quandl_partialurl.format(symbol, startdate.strftime('%Y-%m-%d'), quandl.ApiConfig.api_key)
    # print(url)
    return __process_request(url)

def __process_request(url):

    #jsn = requests.get(url).json()
    jsn = httphelper.get_httprequest(url).json()

    data = jsn['dataset_data']['data']
    cln = jsn['dataset_data']['column_names']
    df = pd.DataFrame(data = data, columns = cln)
    df.set_index('Date', inplace=True)
    df.index = df.index.astype('M')
    df = df.sort_index()

    return df


from __future__ import print_function

# system imports
from datetime import datetime, timedelta
import urllib
try:
	# noinspection PyUnresolvedReferences
	from typing import Callable, Optional, List, Tuple  # pylint: disable=unused-import
except ImportError:
	pass

# enigma2 imports
from Components.Sources.List import List as ListSource
from Components.Sources.Boolean import Boolean
from Components.ActionMap import ActionMap, NumberActionMap
from Components.config import config, configfile
from Components.Label import Label
from Components.ScrollLabel import ScrollLabel
from Components.Slider import Slider
from Components.ServiceEventTracker import InfoBarBase
from Components.Input import Input
from Components.MenuList import MenuList
from Components.Pixmap import Pixmap
from Components.GUIComponent import GUIComponent
from Screens.InfoBarGenerics import InfoBarPlugins, InfoBarExtensions, \
	InfoBarNotifications, InfoBarAudioSelection, InfoBarSubtitleSupport, InfoBarSummary
from Screens.Screen import Screen
from Screens.MessageBox import MessageBox
from Screens.MinuteInput import MinuteInput
from Screens.ChoiceBox import ChoiceBox
from Screens.InputBox import InputBox
from Tools.LoadPixmap import LoadPixmap
from Tools.Directories import resolveFilename, SCOPE_CURRENT_SKIN, SCOPE_SKIN, SCOPE_SYSETC, SCOPE_CURRENT_PLUGIN

# enigma2 core imports
from enigma import eListboxPythonMultiContent, RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_VALIGN_CENTER, \
	eLabel, eSize, ePoint
from enigma import eServiceReference
from skin import parseFont, parseColor

# plugin imports
from .layer import eTimer
from .common import NumberEnter
from .utils import trace, tdSec, secTd, syncTime, APIException, APIWrongPin, EPG, timeit
from .api.abstract_api import AbstractStream
from .loc import translate as _
from .common import ShowHideScreen, AutoAudioSelection, MainMenuScreen
from .standby import standbyNotifier
from .cache import LiveEpgWorker
from .lib.epg import EpgProgress
from .lib.tv import SortOrderSettings, Picon

SKIN_PATH = resolveFilename(SCOPE_SKIN, 'IPtvDream')
ENIGMA_CONF_PATH = resolveFilename(SCOPE_SYSETC, 'enigma2')
EPGMAP_PATH = resolveFilename(SCOPE_SYSETC, 'iptvdream')

rec_png = LoadPixmap(cached=True, path=SKIN_PATH + '/rec.png')
EPG_UPDATE_INTERVAL = 60  # Seconds, in channel list.
PROGRESS_TIMER = 1000*60  # Update progress in infobar.
PROGRESS_SIZE = 500
ARCHIVE_TIME_FIX = 5  # sec. When archive paused, we could miss some video

class IPtvDreamStreamPlayer(
		ShowHideScreen, AutoAudioSelection, MainMenuScreen,
		InfoBarBase, InfoBarPlugins, InfoBarExtensions,
		InfoBarNotifications, InfoBarAudioSelection, InfoBarSubtitleSupport):
	"""
	:type channels: IPtvDreamChannels
	:type db: AbstractStream
	"""

	ALLOW_SUSPEND = True

	def __init__(self, session, db):
		super(IPtvDreamStreamPlayer, self).__init__(session)
		InfoBarBase.__init__(self, steal_current_service=True)
		InfoBarExtensions.__init__(self)
		InfoBarPlugins.__init__(self)
		InfoBarNotifications.__init__(self)
		InfoBarAudioSelection.__init__(self)
		InfoBarSubtitleSupport.__init__(self)

		trace("start stream player")
		self.db = db
		from .manager import manager
		self.cfg = manager.getConfig(self.db.NAME)
		self.cid = None

		standbyNotifier.onStandbyChanged.append(self.standbyChanged)
		self.onClose.append(lambda: standbyNotifier.onStandbyChanged.remove(self.standbyChanged))

		self.channels = self.session.instantiateDialog(IPtvDreamChannels, self.db, self)
		self.onFirstExecBegin.append(self.start)

		self.setTitle(self.db.NAME)
		self["channelName"] = Label("")
		# Epg widgets
		self["currentName"] = Label("")
		self["nextName"] = Label("")
		self["currentTime"] = Label("")
		self["nextTime"] = Label("")
		self["currentDuration"] = Label("")
		self["nextDuration"] = Label("")
		self["progressBar"] = Slider(0, PROGRESS_SIZE)
		# Buttons
		self["key_red"] = Label(_("Archive"))
		self["key_green"] = Label(_("Settings"))
		self["key_yellow"] = Label(_("Audio"))
		self["key_blue"] = Label(_("Extensions"))

		# TODO: think more
		self["archiveDate"] = Label("")
		self["inArchive"] = Boolean(False)

		self["picon"] = Pixmap()
		self._picon = Picon(self["picon"])

		self["provider"] = Pixmap()
		icon_path = resolveFilename(SCOPE_CURRENT_PLUGIN, 'Extensions/IPtvDream/logo/%s.png' % self.db.NAME)
		self.onFirstExecBegin.insert(0, lambda: self["provider"].instance.setPixmap(LoadPixmap(icon_path)))

		# TODO: ActionMap add help.
		self["actions"] = ActionMap(["IPtvDreamInfobarActions", "ColorActions", "OkCancelActions"], {
				"cancel": self.confirmExit,
				"closePlugin": self.exit,
				"openVideos": self.openVod,
				"red": self.showEpg,
				"green": self.openSettings,
				"openServiceList": self.showList,
				"zapUp": self.previousChannel,
				"zapDown": self.nextChannel,
				"historyNext": self.historyNext,
				"historyBack": self.historyBack,
				"showEPGList": self.showEpg,
			})

		self["live_actions"] = ActionMap(["IPtvDreamLiveActions"], {
				"zapUp": self.previousChannel,
				"zapDown": self.nextChannel,
			}, -1)

		self["archive_actions"] = ActionMap(["IPtvDreamArchiveActions", "NumberActions"], {
				"exitArchive": self.exitArchive,
				"playpause": self.playPauseArchive,
				"play": lambda: self.playPauseArchive(True, False),
				"pause": lambda: self.playPauseArchive(False, True),
				"seekForward": self.archiveSeekFwd,
				"seekBackward": self.archiveSeekRwd,
				"1": lambda: self.jump(1),
				"3": lambda: self.jump(3),
				"4": lambda: self.jump(4),
				"6": lambda: self.jump(6),
				"7": lambda: self.jump(7),
				"9": lambda: self.jump(9),
			}, -1)

		self["number_actions"] = NumberActionMap(["NumberActions"], {
				"1": self.keyNumberGlobal,
				"2": self.keyNumberGlobal,
				"3": self.keyNumberGlobal,
				"4": self.keyNumberGlobal,
				"5": self.keyNumberGlobal,
				"6": self.keyNumberGlobal,
				"7": self.keyNumberGlobal,
				"8": self.keyNumberGlobal,
				"9": self.keyNumberGlobal,
				"0": self.keyNumberGlobal,
			})

		self.currentEpg = None
		self.epgTimer = eTimer()
		self.epgProgressTimer = eTimer()
		self.epgTimer.callback.append(self.epgEvent)
		self.epgProgressTimer.callback.append(self.epgUpdateProgress)

		self.archive_pause = None
		self.shift = 0

	# Init and destroy

	def start(self):
		trace("player start")
		self.showList()

	def exit(self, ret=None):
		self.channels.saveQuery()
		self.session.deleteDialog(self.channels)
		self.close(ret)

	def confirmExit(self):
		def cb(ret):
			if ret:
				self.exit()
		self.session.openWithCallback(cb, MessageBox, _("Exit plugin?"), MessageBox.TYPE_YESNO)

	# Play

	def play(self, cid):
		trace("play cid =", cid)

		self.cid = cid
		self.session.nav.stopService()
		if cid is None:
			return

		if self.db.channels[cid].is_protected:
			trace("protected by api")
			code = self.cfg.parental_code.value
			if code:
				trace("using saved code")
				self.getUrl(code)
			else:
				self.enterPin()
		else:
			self.getUrl(None)

	def enterPin(self):
		self.session.openWithCallback(
				self.getUrl, InputBox, title=_("Enter protect password"),
				windowTitle=_("Channel Locked"), type=Input.PIN)

	def getUrl(self, pin):
		try:
			url = self.db.getStreamUrl(self.cid, pin, self.time())
		except APIWrongPin:
			self.session.openWithCallback(
					lambda ret: self.enterPin(), MessageBox, _("Wrong pin!"),
					MessageBox.TYPE_ERROR, timeout=10, enable_input=False)
			return
		except APIException as e:
			self.showError(_("Error while getting stream url:") + str(e))
			self.updateLabels()
			return

		self.playUrl(url)

	# Player

	def playUrl(self, url):
		cid = self.cid
		if self.cfg.use_hlsgw.value:
			url = "http://localhost:7001/url=%s" % urllib.quote(url)
		trace("play", url)
		ref = eServiceReference(int(self.cfg.playerid.value), 0, url)
		ref.setName(self.db.channels[cid].name)
		ref.setData(1, 1)
		self.session.nav.playService(ref)
		self.updateLabels()

	def updateLabels(self):
		cid = self.cid
		self["channelName"].setText("%d. %s" % (self.db.channels[cid].number, self.db.channels[cid].name))
		self._picon.setIcon(self.db.getPiconUrl(cid))
		self.epgEvent()

	def standbyChanged(self, sleep):
		if sleep:
			trace("entered standby")
			if self.shift and not self.archive_pause:
				self.playPauseArchive()
			else:
				self.session.nav.stopService()
		else:
			trace("exited standby")
			if self.shift:
				self.playPauseArchive()
			else:
				self.play(self.cid)

	# Archive

	def setArchiveShift(self, time_shift):
		self.shift = time_shift
		if time_shift:
			self.archive_pause = None
			self["live_actions"].setEnabled(False)
			self["number_actions"].setEnabled(False)
			self["archive_actions"].setEnabled(True)
			self["inArchive"].setBoolean(True)
		else:
			self["archive_actions"].setEnabled(False)
			self["live_actions"].setEnabled(True)
			self["number_actions"].setEnabled(True)
			self["inArchive"].setBoolean(False)

	def time(self):
		if self.shift:
			return syncTime() + secTd(self.shift)
		return None

	def archiveSeekFwd(self):
		self.session.openWithCallback(self.fwdJumpMinutes, MinuteInput)

	def archiveSeekRwd(self):
		self.session.openWithCallback(self.rwdJumpMinutes, MinuteInput)

	def fwdJumpMinutes(self, minutes):
		return self.fwdJump(minutes * 60)

	def rwdJumpMinutes(self, minutes):
		return self.rwdJump(minutes * 60)

	def fwdJump(self, seconds):
		trace("fwdSeek", seconds)
		self.shift += seconds
		if self.shift > 0:
			self.setArchiveShift(0)
		self.play(self.cid)

	def rwdJump(self, seconds):
		trace("rwdSeek", seconds)
		self.shift -= seconds
		self.play(self.cid)

	def jump(self, n):
		try:
			t13 = config.seek.selfdefined_13.value
			t46 = config.seek.selfdefined_46.value
			t79 = config.seek.selfdefined_79.value
		except AttributeError:
			t13 = 15
			t46 = 60
			t79 = 300

		t = {1: -t13, 3: t13, 4: -t46, 6: t46, 7: -t79, 9: t79}[n]
		if t < 0:
			self.rwdJump(abs(t))
		else:
			self.fwdJump(abs(t))

	def playPauseArchive(self, play=True, pause=True):
		if self.archive_pause and play:
			# do unPause
			self.shift -= tdSec(syncTime()-self.archive_pause)-ARCHIVE_TIME_FIX
			self.archive_pause = None
			self.play(self.cid)
			self.unlockShow()
		elif pause:
			# do pause
			self.archive_pause = syncTime()
			# try to pause and freeze the picture, otherwise stop and show black screen
			service = self.session.nav.getCurrentService()
			pauseable = service and service.pause()
			if pauseable:
				pauseable.pause()
			else:
				self.session.nav.stopService()
			self.lockShow()
			# freeze epg labels
			self.epgTimer.stop()
			self.epgProgressTimer.stop()

	def exitArchive(self):
		self.setArchiveShift(0)
		self.play(self.cid)

	# EPG

	def epgEvent(self):
		# first stop timers
		self.epgTimer.stop()
		self.epgProgressTimer.stop()
		cid = self.cid
		time = syncTime() + secTd(self.shift)

		def setEpgCurrent():
			curr = self.db.channels[cid].epgCurrent(time)
			if not curr:
				return False

			self.currentEpg = curr
			self["currentName"].setText(curr.name)
			self["currentTime"].setText(curr.begin.strftime("%H:%M"))
			self["nextTime"].setText(curr.end.strftime("%H:%M"))
			self.epgTimer.start(curr.timeLeftMilliseconds(time) + 1000)
			self["currentDuration"].setText("+%d min" % (curr.timeLeft(time) / 60))
			self["progressBar"].setValue(curr.percent(time, PROGRESS_SIZE))
			self.epgProgressTimer.start(PROGRESS_TIMER)
			if self.shift:
				self["archiveDate"].setText(curr.begin.strftime("%d.%m"))
				self["archiveDate"].show()
			else:
				self["archiveDate"].hide()
			return True

		if not setEpgCurrent():
			try:
				self.db.loadDayEpg(cid, time)
			except APIException as e:
				trace("ERROR load epg failed! cid =", cid, bool(self.shift), e)
			if not setEpgCurrent():
				self["currentName"].setText('')
				self["currentTime"].setText('')
				self["nextTime"].setText('')
				self["currentDuration"].setText('')
				self["progressBar"].setValue(0)

		def setEpgNext():
			e = self.db.channels[cid].epgNext(time)
			if not e:
				return False
			self['nextName'].setText(e.name)
			self['nextDuration'].setText("%d min" % (e.duration() / 60))
			return True

		if not setEpgNext():
			try:
				self.db.loadDayEpg(cid, time)
			except APIException:
				trace("load epg next failed!")
			if not setEpgNext():
				self["nextName"].setText('')
				self["nextDuration"].setText('')

		self.serviceStarted()

	def epgUpdateProgress(self):
		time = syncTime() + secTd(self.shift)
		self["currentDuration"].setText("+%d min" % (self.currentEpg.timeLeft(time) / 60))
		self["progressBar"].setValue(self.currentEpg.percent(time, PROGRESS_SIZE))
		self.epgProgressTimer.start(PROGRESS_TIMER)

	# Dialogs

	def showEpg(self):
		self.session.openWithCallback(self.programSelected, IPtvDreamEpg, self.db, self.cid, self.shift)

	def programSelected(self, cid=None, time=None):
		if cid is not None and time is not None:
			self.setArchiveShift(tdSec(time-syncTime()))  # shift < 0
			self.play(cid)

	def showList(self):
		self.session.execDialog(self.channels)
		self.channels.callback = self.listClosed

	def listClosed(self, cid=None, time=None, action=None):
		if action is None:
			self.channelSelected(cid, time)
		else:
			self.exit(action)

	def channelSelected(self, cid, time=None):
		if cid is None:
			return
		if time:
			self.programSelected(cid, time)
		elif cid != self.cid:
			self.switchChannel(cid)

	def openSettings(self):
		self.exit('settings')

	def openVod(self):
		self.exit('vod')

	def createSummary(self):
		return InfoBarSummary

	# Channels

	def switchChannel(self, cid):
		# FIXME: zapping breaks archive shift
		trace("switch channel", self.cid)
		self.setArchiveShift(0)
		self.play(cid)

	def nextChannel(self):
		cid = self.channels.nextChannel()
		self.switchChannel(cid)

	def previousChannel(self):
		cid = self.channels.prevChannel()
		self.switchChannel(cid)

	def historyNext(self):
		if self.channels.historyNext():
			cid = self.channels.getCurrent()
			self.switchChannel(cid)

	def historyBack(self):
		if self.channels.historyPrev():
			cid = self.channels.getCurrent()
			self.switchChannel(cid)

	def keyNumberGlobal(self, number):
		self.session.openWithCallback(self.numberEntered, NumberEnter, number)

	def numberEntered(self, num=None):
		trace("numberEntered", num)
		if num is not None and self.channels.goToNumber(num):
			cid = self.channels.getCurrent()
			self.switchChannel(cid)

	# Errors

	def showError(self, msg):
		self.session.open(MessageBox, msg, MessageBox.TYPE_ERROR, 5)

class ChannelList(MenuList):
	def __init__(self):
		MenuList.__init__(self, [], content=eListboxPythonMultiContent, enableWrapAround=True)
		self.list = []
		self.index = {}
		self.col = {}
		self.fontCalc = []

		self.pixmapProgressBar = None
		self.pixmapArchive = None
		self.listItemHeight = 28
		self.listItemWidth = 0
		self.l.setFont(0, parseFont("Regular;22", ((1, 1), (1, 1))))
		self.l.setFont(1, parseFont("Regular;18", ((1, 1), (1, 1))))
		self.l.setFont(2, parseFont("Regular;20", ((1, 1), (1, 1))))
		self.showEpgProgress = config.usage.show_event_progress_in_servicelist.value
		self.num = 0
		self.highlight_cid = 0

		for x in [
				"colorEventProgressbar", "colorEventProgressbarSelected",
				"colorEventProgressbarBorder", "colorEventProgressbarBorderSelected",
				"colorServiceDescription", "colorServiceDescriptionSelected",
				"colorServicePlaying", "colorServicePlayingSelected"]:
			self.col[x] = None

	def postWidgetCreate(self, instance):
		trace("postWidgetCreate")
		MenuList.postWidgetCreate(self, instance)
		# Create eLabel instances, because we can't access eTextPara directly
		self.fontCalc = [eLabel(self.instance), eLabel(self.instance), eLabel(self.instance)]
		self.fontCalc[0].setFont(parseFont("Regular;22", ((1, 1), (1, 1))))
		self.fontCalc[1].setFont(parseFont("Regular;18", ((1, 1), (1, 1))))
		self.fontCalc[2].setFont(parseFont("Regular;20", ((1, 1), (1, 1))))

	def applySkin(self, desktop, parent):
		scale = ((1, 1), (1, 1))
		attribs = []
		if self.skinAttributes is not None:
			for (attrib, value) in self.skinAttributes:
				if attrib in (
						"colorEventProgressbar", "colorEventProgressbarSelected",
						"colorEventProgressbarBorder", "colorEventProgressbarBorderSelected",
						"colorServiceDescription", "colorServiceDescriptionSelected",
						"colorServicePlaying", "colorServicePlayingSelected"):
					self.col[attrib] = parseColor(value).argb()
				elif attrib == "picServiceEventProgressbar":
					pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, value))
					if pic:
						self.pixmapProgressBar = pic
				elif attrib == "picServiceArchive":
					pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, value))
					if pic:
						self.pixmapArchive = pic
				elif attrib == "serviceItemHeight":
					self.listItemHeight = int(value)
				elif attrib == "serviceNameFont":
					self.l.setFont(0, parseFont(value, scale))
					self.fontCalc[0].setFont(parseFont(value, scale))
				elif attrib == "serviceInfoFont":
					self.l.setFont(1, parseFont(value, scale))
					self.fontCalc[1].setFont(parseFont(value, scale))
				elif attrib == "serviceNumberFont":
					self.l.setFont(2, parseFont(value, scale))
					self.fontCalc[2].setFont(parseFont(value, scale))
				else:
					attribs.append((attrib, value))

		self.skinAttributes = attribs
		res = GUIComponent.applySkin(self, desktop, parent)

		self.l.setItemHeight(self.listItemHeight)
		self.listItemWidth = self.instance.size().width()
		for x in self.fontCalc:
			# resize and move away
			x.resize(eSize(self.listItemWidth, self.listItemHeight))
			x.move(ePoint(int(self.instance.size().width()+10), int(self.instance.size().height()+10)))
			x.setNoWrap(1)
		return res

	def setEnumerated(self, enumerated):
		if enumerated:
			self.num = 1
		else:
			self.num = 0

	def setChannelsList(self, channels):
		self.setList(map(self.buildChannelEntry, channels))
		# Create map from channel id to its index in list
		self.index = dict((entry[0][0].cid, i) for (i, entry) in enumerate(self.list))
		if self.num:
			self.num = 1

	def updateChannel(self, cid, channel):
		try:
			index = self.index[cid]
		except KeyError:
			return
		self.list[index] = self.buildChannelEntry(channel)
		self.l.invalidateEntry(index)

	def updateChannelsProgress(self):
		if self.showEpgProgress:
			self.setList([self.buildChannelEntry(item[0]) for item in self.list])

	def moveEntryUp(self):
		index = self.getSelectedIndex()
		if index == 0:
			return
		self.list[index - 1], self.list[index] = self.list[index], self.list[index - 1]
		self.l.invalidateEntry(index - 1)
		self._updateIndexMap(index - 1)
		self.l.invalidateEntry(index)
		self._updateIndexMap(index)
		self.up()

	def moveEntryDown(self):
		index = self.getSelectedIndex()
		if index + 1 == len(self.list):
			return
		self.list[index], self.list[index + 1] = self.list[index + 1], self.list[index]
		self.l.invalidateEntry(index)
		self._updateIndexMap(index)
		self.l.invalidateEntry(index + 1)
		self._updateIndexMap(index + 1)
		self.down()

	def _updateIndexMap(self, i):
		cid = self.list[i][0][0].cid
		self.index[cid] = i

	def highlight(self, cid):
		self.highlight_cid = cid

	def setGroupList(self, groups):
		self.setList(map(self.buildGroupEntry, groups))
		self.index = {}

	def calculateWidth(self, text, font):
		self.fontCalc[font].setText(text)
		return int(round(self.fontCalc[font].calculateSize().width()*1.1))

	def buildGroupEntry(self, group):
		return [
			group,
			(eListboxPythonMultiContent.TYPE_TEXT, 0, 0, self.listItemWidth, self.listItemHeight,
				0, RT_HALIGN_LEFT | RT_VALIGN_CENTER, group.title)
		]

	def buildChannelEntry(self, entry):
		"""
		:type entry: Tuple[utils.Channel, utils.EPG]
		"""
		c, e = entry
		defaultFlag = RT_HALIGN_LEFT | RT_VALIGN_CENTER
		# Filling from left to right

		lst = [entry]
		xoffset = 1

		if self.num:
			xoffset += 55
			text = str(c.number)
			lst.append(
				(eListboxPythonMultiContent.TYPE_TEXT, 0, 0, xoffset-5, self.listItemHeight,
					2, RT_HALIGN_RIGHT | RT_VALIGN_CENTER, text))

		if self.pixmapArchive:
			width = self.pixmapArchive.size().width()
			height = self.pixmapArchive.size().height()
			if c.has_archive:
				lst.append(
					(eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST,
						xoffset, (self.listItemHeight - height) / 2, width, height, self.pixmapArchive))
			xoffset += width+5

		if self.showEpgProgress:
			width = 52
			height = 6
			if e:
				percent = e.percent(syncTime(), 100)
				lst.extend([
					(eListboxPythonMultiContent.TYPE_PROGRESS,
						xoffset+1, (self.listItemHeight-height)/2, width, height,
						percent, 0, self.col['colorEventProgressbar'], self.col['colorEventProgressbarSelected']),
					(eListboxPythonMultiContent.TYPE_PROGRESS,
						xoffset, (self.listItemHeight-height)/2 - 1, width+2, height+2,
						0, 1, self.col['colorEventProgressbarBorder'], self.col['colorEventProgressbarBorderSelected'])
				])
			xoffset += width+7

		text = str(c.name)
		width = self.calculateWidth(text, 0)
		if c.cid != self.highlight_cid:
			lst.append(
				(eListboxPythonMultiContent.TYPE_TEXT, xoffset, 0, width, self.listItemHeight,
					0, defaultFlag, text))
		else:
			lst.append(
				(eListboxPythonMultiContent.TYPE_TEXT, xoffset, 0, width, self.listItemHeight,
					0, defaultFlag, text, self.col['colorServicePlaying'], self.col['colorServicePlayingSelected']))
		xoffset += width+10

		if e:
			text = '(%s)' % e.name
			lst.append(
				(eListboxPythonMultiContent.TYPE_TEXT, xoffset, 0, self.listItemWidth, self.listItemHeight,
					1, defaultFlag, text,
					self.col['colorServiceDescription'], self.col['colorServiceDescriptionSelected']))

		return lst

class History(object):
	def __init__(self, size):
		self._size = size
		self._history = []  # type: List[HistoryEntry]
		self._index = -1

	def isEmpty(self):
		return len(self._history) == 0

	def append(self, val):
		while len(self._history) > self._index + 1:
			self._history.pop()
		self._history.append(val)
		if len(self._history) > self._size:
			self._history.pop(0)
		else:
			self._index += 1

	def historyPrev(self):
		if self._index < 1:
			return None
		else:
			self._index -= 1
			return self._history[self._index]

	def historyNext(self):
		if self._index+1 == len(self._history):
			return None
		else:
			self._index += 1
			return self._history[self._index]

	def now(self):
		if len(self._history):
			return self._history[self._index]
		else:
			return None

	def __repr__(self):
		return map(str, self._history)

class HistoryEntry(object):
	def __init__(self, mode, gid, gr_idx, cid, ch_idx):
		self.mode = mode
		self.gid, self.gr_idx = gid, gr_idx
		self.cid, self.ch_idx = cid, ch_idx

	def copy(self):
		return HistoryEntry(self.mode, self.gid, self.gr_idx, self.cid, self.ch_idx)

	def fromStr(self, s):
		self.mode, self.gid, self.gr_idx, self.cid, self.ch_idx = map(int, s.split(","))

	def toStr(self):
		return ",".join(map(str, (self.mode, self.gid, self.gr_idx, self.cid, self.ch_idx)))

	def makeTuple(self):
		return self.mode, self.gid, self.gr_idx, self.cid, self.ch_idx

	def __repr__(self):
		return "HistoryEntry(%d, (%d, %d), (%d, %d))" % (self.mode, self.gid, self.gr_idx, self.cid, self.ch_idx)

class VerticalLayoutPart(object):
	"""
	Grow program name label while title does not fit, and shrink program description accordingly
	"""

	def __init__(self, screen, widgetsToMove):
		self._name_height = 0
		self._desc_top = 0
		self._desc_height = 0
		self._widgets_top = []
		self.name = screen["epgName"]
		self.desc = screen["epgDescription"]
		self.widgets = widgetsToMove
		screen.onLayoutFinish.append(self.initLayout)

	def initLayout(self):
		self._name_height = self.name.instance.size().height()
		self._desc_top = self.desc.instance.position().y()
		self._desc_height = self.desc.instance.size().height()
		self._widgets_top = [w.instance.position().y() for w in self.widgets]

	def updateLayout(self):
		height = min(self.name.instance.calculateSize().height(), self._name_height * 3)
		dh = height - self._name_height
		self.name.instance.resize(eSize(
			self.name.instance.size().width(), height))
		self.desc.instance.move(ePoint(
			self.desc.instance.position().x(), self._desc_top + dh))
		self.desc.instance.resize(eSize(
			self.desc.instance.size().width(), self._desc_height - dh))
		for w, y in zip(self.widgets, self._widgets_top):
			w.instance.move(ePoint(w.instance.position().x(), y + dh))

class IPtvDreamChannels(Screen):
	"""
	:type db: AbstractStream
	:type saved_state: Optional[HistoryEntry]
	"""

	GROUPS, ALL, GROUP, FAV = range(4)

	def __init__(self, session, db, player_ref):
		Screen.__init__(self, session)

		trace("channels init")
		self.history = History(10)
		self.db = db  # type: AbstractStream
		self.player_ref = player_ref
		from .manager import manager
		self.cfg = manager.getConfig(self.db.NAME)

		self["caption"] = Label(_("Channel Selection"))
		self["key_red"] = Label(_("All"))
		self["key_green"] = Label(_("Groups"))
		self["key_yellow"] = Label(_("Add"))
		self["key_blue"] = Label(_("Favourites"))

		self.list = self["list"] = ChannelList()

		self["channelName"] = Label()
		self["epgName"] = Label()
		self["epgTime"] = Label()
		self["epgDescription"] = Label()
		self["epgNextTime"] = Label()
		self["epgNextName"] = Label()
		self["epgNextDescription"] = Label()

		self["epgProgress"] = Slider(0, 100)
		self["progress"] = self._progress = EpgProgress()
		self._progress.onChanged.append(lambda value: self["epgProgress"].setValue(int(100 * value)))

		# auto resize some widgets
		self._info_part = VerticalLayoutPart(self, (self["epgTime"], self["epgProgress"]))

		self._worker = LiveEpgWorker(db)
		self._worker.onUpdate.append(self.updatePrograms)
		self.onClose.append(self._worker.destroy)

		def workerStandby(sleep):
			if sleep:
				self._worker.stop()
			else:
				self._worker.update()
		standbyNotifier.onStandbyChanged.append(workerStandby)
		self.onClose.append(lambda: standbyNotifier.onStandbyChanged.remove(workerStandby))

		self._progressTimer = eTimer()
		self._progressTimer.callback.append(self.updateProgramsProgress)
		self._progressTimer.start(1000 * 60 * 5)  # every 5 min

		self["actions"] = ActionMap(
			["OkCancelActions", "IPtvDreamChannelListActions"], {
				"cancel": self.exit,
				"ok": self.ok,
				"showAll": self.showAll,
				"showGroups": self.showGroups,
				"addFavourites": self.addRemoveFavourites,
				"showFavourites": self.showFavourites,
				"contextMenu": self.showMenu,
				"showEPGList": self.showEpgList,
				"nextBouquet": self.nextGroup,
				"prevBouquet": self.prevGroup
			}, -1)

		self.list.onSelectionChanged.append(self.selectionChanged)
		self.onClose.append(lambda: self.list.onSelectionChanged.remove(self.selectionChanged))

		start_mode = manager.getStartMode()
		if start_mode == self.FAV and not self.db.selectFavourites():
			start_mode = self.GROUPS

		self.order_config = SortOrderSettings()
		self.mode = start_mode
		self.gid = None
		self.saved_state = None

		self.edit_mode = False
		self.marked = False  # Whether current entry is marked (in edit mode)
		self["move_actions"] = ActionMap(
			["OkCancelActions", "DirectionActions", "IPtvDreamChannelListActions"], {
				"cancel": self.finishEditing,
				"ok": self.toggleMarkForMoving,
				"up": self.moveUp,
				"down": self.moveDown,
				"contextMenu": self.showMenu,
				"addFavourites": self.addRemoveFavourites,
			}, -1)
		self["move_actions"].setEnabled(False)

		self["packetExpire"] = Label()
		if self.db.packet_expire is not None:
			self["packetExpire"].setText(_("Payment expires: ") + self.db.packet_expire.strftime("%d.%m.%Y"))

		self.onLayoutFinish.append(self.fillList)
		self.onShown.append(self.start)

	def start(self):
		trace("Channels list shown")
		if not self.history.isEmpty():
			self.saved_state = self.history.now().copy()
		else:
			self.saved_state = None

	def saveQuery(self):
		trace("save query")
		h = self.history.now()
		if h is not None:
			self.cfg.last_played.value = self.history.now().toStr()
		else:
			self.cfg.last_played.value = ""
		self.cfg.last_played.save()
		configfile.save()

	def createHistoryEntry(self):
		entry = self.getSelected()
		assert entry is not None
		return HistoryEntry(self.mode, self.gid, 0, entry.cid, self.list.getSelectedIndex())

	def recoverState(self, state):
		"""
		:param HistoryEntry state:
		"""
		self.mode, self.gid = state.mode, state.gid
		if self.mode == self.GROUPS:
			self.fillGroupsList()
			self.list.moveToIndex(self.saved_state.gr_idx)
		else:
			self.fillList()
			self.list.moveToIndex(self.saved_state.ch_idx)

	def exit(self):
		if self.saved_state is not None:
			self.recoverState(self.saved_state)
		self.close(None)

	def ok(self, time=None):
		entry = self.getSelected()
		if entry is None:
			return
		if self.mode == self.GROUPS:
			self.mode = self.GROUP
			self.gid = entry.gid
			self.fillList()
			self.list.moveToIndex(0)
		else:
			idx = self.list.getSelectedIndex()
			cid = entry.cid
			self.history.append(HistoryEntry(self.mode, self.gid, 0, cid, idx))
			self.close(cid, time)

	@timeit
	def updateProgramsProgress(self):
		if self.mode != self.GROUPS:
			print("Updating list progressbars")
			self.list.updateChannelsProgress()

	def updatePrograms(self, data):
		# type: (List[Tuple[int, EPG]]) -> None
		if self.mode == self.GROUPS:
			return
		for (cid, epg) in data:
			if epg:
				try:
					channel = self.db.channels[cid]
				except KeyError:
					continue
				self.list.updateChannel(cid, (channel, epg))

	@timeit
	def setChannels(self, channels):
		self.list.setChannelsList((c, self._worker.get(c.cid)) for c in channels)

	def fillGroupsList(self):
		self.setTitle(" / ".join([self.db.NAME, _("Groups")]))
		groups = self.db.selectGroups()
		self.list.setGroupList(groups)
		if self.gid is not None:
			for idx, g in enumerate(groups):
				if g.gid == self.gid:
					self.list.moveToIndex(idx)
					break
			else:
				self.gid = None

	def fillList(self):
		title = [self.db.NAME]
		# Highlight is used for edit mode
		# self.list.highlight(self.player_ref.cid)
		order = self.order_config.getValue()

		if self.mode == self.GROUPS:
			self.fillGroupsList()
			title.append(_("Groups"))
		elif self.mode == self.GROUP:
			self.setChannels(self.db.selectChannels(self.gid, sort_key=order))
			title.append(self.db.groups[self.gid].title)
		elif self.mode == self.ALL:
			self.setChannels(self.db.selectAll(sort_key=order))
			title.append(_("All channels"))
		elif self.mode == self.FAV:
			self.setChannels(self.db.selectFavourites())
			title.append(_("Favourites"))

		self.setTitle(" / ".join(title))
		if self.mode == self.FAV:
			self["key_yellow"].setText(_("Remove"))
		else:
			self["key_yellow"].setText(_("Add"))

	def selectionChanged(self):
		channel = self.getSelected()
		trace("selection =", channel)

		if self.mode == self.GROUPS or channel is None:
			self["channelName"].setText("")
			self.hideEpgLabels()
			self.hideEpgNextLabels()
		else:
			self["channelName"].setText(channel.name)
			self["channelName"].show()
			curr = self._worker.get(channel.cid)
			if curr:
				self["epgTime"].setText("%s - %s" % (curr.begin.strftime("%H:%M"), curr.end.strftime("%H:%M")))
				self["epgName"].setText(curr.name)
				self["epgName"].show()
				self["epgTime"].show()
				self["epgDescription"].setText(curr.description)
				self["epgDescription"].show()
				self._progress.setEpg(curr)
				self["epgProgress"].show()
				self._info_part.updateLayout()
			else:
				self.hideEpgLabels()
			curr = self._worker.getNext(channel.cid)
			if curr:
				self["epgNextTime"].setText("%s - %s" % (curr.begin.strftime("%H:%M"), curr.end.strftime("%H:%M")))
				self["epgNextName"].setText(curr.name)
				self["epgNextDescription"].setText(curr.description)
				self["epgNextName"].show()
				self["epgNextTime"].show()
				self["epgNextDescription"].show()
			else:
				self.hideEpgNextLabels()

	def hideEpgLabels(self):
		self["epgName"].hide()
		self["epgTime"].hide()
		self["epgProgress"].hide()
		self["epgDescription"].hide()

	def hideEpgNextLabels(self):
		self["epgNextName"].hide()
		self["epgNextTime"].hide()
		self["epgNextDescription"].hide()

	def showGroups(self):
		self.mode = self.GROUPS
		self.fillList()

	def showAll(self):
		self.mode = self.ALL
		self.fillList()

	def showFavourites(self):
		self.mode = self.FAV
		self.fillList()

	def npGroup(self, diff):
		if self.mode == self.GROUP:
			groups = self.db.selectGroups()
			for idx, g in enumerate(groups):
				if g.gid == self.gid:
					self.gid = groups[(idx + diff) % len(groups)].gid
					self.fillList()
					break

	def nextGroup(self):
		self.npGroup(1)

	def prevGroup(self):
		self.npGroup(-1)

	def addRemoveFavourites(self):
		channel = self.getSelected()
		if not channel:
			return
		if self.mode == self.FAV:
			self.db.rmFav(channel.cid)
			self.showFavourites()
		elif self.mode != self.GROUPS:
			self.db.addFav(channel.cid)

	def showMenu(self):
		actions = []
		current = self.getSelected()
		if self.mode in [self.ALL, self.GROUP]:
			actions += [
				(_("Sort by number"), self.sortByNumber),
				(_("Sort by name"), self.sortByName),
			]
			if current:
				actions += [
					(_('Add "%s" to favourites') % current.name, self.addRemoveFavourites),
				]
				if current.has_archive:
					actions += [(_('Open archive for "%s"') % current.name, self.showEpgList)]
		if self.mode == self.FAV:
			if current:
				actions += [
					(_('Remove "%s" from favourites') % current.name, self.addRemoveFavourites),
				]
				if current.has_archive:
					actions += [(_('Open archive for "%s"') % current.name, self.showEpgList)]
				if not self.edit_mode:
					actions += [(_("Enter edit mode"), self.confirmStartEditing)]
				else:
					actions += [(_("Exit edit mode"), self.notifyFinishEditing)]
		actions += [(_("Open plugin settings"), self.openSettings)]
		if self.db.AUTH_TYPE:
			actions += [(_("Clear login data and exit"), self.clearLogin)]

		def cb(entry=None):
			if entry is not None:
				func = entry[1]
				func()
		if actions:
			self.session.openWithCallback(cb, ChoiceBox, _("Context menu"), actions)

	def sortBy(self, what):
		channel = self.getSelected()
		if channel is None:
			return
		self.order_config.setValue(what)
		self.fillList()
		index = self.findChannelIndex(channel.cid)
		if index:
			self.list.moveToIndex(index)

	def sortByNumber(self):
		self.sortBy('number')

	def sortByName(self):
		self.sortBy('name')

	def confirmStartEditing(self):
		def cb(ret):
			if ret:
				self.startEditing()
		message = _(
			"In the editing mode you can reorder your favourites list. Quick help:\n"
			"- Select channel that you want to put to a new position.\n"
			"- Press OK to start moving the channel around with arrow buttons.\n"
			"- Press OK again to fix the position of the channel.\n"
			"- Press EXIT when done.\n"
			"Start editing mode?"
		)
		self.session.openWithCallback(cb, MessageBox, _(message), MessageBox.TYPE_YESNO)

	def startEditing(self):
		"""Start reordering of channels in the favourites list"""
		self.edit_mode = True
		self["actions"].setEnabled(False)
		self["move_actions"].setEnabled(True)

	def toggleMarkForMoving(self):
		if self.marked:
			self.marked = False
			self.list.highlight(None)
		else:
			self.marked = True
			channel = self.getSelected()
			if channel:
				self.list.highlight(channel.cid)

	def moveUp(self):
		if self.marked:
			self.list.moveEntryUp()
		else:
			self.list.up()

	def moveDown(self):
		if self.marked:
			self.list.moveEntryDown()
		else:
			self.list.down()

	def notifyFinishEditing(self):
		self.session.openWithCallback(
			lambda ret: self.finishEditing(),
			MessageBox, _("Exiting edit mode"), MessageBox.TYPE_INFO, timeout=5)

	def finishEditing(self):
		self.edit_mode = False
		self["actions"].setEnabled(True)
		self["move_actions"].setEnabled(False)
		try:
			self.db.setFavourites([entry[0][0].cid for entry in self.list.list])
		except APIException as ex:
			self.session.open(
				MessageBox, "%s\n%s" % (_("Failed to save favourites list."), str(ex)), MessageBox.TYPE_ERROR)

	def showEpgList(self):
		channel = self.getSelected()
		if channel and self.modeChannels():
			self.session.openWithCallback(self.showEpgCB, IPtvDreamEpg, self.db, channel.cid, 0)

	def showEpgCB(self, cid=None, time=None):
		trace("selected program", cid, time)
		if time is not None:
			self.ok(time)

	def getSelected(self):
		entry = self.list.getCurrent()
		trace("getSelected", entry and entry[0])
		if entry:
			if self.mode == self.GROUPS:
				return entry[0]
			else:
				return entry[0][0]
		return None

	def getCurrent(self):
		return self.history.now().cid

	def modeChannels(self):
		return self.mode != self.GROUPS

	def nextChannel(self):
		self.list.down()
		self.history.append(self.createHistoryEntry())
		return self.getCurrent()

	def prevChannel(self):
		self.list.up()
		self.history.append(self.createHistoryEntry())
		return self.getCurrent()

	def historyNext(self):
		h = self.history.historyNext()
		if h is not None:
			self.recoverState(h)
			return self.getCurrent()
		else:
			return None

	def historyPrev(self):
		h = self.history.historyPrev()
		if h is not None:
			self.recoverState(h)
			return self.getCurrent()
		else:
			return None

	def findChannelIndex(self, cid):
		for i, entry in enumerate(self.list.list):
			channel = entry[0][0]
			if channel.cid == cid:
				return i
		return None

	def goToNumber(self, num):
		cid = self.db.findNumber(num)
		if cid is None:
			return None
		idx = self.findChannelIndex(cid)
		if idx is None:
			self.mode, self.gid = self.ALL, None
			self.fillList()
			idx = self.findChannelIndex(cid)
		self.list.moveToIndex(idx)
		self.history.append(self.createHistoryEntry())
		return cid

	def openSettings(self):
		self.close(None, None, 'settings')

	def clearLogin(self):
		self.close(None, None, 'clear_login')

class IPtvDreamEpg(Screen):
	def __init__(self, session, db, cid, shift):
		Screen.__init__(self, session)

		self["caption"] = Label(_("EPG List"))
		self["btn_red"] = Pixmap()
		self["key_red"] = Label(_("Archive"))
		self["key_green"] = Label(_("Details"))
		self["list"] = self.list = ListSource()

		self["epgName"] = Label()
		self["epgDescription"] = Label()
		self["epgTime"] = Label()
		self["epgDuration"] = Label()

		self["epgProgress"] = Slider(0, 100)
		self["progress"] = self._progress = EpgProgress()
		self._progress.onChanged.append(lambda value: self["epgProgress"].setValue(int(100 * value)))

		# auto resize some widgets
		self._info_part = VerticalLayoutPart(self, (self["epgTime"], self["epgProgress"], self["epgDuration"]))

		self["packetExpire"] = Label()

		self["actions"] = ActionMap(
			["OkCancelActions", "IPtvDreamEpgListActions", "ColorActions"], {
				"cancel": self.close,
				"ok": self.archive,
				"up": self.up,
				"down": self.down,
				"pageUp": self.pageUp,
				"pageDown": self.pageDown,
				"nextDay": self.nextDay,
				"prevDay": self.prevDay,
				"green": self.showInfo,
				"showInfo": self.showInfo,
				"red": self.archive
			}, -1)

		self.db = db  # type: AbstractStream
		self.cid = cid
		self.shift = shift
		self.day = 0
		self.list.onSelectionChanged.append(self.updateLabels)
		self.onShown.append(self.start)

	def start(self):
		self.onShown.remove(self.start)
		self.fillList()

	def buildEpgEntry(self, entry):
		if self.db.channels[self.cid].has_archive and entry.begin < syncTime():
			pixmap = rec_png
		else:
			pixmap = None
		return entry, pixmap, entry.begin.strftime('%a'), entry.begin.strftime('%H:%M'), entry.name

	def fillList(self):
		if self.cid is None:
			return

		time = syncTime() + secTd(self.shift)
		d = time + timedelta(self.day)

		epg_list = []
		try:
			epg_list = self.db.getDayEpg(self.cid, datetime(d.year, d.month, d.day))
		except APIException as e:
			self.session.open(MessageBox, _("Can not load EPG:") + str(e), MessageBox.TYPE_ERROR, 5)

		self.list.setList(map(self.buildEpgEntry, epg_list))
		self.setTitle("EPG / %s / %s %s" % (self.db.channels[self.cid].name, d.strftime("%d"), _(d.strftime("%b"))))
		self.list.setIndex(0)

		if self.day == 0:
			for i, program in enumerate(epg_list):
				if program.isAt(time):
					self.list.setIndex(i)
					break

	def updateLabels(self):
		entry = self.list.getCurrent()
		if not entry:
			return

		entry = entry[0]
		self["epgName"].setText(entry.name)
		self["epgTime"].setText(entry.begin.strftime("%d.%m %H:%M"))
		self["epgDescription"].setText(entry.description)
		self["epgDuration"].setText("%s min" % (entry.duration() / 60))
		if self.db.channels[self.cid].has_archive and entry.begin < syncTime():
			self["btn_red"].show()
			self["key_red"].show()
		else:
			self["btn_red"].hide()
			self["key_red"].hide()
		self._progress.setEpg(entry)
		self._info_part.updateLayout()

	def archive(self):
		entry = self.list.getCurrent()
		if not entry:
			return
		entry = entry[0]
		if self.db.channels[self.cid].has_archive and entry.begin < syncTime():
			self.close(self.cid, entry.begin)

	def showInfo(self):
		entry = self.list.getCurrent()
		if not entry:
			return
		entry = entry[0]
		self.session.openWithCallback(self.infoClosed, IPtvDreamEpgInfo, self.db.channels[self.cid], entry)

	def infoClosed(self, time=None):
		if time is not None:
			self.close(self.cid, time)

	def up(self):
		idx = self.list.getIndex()
		if idx == 0:
			self.prevDay()
			self.list.setIndex(self.list.count() - 1)
		else:
			self.list.selectPrevious()

	def down(self):
		idx = self.list.getIndex()
		if idx == self.list.count() - 1 or self.list.count() == 0:
			self.nextDay()
		else:
			self.list.selectNext()

	def pageUp(self):
		idx = self.list.getIndex()
		if idx == 0:
			self.prevDay()
			self.list.setIndex(self.list.count() - 1)
		else:
			self.list.pageUp()

	def pageDown(self):
		idx = self.list.getIndex()
		if idx == self.list.count() - 1 or self.list.count() == 0:
			self.nextDay()
		else:
			self.list.pageDown()

	def nextDay(self):
		self.day += 1
		self.fillList()

	def prevDay(self):
		self.day -= 1
		self.fillList()

class IPtvDreamEpgInfo(Screen):
	def __init__(self, session, channel, entry):
		"""
		Screen to show information for single EPG entry
		:type entry: utils.EPG
		:type channel: utils.Channel
		"""
		Screen.__init__(self, session)
		self.entry = entry
		self.channel = channel

		self.setTitle("%d. %s" % (channel.number, channel.name))

		self["epgName"] = Label(entry.name)
		self["epgDescription"] = ScrollLabel(entry.description or _("No detailed information"))
		self._main_part = VerticalLayoutPart(self, widgetsToMove=())

		self["epgTime"] = Label(entry.begin.strftime("%a %H:%M"))
		self["epgDate"] = Label(entry.begin.strftime("%d.%m.%Y"))
		self["epgDuration"] = Label()

		self["epgProgress"] = Slider(0, 100)
		self["progress"] = self._progress = EpgProgress()
		self._progress.onChanged.append(self.updateProgress)
		self.onLayoutFinish.append(self.initGui)

		self["btn_red"] = Pixmap()
		self["key_red"] = Label(_("Archive"))

		if not self.hasArchive():
			self["btn_red"].hide()
			self["key_red"].hide()

		self["actions"] = ActionMap(["OkCancelActions", "DirectionActions", "ColorActions"], {
			"cancel": self.close,
			"red": self.playArchive,
			"ok": self.close,
			"up": self["epgDescription"].pageUp,
			"down": self["epgDescription"].pageDown
		}, -1)

	def initGui(self):
		self._main_part.updateLayout()
		self._progress.setEpg(self.entry)

	def hasArchive(self):
		return self.channel.has_archive and self.entry.begin < syncTime()

	def playArchive(self):
		if self.hasArchive():
			self.close(self.entry.begin)

	def updateProgress(self, value):
		t = syncTime()
		if self.entry.isAt(t):
			self["epgDuration"].setText("+%s min" % (self.entry.timeLeft(t) / 60))
		else:
			self["epgDuration"].setText("%s min" % (self.entry.duration() / 60))
		self["epgProgress"].setValue(int(100 * value))

# gettext HACK:
# [_("Jan"), _("Feb"), _("Mar"), _("Apr"), _("May"), _("Jun"), _("Jul"), _("Aug"), _("Sep"), _("Oct"), _("Nov") ]


"""
闭包中，内部函数修改外部函数的数据

"""

x = 300
def test1():
    x = 200

    def test2():
        # 表示在这里使用的是不是内部函数中的变量
        nonlocal x
        print("-----1---%d" % x)
        # 如果在内部函数中有修改外部函数中的数据，那么如果在修改之前使用该数据，python会认为该函数未定义，因为它使用
        # 的是内部函数中的变量，所以需要加 nonlocal
        x = 100
        print("-----1---%d" % x)
    return test2

t = test1()
t()

02_闭包修改数据.py


# esreveR
#
# https://www.codewars.com/kata/5413759479ba273f8100003d
#
# Write a function reverse which reverses a list (or in clojure's case, any list-like data structure)
#
# (the dedicated builtin(s) functionalities are deactivated)

def reverse(lst):
    empty_list = list()
    while len(lst) > 0:
        empty_list.append(lst.pop())
    return empty_list

# Best practice:
#
# def reverse(lst):
#     out = list()
#     for i in range(len(lst)-1,-1,-1):
#         out.append(lst[i])
#     return out
#
# Clever solution:
#
# def reverse(lst):
#     empty_list = list()
#     for i in range(len(lst)):
#         empty_list.append(lst.pop())
#     return empty_list


import pymongo
from app import app
from flask import request, jsonify, render_template, redirect, url_for, flash
import sys
from app.database import tasks_collection, redis_conn
from rq import Queue
from bson import ObjectId
from datetime import datetime
from app.worker import clean_data, transform_data, analyze_data
from app.task import Task

# Priority mapping for filtering tasks by priority
priority_mapping = {
    "low": 0,
    "medium": 1,
    "high": 2
}

# RQ queues
low_priority_queue = Queue('low', connection=redis_conn)
medium_priority_queue = Queue('medium', connection=redis_conn)
high_priority_queue = Queue('high', connection=redis_conn)

# Check RQ queue connection
try:
    queue_length = low_priority_queue.count  # Updated to use low_priority_queue instead of queue
    print(f"Successfully connected to RQ queue. Current queue length: {queue_length}")
except Exception as e:
    print("Error connecting to RQ queue: ", e, file=sys.stderr)
    sys.exit(1)

@app.route('/', methods=['GET'])
def index():
    return render_template('index.html')

@app.route('/tasks/create', methods=['GET', 'POST'])
def create_task():
    if request.method == 'POST':
        task_data = {
            'description': request.form['description'],
            'priority': request.form['priority'],
            'task_type': request.form['task_type'],
        }

        response, status = create_task_with_data(task_data)

        if status == 201:
            task_id = response['task_id']
            flash(f'Task created successfully with ID: {task_id}')
            return redirect(url_for('get_task', task_id=task_id))
        else:
            flash(f'Error creating task: {response["error"]}')
            return render_template('create_task.html'), status
    else:
        return render_template('create_task.html')

# New function to create a task with the given data
def create_task_with_data(data):
    # Validate required fields
    if 'description' not in data or 'priority' not in data or 'task_type' not in data:
        return {'error': 'Missing required fields'}, 400

    # Create a Task object
    new_task = Task(data)
    # Save the task to the database
    new_task.save()

    # Add 'created_at' field with the current timestamp as an ISO-formatted string
    data['created_at'] = datetime.utcnow()
    # Add 'status' field with the default value 'pending'
    data['status'] = 'pending'

    allowed_task_types = ['data_cleaning', 'data_transformation', 'data_analysis']

    if data['task_type'] not in allowed_task_types:
        return {'error': 'Invalid task type'}, 400

    task_id = tasks_collection.insert_one(data).inserted_id

    # Determine target queue based on priority
    priority = priority_mapping.get(data['priority'], 1)  # Default to low priority if not provided

    if priority == 'high':
        target_queue = high_priority_queue
    elif priority == 'medium':
        target_queue = medium_priority_queue
    else:
        target_queue = low_priority_queue

    task_type_to_function = {
        'data_cleaning': clean_data,
        'data_transformation': transform_data,
        'data_analysis': analyze_data,
    }

    worker_function = task_type_to_function[data['task_type']]

    job = target_queue.enqueue_call(
    func=task_type_to_function[data['task_type']],
    args=(str(task_id), data),
    result_ttl=86400
)

    return {'task_id': str(task_id)}, 201

# Function to get the status and result of a task
@app.route('/tasks/<task_id>', methods=['GET'])
def get_task(task_id):
    task = tasks_collection.find_one({'_id': ObjectId(task_id)}, sort=[('priority', -1), ('created_at', 1)])
    if not task:
        flash('Task not found')
        return redirect(url_for('index'))

    return render_template('view_task.html', task=task)

# Route for monitoring task status
@app.route('/tasks/<job_id>/status', methods=['GET'])
def get_task_status(job_id):
    job = None
    for queue in [high_priority_queue, medium_priority_queue, low_priority_queue]:
        job = queue.fetch_job(job_id)
        if job:
            break

    if not job:
        return jsonify({'error': 'Job not found'}), 404

    task_status = job.get_status()
    return render_template('task_status.html', task_id=job_id, status=task_status, result=job.result if task_status == 'finished' else None)

# Function to update the status of a task
@app.route('/tasks/<task_id>/status', methods=['PUT'])
def update_task_status(task_id):
    if request.content_type != 'application/json':
        return 'request Content-Type was not "application/json".', 415

    data = request.get_json()
    new_status = data.get('status', None)
    new_result = data.get('result', None)  # Get the result from the request data
    if new_result:
        update_data['result'] = new_result
        print("New result:", new_result)
    if new_status:
        update_data = {'status': new_status}
        if new_result:
            update_data['result'] = new_result  # Add the result to the update data if it's not None

        tasks_collection.update_one(
            {'_id': ObjectId(task_id)},
            {'$set': update_data}
        )
        return jsonify({'message': 'Task status updated'}), 200
    else:
        return jsonify({'error': 'Invalid status'}), 400

    if new_result:
        update_data['result'] = new_result
        print("New result:", new_result)

@app.route('/tasks/<task_id>/details', methods=['GET'])
def get_task_details(task_id):
    task = tasks_collection.find_one({'_id': ObjectId(task_id)})
    if task:
        response = {
            'task_id': str(task['_id']),
            'description': task['description'],
            'priority': task['priority'],
            'created_at': task.get('created_at', None),  # Use get() to avoid KeyError
            'status': task.get('status', None)  # Use get() to avoid KeyError
        }
        return jsonify(response), 200
    else:
        return jsonify({'error': 'Task not found'}), 404

# Function to retrieve all tasks
@app.route('/tasks/view', methods=['GET'])
def get_all_tasks():
    # Get query parameters for pagination, sorting, and filtering
    page = int(request.args.get('page', 1))
    per_page = int(request.args.get('per_page', 10))
    sort_by = request.args.get('sort_by', 'created_at')
    sort_order = request.args.get('sort_order', 'asc')
    priority = request.args.get('priority', None)
    status = request.args.get('status', None)
    search = request.args.get('search', None)

    tasks_data = get_all_tasks_data(page, per_page, sort_by, sort_order, priority, status, search)

    # Render the tasks_data and pagination data in the template (adapt this to your needs)
    return render_template('tasks_view.html', tasks=tasks_data['tasks'], pagination=tasks_data['pagination'])

def get_all_tasks_data(page, per_page, sort_by, sort_order, priority, status, search):
    # Build filter query based on priority and status
    filter_query = {}
    if priority:
        filter_query['priority'] = priority_mapping.get(priority)
    if status:
        filter_query['status'] = status
    if search:
        filter_query['description'] = {'$regex': search, '$options': 'i'}

    # Build sort query based on sort_by and sort_order
    sort_query = [(sort_by, pymongo.ASCENDING if sort_order == 'asc' else pymongo.DESCENDING)]

    # Retrieve tasks from collection using find(), skip(), limit(), and sort()
    tasks = tasks_collection.find(filter_query).skip((page - 1) * per_page).limit(per_page).sort(sort_query)

    # Get the total number of tasks
    total_tasks = tasks_collection.count_documents(filter_query)

    # Calculate the total number of pages
    total_pages = total_tasks // per_page + (1 if total_tasks % per_page > 0 else 0)

    # Convert tasks to JSON format
    response = {
        'tasks': [],
        'pagination': {
            'current_page': page,
            'total_pages': total_pages,
            'per_page': per_page
        }
    }
    for task in tasks:
        task_obj = Task(task)
        task_obj.id = str(task['_id'])
        response['tasks'].append({
            'task_id': task_obj.id,
            'description': task_obj.input_data.get('description'),
            'priority': task_obj.input_data.get('priority'),
            'created_at': task_obj.created_at,
            'status': task_obj.status,
            'result': task_obj.result
        })

    return response

# Function to delete a task by ID
@app.route('/tasks/<task_id>', methods=['DELETE'])
def delete_task(task_id):
    task = tasks_collection.find_one({'_id': ObjectId(task_id)})
    if task:
        tasks_collection.delete_one({'_id': ObjectId(task_id)})

        # Get the job_id from the task document
        job_id = task.get('job_id', None)  # Use get() to avoid KeyError

        # Cancel the corresponding job in the task queue
        if job_id:
            for queue in [low_priority_queue, medium_priority_queue, high_priority_queue]:
                job = queue.fetch_job(job_id)
                if job:
                    job.cancel()
                    break

        return jsonify({'message': 'Task deleted'}), 200
    else:
        return jsonify({'error': 'Task not found'}), 404

@app.route('/tasks/delete_all', methods=['DELETE'])
def delete_all_tasks():
    # Delete all tasks in the database
    result = tasks_collection.delete_many({})

    # Cancel all jobs in the task queues
    for queue in [low_priority_queue, medium_priority_queue, high_priority_queue]:
        job_ids = [job.id for job in queue.get_jobs()]
        for job_id in job_ids:
            job = queue.fetch_job(job_id)
            if job:
                job.cancel()

    return jsonify({'message': f'{result.deleted_count} tasks deleted'}), 200


import sys
import os
import pickle
import numpy as np
from readjsonApi import get_feature_from_joints
from histogramApi import gen_vec_from_feature
from caculateDistance import get_sample_label
#¼ì²â
def get_label_score(skeletonFrameList,vectors):
    featureStr = get_feature_from_joints(skeletonFrameList)
    vecList = gen_vec_from_feature(featureStr)
    label, sim = get_sample_label(vecList, vectors)
    if np.isnan(sim):
        sim = 0
    return label, sim

#Â¼ÈëÊý¾Ý
def save_label(skeletonFrameList,datasetDir,label):
    featureStr = get_feature_from_joints(skeletonFrameList)
    vecList = gen_vec_from_feature(featureStr)
    files = os.listdir(datasetDir)
    videoIdList = [int(fName.split('v')[1].split('.')[0]) for fName in files if 'p'+label+'v' in fName]
    if len(videoIdList)==0:
        vId = 1
    else:
        vId = max(videoIdList)+1
    saveFileName = 'p'+label+'v'+str(vId)+'.txt'
    outputpath = os.path.join(datasetDir,saveFileName)
    pickle.dump(vecList, open(outputpath, 'wb'))
    return saveFileName

def get_joints_array(jointFilePath):
    file = open(jointFilePath)
    jointsFrameArray = []
    for line in file.readlines():
        if str(line)=="":
            continue
        jointsArray = line.split(',')
        jointsArray.__delitem__(len(jointsArray) - 1)
        jointsArray = [float(i) for i in jointsArray]
        jointsFrameArray.append(jointsArray)
    return jointsFrameArray

if __name__ == '__main__':
    jointsFrameArray = get_joints_array(sys.argv[1])
    featureStr = get_feature_from_joints(jointsFrameArray)
    vecList = gen_vec_from_feature(featureStr)
    #check dataset and caculate distance
    datasetDir = sys.argv[2]
    files = os.listdir(datasetDir)
    vectors = []
    for f in files:
        vector = pickle.load(open(os.path.join(datasetDir,f), 'rb'), encoding='iso-8859-1')
        vectors.append((vector, f.split('v')[0].split('p')[1]))

    label,sim = get_sample_label(vecList,vectors)
    print(str(label)+":"+str(sim))
    #output label and sim
    labelPath = sys.argv[3]
    f = open(labelPath,'w')
    f.writelines(str(label)+":"+str(sim))
    f.close()


abecedario = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',\
    'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',\
    'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', \
    'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

def caesar(texto, recorreN, operacion):
    textoFinal = ""
    if operacion == "decode":
        recorreN *= -1
    for letra in texto:
        if letra in abecedario:
            posicion_actual = abecedario.index(letra)
            nueva_posicion = posicion_actual + recorreN
            textoFinal += abecedario[nueva_posicion]
        else:
            textoFinal += letra
    print(f"Operacion elegida: {operacion}\nResultado: {textoFinal}")

repetir = True
while  repetir:

    quiero = input("Escribe \n\t'encode' para encriptar\n\t'decode' para desencriptar\n: ")
    text = input("Escribe el mensaje: ").lower()
    mueve = int(input("Escribe el numero de posiciones a mover: "))

    mueve = mueve % 26

    print("****************************************************")
    caesar(texto=text, recorreN=mueve, operacion=quiero)
    print("****************************************************")
    restart = input("Desea repetir el programa?\n\t'si' para repetir\n\t'no' para finalizar\n: ")
    if restart.lower() == "no":
        repetir = False
        print("Programa terminado")


import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

file_path_csv = '../data/data.csv'
data = pd.read_csv(file_path_csv)

data.head()

# Devices Used
plt.figure(figsize=(10, 6))
sns.countplot(x='DEVICE_TYPE_W63', data=data)
plt.title('Distribution of Devices Used')
plt.ylabel('Count')
plt.xlabel('Type of Device')
plt.xticks(ticks=[0, 1, 2], labels=['Desktop', 'Mobile Phone', 'Tablet'])
plt.show()

# Age Category
plt.figure(figsize=(10, 6))
sns.countplot(x='F_AGECAT', data=data)
plt.title('Distribution by Age')
plt.ylabel('Count')
plt.xlabel('Age Category')
plt.show()

# Education Level
plt.figure(figsize=(10, 6))
sns.countplot(x='F_EDUCCAT', data=data)
plt.title('Distribution by Level of Education')
plt.ylabel('Count')
plt.xlabel('Level of Education')
plt.show()

# Correlation Matrix
subset_columns = [
    'DEVICE_TYPE_W63',
    'LANG_W63_W63',
    'SNSUSE_W63',
    'VIDEOGAME_W63',
    'F_AGECAT',
    'F_EDUCCAT',
    'F_INCOME',
    'SMARTPHONE_W63',
    'F_SEX'
]

correlation_data = data[subset_columns]
correlation_matrix = correlation_data.corr()

plt.figure(figsize=(12, 8))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm')
plt.title('Correlation Matrix')
plt.show()


# alphabet = [',', "'", '?', ' ', 'a', '0', 'b', '1', 'c', '2', 'd', '9', 'e', '3', 'f', '"', 'g', 'h', '.', 'i',
#             '4', 'j', '5', 'k', 'l', '6', 'm', 'n', '7', '!', 'o', '8', 'p', 'q', 'r', 's', 't', 'u', 'v', '%', 'w',
#             'x', 'y', 'z']
import string

box = " "
box += string.ascii_letters
box += string.digits
box += string.punctuation
alphabet = []
for symbol in box:
    alphabet.append(symbol)

def encode(text, shift):
    new_text = ""
    for letter in text:
        idx = alphabet.index(letter)
        if idx + shift >= len(alphabet):
            new_idx = idx + shift - len(alphabet)
        else:
            new_idx = idx + shift
        new_letter = alphabet[new_idx]
        new_text += new_letter
    return new_text

def decode(text, shift):
    new_text = ""
    for letter in text:
        idx = alphabet.index(letter)
        if idx - shift < 0:
            new_idx = len(alphabet) - (shift - idx)
        else:
            new_idx = idx - shift
        new_letter = alphabet[new_idx]
        new_text += new_letter
    return new_text

def cipher_mashine(direction, text, shift):
    if shift > len(alphabet):
        shift = shift % len(alphabet)
    if direction == "encode":
        encode(text, shift)
    else:
        decode(text, shift)


# The Nature of Code
# Daniel Shiffman
# http://natureofcode.com

# Genetic Algorithm, Evolving Shakespeare

# A class to describe a psuedo-DNA, i.e. genotype
#   Here, a virtual organism's DNA is an array of character.
#   Functionality:
#      -- convert DNA into a string
#      -- calculate DNA's "fitness"
#      -- mate DNA with another set of DNA
#      -- mutate DNA

import random
import math

class DNA:
    def __init__(self, num):
        """Constructor (makes a random DNA)"""
        self.genes = ["x"] * num # The genetic sequence as a string
        self.fitness = 0.0

        for i in range(0,len(self.genes)):
            self.genes[i] = chr(random.randint(32,128)) # Pick from range of chars given by an ASCII number

    def getPhrase(self):
        return "".join(self.genes)

    def calcFitness(self, target):
        """Fitness function (returns floating point % of "correct" characters)"""
        score = 0
        for i in range(0, len(self.genes)):
            if(self.genes[i] == target[i]):
                score += 1
        # fancy fitness version:
        #self.fitness = math.pow(2, score)
        self.fitness = score / len(target)

    def crossover(self, partner):
        """Crossover"""
        child = DNA(len(self.genes)) # A new child

        midpoint = random.randint(0,len(self.genes)-1) # Pick a midpoint

        # Half from one, half from the other
        for i in range(0,len(self.genes)):
            if(i > midpoint):
                child.genes[i] = self.genes[i]
            else:
                child.genes[i] = partner.genes[i]
        return child

    def mutate(self, mutationRate):
        """Based on a mutation probability, picks a new random character"""
        for i in range(0, len(self.genes)):
            if(random.random() < mutationRate):
                self.genes[i] = chr(random.randint(32,128))


from django.urls import path
from django.contrib.auth.decorators import login_required
from apps.citas.views import *
urlpatterns =[
    path('listar_tipo_mascota/',login_required(TipoMascotaListView.as_view()), name='listar_tipo_mascota'),
    path('tipo_mascota/',login_required(TipoMascotaView.as_view()), name='tipo_mascota'),
    path('modificar_tipo_mascota/',login_required(TipoMascotaUpdateView.as_view()), name='modificar_tipo_mascota'),
    path('eliminar_tipo_mascota/<int:id>/',login_required(eliminarTipoMascota), name='eliminar_tipo_mascota'),

    path('listar_raza/',login_required(RazaListView.as_view()), name='listar_raza'),
    path('raza/',login_required(RazaView.as_view()), name='raza'),
    path('modificar_raza/',login_required(RazaUpdateView.as_view()), name='modificar_raza'),
    path('eliminar_raza/<int:id>/',login_required(eliminarRaza), name='eliminar_raza'),

    path('listar_mascota/',login_required(MascotaListView.as_view()), name='listar_mascota'),
    path('mascota/',login_required(MascotaView.as_view()), name='mascota'),
    path('modificar_mascota/',login_required(MascotaUpdateView.as_view()), name='modificar_mascota'),
    path('eliminar_mascota/<int:id>/',login_required(eliminarMascota), name='eliminar_mascota'),
    path('buscar_cliente/<str:dni>/',login_required(buscarCliente), name='buscar_cliente'),
    path('listar_tipo_servicio/',login_required(TipoServicioListView.as_view()), name='listar_tipo_servicio'),
    path('tipo_servicio/',login_required(TipoServicioView.as_view()), name='tipo_servicio'),
    path('modificar_tipo_servicio/',login_required(TipoServicioUpdateView.as_view()), name='modificar_tipo_servicio'),
    path('eliminar_tipo_servicio/<int:id>/',login_required(eliminarTipoServicio), name='eliminar_tipo_servicio'),

    path('listar_servicio/',login_required(ServicioListView.as_view()), name='listar_servicio'),
    path('servicio/',login_required(ServicioView.as_view()), name='servicio'),
    path('modificar_servicio/',login_required(ServicioUpdateView.as_view()), name='modificar_servicio'),
    path('eliminar_servicio/<int:id>/',login_required(eliminarServicio), name='eliminar_servicio'),

    #Cita
    #path('listar_cita/',login_required(CitaListView.as_view()), name='listar_cita'),
    #path('cita/', login_required(CitaView.as_view()), name='cita'),
    #path('modificar_cita/',login_required(MascotaUpdateView.as_view()), name='modificar_cita'),
    #path('eliminar_cita/<int:id>/',login_required(eliminarCita), name='eliminar_cita'),

]


import sys,argparse,codecs

from tfner.configfromfile import ModelConfig
from tfner.core import build_model

#----------------------------------------------------------------------
# main function
def main(argv):
    # parse command-line arguments
    parser=argparse.ArgumentParser(description="build a NN model for NER")
    # optional arguments
    #parser.add_argument("--arg",type=int,default=42,help="description")
    # positional arguments
    parser.add_argument("config_file",help="configuration file indicating the parameters for the training")

    param=parser.parse_args()

    # do main
    cfg=ModelConfig(param.config_file)
    build_model(cfg)

if __name__ == "__main__":
    main(sys.argv[1:])


from django.core.validators import MinValueValidator, MaxValueValidator
from django.db import models

class Task(models.Model):
    text = models.CharField(max_length=160)
    deadline = models.DateField()
    progress = models.IntegerField(
        default=0,
        validators=[
            MinValueValidator(0),
            MaxValueValidator(100)
        ]
    )