import os
from flask import Flask, request, abort, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS
from custom_validator import valid_response
from flask_cors.decorator import cross_origin
import random

from models import setup_db, Question, Category

QUESTIONS_PER_PAGE = 10

def create_app(test_config=None):
    # create and configure the app
    app = Flask(__name__)
    setup_db(app)
    CORS(app)
    #========================================#
    #                                        #
    #  CORS (Cross Origin Resource Sharing)- #
    #  settings                       #      #
    #                                        #
    #========================================#

    @app.after_request
    def after_request(response):
        response.headers.add('Access-Control-Allow-Origin', '*')
        response.headers.add('Access-Control-Allow-Mehotds',
                             'GET, POST, PATCH, DELETE')
        response.headers.add('Content-Type', 'application/json')

        return response
    #========================================#
    #                                        #
    #  HELPERS - paginating function         #
    #  and filter_questions function         #
    #                                        #
    #========================================#

    def paginate_questions(request, selection):
        page = request.args.get('page', 1, type=int)
        start = (page - 1) * QUESTIONS_PER_PAGE
        end = start + QUESTIONS_PER_PAGE
        questions = [questions.format() for questions in selection]
        current_questions = questions[start:end]

        return current_questions

    def filter_questions(previous_questions, questions):
        return [question for question in questions if question['id'] not in previous_questions]

    def get_filtered_questions(previous_questions):
        questions = Question.query.all()
        questions = [question.format()
                     for question in questions]
        questions = filter_questions(
            previous_questions, questions)
        return questions
    #========================================#
    #                                        #
    #   [GET] /categories - retrive all      #
    #   categories                           #
    #                                        #
    #========================================#

    @app.route('/categories', methods=['GET'])
    @cross_origin()
    def get_all_catgories():
        categories = Category.query.all()
        formatted_categories = {}
        for category in categories:
            formatted_categories[str(category.format()['id'])] = category.format()[
                'type']

        return jsonify({
            "success": True,
            "categories": formatted_categories,
            "total_categories": len(categories)
        })
    #========================================#
    #                                        #
    #  [GET] /categories/<category_id> - get #
    #  get category by id                    #
    #                                        #
    #  [DELETE] /categories/<category_id> -  #
    #  delete category                       #
    #                                        #
    #  [PATCH] - categories/<category_id> -  #
    #  update category                       #
    #                                        #
    #========================================#

    @app.route('/categories/<int:category_id>', methods=['GET', 'PATCH', 'DELETE'])
    @cross_origin()
    def get_or_delete_or_update_category_by_id(category_id):
        if request.method == 'GET':
            category = Category.query.get_or_404(category_id)
            return jsonify({
                "category_id": category.id,
                "category_type": category.type,
                "total_categories": len(Category.query.all()),
                "success": True
            })
        if request.method == 'DELETE':
            category = Category.query.get_or_404(category_id)
            try:
                category.delete()
                return jsonify({
                    "deleted_category_id": category.id,
                    "success": True
                })
            except:
                abort(422)

        if request.method == 'PATCH':
            category = Category.query.get_or_404(category_id)
            data = request.get_json()
            try:
                if 'type' in data:
                    if len(data['type']) > 3:
                        category.type = data['type']
                    else:
                        abort(400)
                category.update()
                return jsonify({
                    "success": True,
                    "updated_category_id": category.id
                })
            except:
                abort(400)
    #========================================#
    #                                        #
    #   [POST] /categories - create new      #
    #   category                             #
    #                                        #
    #========================================#

    @app.route('/categories', methods=['POST'])
    @cross_origin()
    def add_new_category():
        data = request.get_json()
        if not data:
            abort(400)
        new_category = data.get('type')
        print(data)
        if not new_category or len(new_category) < 3:
            abort(400)
        try:
            category = Category(type=new_category)
            category.insert()
            return jsonify({
                "created_category_id": category.id,
                "success": True
            })
        except:
            abort(400)
    #========================================#
    #                                        #
    #   [GET]                                #
    #   /categories/<category_id>/questions  #
    #   - get questions by category          #
    #                                        #
    #========================================#

    @app.route('/categories/<int:category_id>/questions', methods=['GET'])
    @cross_origin()
    def get_questions_by_category(category_id):
        current_category = Category.query.get_or_404(category_id)
        current_questions = paginate_questions(
            request, current_category.questions)
        return jsonify({
            "questions": current_questions,
            "total_questions": len(Question.query.all()),
            "current_category": current_category.type,
            "success": True
        })
    #========================================#
    #                                        #
    #  [GET] /questions - get all questions  #
    #                                        #
    #========================================#

    @app.route('/questions', methods=['GET'])
    @cross_origin()
    def get_all_questions():
        selection = Question.query.all()
        current_questions = paginate_questions(request, selection)
        page = request.args.get('page', 1, type=int)
        if page != 1 and len(current_questions) == 0:
            abort(404)
        categories = Category.query.all()
        formatted_categories = {}
        for category in categories:
            formatted_categories[str(category.format()['id'])] = category.format()[
                'type']
        return jsonify({
            "questions": current_questions,
            "total_questions": len(selection),
            "categories": formatted_categories,
            "success": True
        })
    #========================================#
    #                                        #
    #   [POST] /questions - create new       #
    #   question                             #
    #                                        #
    #========================================#

    @app.route('/questions', methods=['POST'])
    @cross_origin()
    def create_new_question():
        data = request.get_json()
        if not data:
            abort(400)
        new_question = data.get('question')
        new_answer = data.get('answer')
        parent_category = data.get('category')
        new_difficulty = data.get('difficulty')
        search_term = data.get('searchTerm')
        try:
            if search_term:
                questions = Question.query.filter(
                    Question.question.ilike(f'%{search_term}%'))
                print(questions)
                current_questions = paginate_questions(request, questions)
                return jsonify({
                    "questions": current_questions,
                    "total_questions": len(Question.query.all())
                })

            else:
                category_id = int(parent_category)
                category_parent = Category.query.get(category_id)
                if len(new_question) <= 5 or category_parent is None:
                    abort(400)
                create_question = Question(question=new_question, answer=new_answer,
                                           category=category_parent, difficulty=new_difficulty)
                create_question.insert()
                return jsonify({
                    "success": True,
                    "created": create_question.id
                })
        except:
            abort(400)
    #========================================#
    #                                        #
    #   [GET] /questions/<question_id> - get #
    #   question by id                       #
    #                                        #
    #   [DELETE] - questions/<question_id> - #
    #   delete question                      #
    #                                        #
    #   [PATCH] - questions/<question_id> -  #
    #   update question                      #
    #                                        #
    #========================================#

    @app.route('/questions/<int:question_id>', methods=['GET', 'DELETE', 'PATCH'])
    @cross_origin()
    def get_or_delete_question(question_id):
        if request.method == 'GET':
            question = Question.query.get_or_404(question_id)
            return jsonify({
                "question_id": question.id,
                "question": question.question,
                "answer": question.answer,
                "difficulty": question.difficulty,
                "category_id": question.category.format()["id"],
                "category": question.category.format()["type"],
                "total_questions": len(Question.query.all()),
                "success": True
            })

        if request.method == 'PATCH':
            question = Question.query.get_or_404(question_id)
            data = request.get_json()

            try:
                if valid_response(data, 'question'):
                    question.question = data['question']
                if valid_response(data, 'answer'):
                    question.answer = data['answer']
                if valid_response(data, 'difficulty'):
                    question.difficulty = int(data['difficulty'])
                if valid_response(data, 'category', Category):
                    try:
                        category = Category.query.get(int(data['category']))
                        if category:
                            question.category = category
                        else:
                            abort(400)
                    except:
                        abort(400)
                question.update()
                return jsonify({
                    'success': True,
                    'updated_question_id': question.id
                })
            except:
                abort(400)

        if request.method == 'DELETE':
            question = Question.query.get_or_404(question_id)

            if question:
                question.delete()
                return jsonify({
                    "deleted_question_id": question.id,
                    "success": True
                })
            else:
                abort(422)
    #======================================#
    #                                      #
    #   [POST] /quizzes - play and enjoy   #
    #   with trivia quiz game              #
    #                                      #
    #======================================#

    @app.route('/quizzes', methods=['POST'])
    @cross_origin()
    def play_trivia_quizz_game():
        data = request.get_json()
        if data:
            previous_questions = data.get('previous_questions', [])
            if previous_questions:
                for question_id in previous_questions:
                    if not str(question_id).isdigit():
                        abort(400)
            quiz_category = data.get('quiz_category', {})
            if quiz_category:
                if 'id' in quiz_category:
                    if not str(quiz_category['id']).isdigit():
                        abort(400)
                else:
                    abort(400)
            if not quiz_category or int(quiz_category['id']) == 0:
                questions = Question.query.all()
                questions = [question.format()
                             for question in questions]
                questions = filter_questions(
                    previous_questions, questions)
            else:
                category = Category.query.get(int(quiz_category['id']))
                if category and category != None:
                    questions = Question.query.filter(
                        Question.category == category).all()
                    questions = [question.format()
                                 for question in questions]
                    questions = filter_questions(
                        previous_questions, questions)
                else:
                    abort(400)
            if len(questions) > 0:
                return jsonify({
                    "previous_questions": previous_questions,
                    "quiz_category": quiz_category,
                    "question": questions[random.randrange(0, len(questions))],
                    "success": True
                })
            else:
                return jsonify({
                    "previous_questions": previous_questions,
                    "question": None,
                    "success": True
                })

        else:
            abort(400)
    #====================#
    #                    #
    #   ErrorHandlers    #
    #                    #
    #====================#
    #                    #
    #   [400] - bad      #
    #   request          #
    #                    #
    #====================#

    @app.errorhandler(400)
    def bad_request(e):
        return jsonify({
            'success': False,
            'error': 400,
            'message': 'bad request'
        }), 400
    #====================#
    #                    #
    #   [404] - resource #
    #   not found        #
    #                    #
    #====================#

    @app.errorhandler(404)
    def resource_not_found(e):
        return jsonify({
            'success': False,
            'error': 404,
            'message': 'resource not found'
        }), 404
    #====================#
    #                    #
    #   [405] - method   #
    #   not allowed      #
    #                    #
    #====================#

    @app.errorhandler(405)
    def method_not_allowed(e):
        return jsonify({
            'success': False,
            'error': 405,
            'message': 'method now allowed'
        }), 405
    #====================#
    #                    #
    #   [422] - unproces #
    #   -sable entity    #
    #                    #
    #====================#

    @app.errorhandler(422)
    def unprocessable_entity(e):
        return jsonify({
            'success': False,
            'error': 422,
            'message': 'unprocessable entity'
        }), 422

    #====================#
    #                    #
    #   [500] - internal #
    #   server error     #
    #                    #
    #====================#

    @app.errorhandler(500)
    def internal_server_error(e):
        return jsonify({
            'success': False,
            'error': 500,
            'message': 'internal server error'
        }), 500

    return app


from ..alarm_item import AlarmItem, AlarmSeverity
from qtpy.QtCore import Qt
from qtpy.QtGui import QBrush
import pytest

def test_is_leaf():
    """Check that an alarm item with no children is considered a leaf"""
    alarm_root = AlarmItem("PV:GROUP")
    assert alarm_root.is_leaf()

    child_node = AlarmItem("TEST:PV")
    alarm_root.append_child(child_node)

    assert not alarm_root.is_leaf()

@pytest.mark.parametrize(
    "alarm_severity, expected_state",
    [
        (AlarmSeverity.MINOR, True),
        (AlarmSeverity.MAJOR, True),
        (AlarmSeverity.INVALID, True),
        (AlarmSeverity.UNDEFINED, True),
        (AlarmSeverity.MINOR_ACK, False),
        (AlarmSeverity.MAJOR_ACK, False),
        (AlarmSeverity.INVALID_ACK, False),
        (AlarmSeverity.UNDEFINED_ACK, False),
    ],
)
def test_is_in_activate_alarm_state(alarm_severity, expected_state):
    """Confirm that the alarm item correctly reports whether or not it is in an active alarm state"""
    alarm_item = AlarmItem("TEST:PV")
    alarm_item.alarm_severity = alarm_severity
    assert alarm_item.is_in_active_alarm_state() == expected_state

def test_is_enabled():
    """Verify the various methods of indicating an alarm item is enabled work properly"""
    alarm_item = AlarmItem("TEST:PV")
    assert alarm_item.is_enabled()  # Should be set to True by default

    alarm_item.enabled = False
    assert not alarm_item.is_enabled()

    alarm_item.enabled = "06/03/2022 15:00:00"  # Simulate a bypass until date
    assert not alarm_item.is_enabled()

def test_assign_parent():
    """Confirm that assigning a parent to an alarm item happens properly"""
    alarm_item = AlarmItem("TEST:PV")
    parent_item = AlarmItem("GROUP:NAME")

    alarm_item.assign_parent(parent_item)
    assert alarm_item.parent_item == parent_item

def test_child():
    """Check that returning an item's children by index works as expected"""
    alarm_item = AlarmItem("TEST:PV")
    child_one = AlarmItem("CHILD:PV:ONE")
    child_two = AlarmItem("CHILD:PV:TWO")

    assert alarm_item.child_count() == 0
    alarm_item.append_child(child_one)
    assert alarm_item.child_count() == 1
    alarm_item.append_child(child_two)
    assert alarm_item.child_count() == 2

    assert alarm_item.child(0).name == "CHILD:PV:ONE"
    assert alarm_item.child(1).name == "CHILD:PV:TWO"
    assert alarm_item.child(2) is None

@pytest.mark.parametrize(
    "enabled, severity, expected_color",
    [
        (False, AlarmSeverity.MAJOR, QBrush(Qt.gray)),
        (True, AlarmSeverity.OK, QBrush(Qt.darkGreen)),
        (True, AlarmSeverity.UNDEFINED, QBrush(Qt.magenta)),
        (True, AlarmSeverity.MAJOR, QBrush(Qt.red)),
        (True, AlarmSeverity.MINOR, QBrush(Qt.darkYellow)),
        (True, AlarmSeverity.MAJOR_ACK, QBrush(Qt.darkRed)),
        (True, AlarmSeverity.MINOR_ACK, QBrush(Qt.darkGray)),
        (True, AlarmSeverity.UNDEFINED_ACK, QBrush(Qt.darkMagenta)),
        (True, AlarmSeverity.INVALID, QBrush(Qt.magenta)),
        (True, AlarmSeverity.INVALID_ACK, QBrush(Qt.darkMagenta)),
    ],
)
def test_display_color(enabled, severity, expected_color):
    """Verify that the color the alarm is to be drawn in is returned correctly"""
    alarm_item = AlarmItem("TEST:PV")
    alarm_item.enabled = enabled
    alarm_item.alarm_severity = severity
    assert alarm_item.display_color(severity) == expected_color


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Oct  9 10:50:18 2018

@author: steven
"""

import math

import numpy as np

import volmdlr as vm
from volmdlr.core import EdgeStyle
import volmdlr.primitives2d as primitives2d
import volmdlr.primitives3d as primitives3d
from volmdlr import curves
# Ajout commentaire juste pour tester
# =============================================================================
#  2D version
# =============================================================================

#p1 = vm.Point2D((0, 0))
#p11 = vm.Point2D((0.5, 0))
#p2 = vm.Point2D((1, 0))
#p3 = vm.Point2D((1, 1))
#p4 = vm.Point2D((2.1, 3.23))
#p5 = vm.Point2D((0, 1.23))
#p4 = vm.Point2D((0,1))
#p5 = vm.Point2D((0,2))

p0 = vm.Point2D(0.2, -0.5)

p1 = vm.Point2D(0  , 0  )
p2 = vm.Point2D(0.5, 0  )
p3 = vm.Point2D(1  , 0  )
p4 = vm.Point2D(1.5, 0  )

p5 = vm.Point2D(2  , 0.4)
p6 = vm.Point2D(2.5, 0.4)
p7 = vm.Point2D(3  , 0.4)
p8 = vm.Point2D(3.5, 0.2)

rl2D_o = primitives2d.OpenedRoundedLineSegments2D(
    [p0, p1, p2, p3, p4, p5, p6, p7, p8], {},
#                                        {2:0.3, 4:0.1, 3:0.1},
                                        adapt_radius=True)

rl2D_o2 = rl2D_o.offset_lines([2], -1.25)
ax= rl2D_o.plot()
rl2D_o2.plot(ax=ax)

rl2D_c = primitives2d.ClosedRoundedLineSegments2D([p0, p1, p2, p3, p4, p5, p6, p7, p8], {},
                                       # {0:1, 1:0.05, 2:0.05, 3:1},
                                        adapt_radius=True)
rl2D_c2 = rl2D_c.offset_lines([2], 0.2)
ax2 = rl2D_c.plot()
rl2D_c2.plot(ax=ax2)

com = rl2D_c2.center_of_mass()
cut_line = curves.Line2D(com, com+ vm.Point2D.random(-1, 1, 0, 1))
ax3 = rl2D_c2.plot()
cut_line.plot(ax=ax3, edge_style=EdgeStyle(color='red'))
com.plot(color='b', ax=ax3)

cutted_contours = rl2D_c2.cut_by_line(cut_line)
list_centers_of_mass = [contour.center_of_mass() for contour in cutted_contours]

u1 = cut_line.point_projection(
    list_centers_of_mass[0])[0] - list_centers_of_mass[0]
u1 = u1.unit_vector()
sign = -1
for contour in cutted_contours:
    r, g, b = np.random.random(), np.random.random(), np.random.random()
    color = (r, g, b)
    contour.translation(sign*0.05*u1).plot(ax=ax3, edge_style=EdgeStyle(color=color))
    sign *= -1

# assert math.isclose(cutted_contours[0].area()+cutted_contours[1].area(),
#                     rl2D_c2.area(), abs_tol=1e-12)

# ax4 = rl2D_c2.plot()
# mesh = rl2D_c2.grid_triangulation(25, 10)
# mesh.plot(ax=ax4)

# =============================================================================
#  3D Version
# =============================================================================
#
#p1 = vm.Point3D((0, 0, 0))
#p2 = vm.Point3D((1, 0, 0))
#p3 = vm.Point3D((1, 1, 1.2))
#p4 = vm.Point3D((2.1, 3.23, 0.3))
#p5 = vm.Point3D((0, 1.23,4.6))
#
#
#rl3D = primitives3D.RoundedLineSegments3D([p1, p2, p3, p4, p5],
#                                        {2:4},
#                                        closed=True, adapt_radius=True)
#rl3D.MPLPlot()
#m = vm.VolumeModel([('rl3D', [rl3D])])
#m.FreeCADExport('rl3D')

#{1:0.3, 2:0.1, 3:0.5}


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Nov 22 19:07:57 2019

@author: fatimamh
"""
import os
from os import path
import sys
import time
from datetime import datetime
import math
import random
import numpy as np
import pandas as pd

import torch
import torch.nn as nn
from torch import optim
from torch.autograd import Variable

from lib.utils.loader_utils import get_data
from lib.utils.file_utils import get_files
from lib.utils.model_utils import get_time
from lib.utils.model_utils import save_checkpoint
from lib.utils.model_utils import load_checkpoint
from lib.utils.file_utils import print_writer
from lib.utils.file_utils import plot_writer
from lib.utils.file_utils import build_row

from lib.utils.plot_utils import showPlot

'''----------------------------------------------------------------
'''

def train(device, model, data_loader, enc_optimizer, dec_optimizer, criterion, clip):
    ''' Training loop for the model to train.
    Args:
        model: A Seq2Seq model instance.
        iterator: A DataIterator to read the data.
        optimizer: Optimizer for the model.
        criterion: loss criterion.
        clip: gradient clip value.
    Returns:
        epoch_loss: Average loss of the epoch.
    '''

    # set model into train mode
    model.train()
    # define epoch loss
    epoch_loss = 0
    batch_num = 1
    total_batch = len(data_loader)
    for input_tensor, target_tensor in data_loader:
        batch_size = input_tensor.size()[0]
        if batch_size == 1: continue
        print('\t---Train Batch: {}/{}---'.format(batch_num, total_batch))
        input_tensor, target_tensor = input_tensor.to(device), target_tensor.to(device)
        '''------------------------------------------------------------
        3: Clear old gradients from the last step
        ------------------------------------------------------------'''
        enc_optimizer.zero_grad()
        dec_optimizer.zero_grad()
        #loss, predictions, attentions = model(input_tensor, target_tensor, criterion, teacher_forcing=True)
        loss, predictions = model(input_tensor, target_tensor, criterion, teacher_forcing=True)
        #print('predictins: {}'.format(predictions.shape))
        #print('target_tensor: {}'.format(target_tensor.shape))
        '''------------------------------------------------------------
        13: Compute the derivative of the loss w.r.t. the parameters
            (or anything requiring gradients) using backpropagation.
        ------------------------------------------------------------'''
        #del predictions
        loss.backward()
        # clip the gradients
        torch.nn.utils.clip_grad_norm_(model.parameters(), clip)
        '''------------------------------------------------------------
        14: Update optimizer to take a step based on the gradients
            of the parameters.
        ------------------------------------------------------------'''
        enc_optimizer.step()
        dec_optimizer.step()
        epoch_loss += loss.item()
        batch_num+=1

    epoch_loss /= len(data_loader)
    return epoch_loss

'''----------------------------------------------------------------
'''
def evaluate(device, model, data_loader, criterion):
    ''' Evaluation loop for the model to evaluate.
    Args:
        model: A Seq2Seq model instance.
        iterator: A DataIterator to read the data.
        criterion: loss criterion.
    Returns:
        epoch_loss: Average loss of the epoch.
    '''
	#set model in evaluation mode
    #  some layers have different behavior during train/and evaluation (like BatchNorm, Dropout) so setting it matters.
    model.eval()
	#declare loss
    epoch_loss = 0
    # we don't need to update the model parameters. only forward pass.
    with torch.no_grad():
        batch_num = 1
        total_batch = len(data_loader)

        for input_tensor, target_tensor in data_loader:
            batch_size = input_tensor.size()[0]
            if batch_size == 1: continue
            print('\t---Eval Batch: {}/{}---'.format(batch_num, total_batch))
            input_tensor, target_tensor = input_tensor.to(device), target_tensor.to(device)
            #loss, predictions, attentions = model(input_tensor, target_tensor, criterion, teacher_forcing=False)
            loss, predictions = model(input_tensor, target_tensor, criterion, teacher_forcing=False)

            epoch_loss += loss.item()
            batch_num +=1

    epoch_loss /= len(data_loader)
    return epoch_loss

'''----------------------------------------------------------------
'''

def train_model(device, config, model, criterion, enc_optimizer, dec_optimizer):

    '''-----------------------------------------------
    Step 1: Get from config
    -----------------------------------------------'''
    s_epoch     = None
    e_epoch     = config["epochs"]
    clip        = config["grad_clip"]
    print_every = config["print_every"]
    plot_every  = config["plot_every"]
    print_file  = config["print_file"]
    plot_file   = config["plot_file"]

    '''-----------------------------------------------
    Step 2: Get data_loaders
    -----------------------------------------------'''
    train_loader = get_data(config, "train")
    val_loader   = get_data(config, "val")

    '''-----------------------------------------------
    Step 3: From scratch or resume
    -----------------------------------------------'''
    # TO DO how to make it in a function
    bm_file     = os.path.join(config["check_point_folder"], config["best_model_file"])
    ckpt_file   = os.path.join(config["check_point_folder"], config["check_point_file"])
    #model_file = "best-model.pth.tar"

    if path.exists(ckpt_file):
        checkpoint 		= load_checkpoint(ckpt_file)
        s_epoch 		= checkpoint["epoch"]
        best_valid_loss = checkpoint["loss"]

        model.load_state_dict(checkpoint["model_state"])
        enc_optimizer.load_state_dict(checkpoint["enc_optimizer"])
        dec_optimizer.load_state_dict(checkpoint["dec_optimizer"])

    elif path.exists(bm_file):
        checkpoint 		= load_checkpoint(bm_file)
        s_epoch 		= checkpoint["epoch"]
        best_valid_loss = checkpoint["loss"]

        model.load_state_dict(checkpoint["model_state"])
        enc_optimizer.load_state_dict(checkpoint["enc_optimizer"])
        dec_optimizer.load_state_dict(checkpoint["dec_optimizer"])

    else: # from scratch
        s_epoch = 1
        best_valid_loss = float('inf')

    plot_train_loss_total = 0
    plot_valid_loss_total = 0
    '''-----------------------------------------------
    Step 2: Get data_loaders
    -----------------------------------------------'''

    # Training and evluation using train and val sets
    for epoch in range(s_epoch, e_epoch+1):
        print('--------Epoch:{} starts--------\n'.format(epoch))
        train_loss = 0
        valid_loss = 0
        '''------------------------------------------------------------
        5: Get batches from loader and pass to train
        ------------------------------------------------------------'''
        start_time = datetime.now()
        train_loss = train(device, model, train_loader, enc_optimizer, dec_optimizer, criterion, clip)
        valid_loss = evaluate(device, model, val_loader, criterion)
        end_time = datetime.now()
        time_diff = get_time(start_time, end_time)

        plot_train_loss_total += train_loss
        plot_valid_loss_total += valid_loss

        print('Epoch: {}/{} ==> {:.0f}% | Time: {}'.format(epoch, e_epoch, epoch/e_epoch*100, time_diff))

        is_best = bool(valid_loss < best_valid_loss)
        best_valid_loss = (min(valid_loss, best_valid_loss))

        print_row = build_row(epoch, train_loss, valid_loss, best_valid_loss, time_diff)
        print_writer(print_file, print_row)

        # Save checkpoint if is a new best
        if is_best:
            save_checkpoint({'epoch': epoch,
	    				 	 'model_state': model.state_dict(),
	    				 	 'enc_optimizer': enc_optimizer.state_dict(),
                             'dec_optimizer': dec_optimizer.state_dict(),
	    				 	 'loss': best_valid_loss}, bm_file, True)

        if epoch%5 == 0:
            save_checkpoint({'epoch': epoch,
	    					 'model_state': model.state_dict(),
                             'enc_optimizer': enc_optimizer.state_dict(),
                             'dec_optimizer': dec_optimizer.state_dict(),
	    				     'loss': best_valid_loss}, ckpt_file, False)

        if epoch % plot_every == 0:

            plot_train_loss_avg = plot_train_loss_total/plot_every
            plot_valid_loss_avg = plot_valid_loss_total/plot_every

            plot_row = build_row(epoch, plot_train_loss_avg, plot_valid_loss_avg)
            plot_writer(plot_file, plot_row)

            plot_train_loss_total = 0
            plot_valid_loss_total = 0

    showPlot(config["out_folder"], plot_file)

    return True


class BIT:
    def __init__(self, n):
        self.n = n
        self.a = [0] * (n + 1)

    # a[i] に xを加算する
    def add(self, i, x):
        if i == 0:
            return
        k = i
        while k <= self.n:
            self.a[k] += x
            k += (k & -k)

    # b[i] + b[i+1] + ... + b[j]
    def sum(self, i, j):
        return self.sum_sub(j) - self.sum_sub(i - 1)

    def sum_sub(self, i):
        if i == 0:
            return 0
        s = 0
        k = i
        while k > 0:
            s += self.a[k]
            k -= (k & -k)
        return s

N = int(input())
C = list(map(int, input().split()))
X = list(map(int, input().split()))

a = [[] for _ in range(N+1)]
for c, x in zip(C, X):
    a[0].append(x)
    a[c].append(x)

bits = BIT(N)
ans = 0
for c in range(N+1):
    for j, x in enumerate(a[c]):
        k = j - bits.sum(i=1, j=x)
        bits.add(x, 1)
        if c == 0:
            ans += k
        else:
            ans -= k
    print(a[c])
    print(bits.a)
    for x in a[c]:
        bits.add(x, -1)
        print(bits.a)
print(ans)


# -*- coding: utf-8 -*-
"""
Created on Sun Mar 14 15:28:42 2021

@author: Lim Zi Xuan
"""

import streamlit as st
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.figure_factory as ff
import altair as alt
import plotly.graph_objects as go
import datetime
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.svm import SVR
from sklearn.preprocessing import PolynomialFeatures
from datetime import timedelta

st.cache(persist=True)
def load_data():
    covid=pd.read_csv("coviddata0330.csv")
    latest=covid[covid["Date"] == "2021-03-30"][["Country","Population","Confirmed","Deaths","Recovered","Active"]]
    confirmed_df = pd.read_csv("confirmed_0330.csv")
    death_df = pd.read_csv("deaths_0330.csv")
    recovered_df = pd.read_csv("recovered_0330.csv")
    return covid, latest, confirmed_df, death_df, recovered_df
covid, latest, confirmed_df, death_df, recovered_df= load_data()

covid1 = covid.copy()
covid1["Date"]=pd.to_datetime(covid1["Date"], errors='coerce')

def breakline():
    return st.markdown("
", unsafe_allow_html=True)

st.markdown("
 Ъда Covid-19 Dashboard Ъда
", unsafe_allow_html=True)

confirmed_total = int(latest['Confirmed'].sum())
active_total = int(latest['Active'].sum())
deaths_total = int(latest['Deaths'].sum())
recovered_total = int(latest['Recovered'].sum())

st.title("World Data Summary: ")
st.markdown(
        """
        Total Confirmed Cases | Total Active Cases | Total Recovered Cases | Total Deaths Cases
        ----------------|--------------|------------|----------
        {0}             | {1}          | {2}        | {3}

        """.format(confirmed_total, active_total, recovered_total, deaths_total)
    )

breakline()

st.markdown("
Covid pandemic across the world
",
            unsafe_allow_html=True)

df_list = []
labels = []
colors = []
colors_dict =  {
        'Confirmed' : 'lightblue',
        'Deaths' : 'red',
        'Recovered' : 'green'
    }
features = st.multiselect("Select Confirmed/Deaths/Cases : ",
                          ['Confirmed', 'Deaths', 'Recovered'],
                          default = ['Confirmed','Recovered','Deaths'],
                          key = 'world')
for feature in features:
    if feature == 'Confirmed':
        labels.append('Confirmed')
        colors.append(colors_dict['Confirmed'])
        df_list.append(confirmed_df)
    if feature == 'Deaths':
        labels.append('Deaths')
        colors.append(colors_dict['Deaths'])
        df_list.append(death_df)
    if feature == 'Recovered':
        labels.append('Recovered')
        colors.append(colors_dict['Recovered'])
        df_list.append(recovered_df)

    line_size = [4, 5, 6]

fig_world = go.Figure();

for i, df in enumerate(df_list):
        x_data = np.array(list(df.iloc[:, 4:].columns))
        y_data = np.sum(np.asarray(df.iloc[:,4:]),axis = 0)

        fig_world.add_trace(go.Scatter(x=x_data, y=y_data, mode='lines+markers',
        name=labels[i],
        line=dict(color=colors[i], width=line_size[i]),
        connectgaps=True,
        text = "Total " + str(labels[i]) +": "+ str(y_data[-1])
        ));

        fig_world.update_layout(
        title="COVID-19 cases of World",
        xaxis_title='Date',
        yaxis_title='No. of Cases',
        margin=dict(l=20, r=20, t=40, b=20),
        paper_bgcolor="white",
        width = 800,

        );

fig_world.update_yaxes(type="linear")
st.plotly_chart(fig_world);

st.header("Select Country to visualize")
city = st.selectbox("Country",covid["Country"][:190])

st.markdown("Info: ")
filtered_dict = covid[covid['Country']== city].to_dict('records')[0]
filtered_dict1 = latest[latest['Country']== city].to_dict('records')[0]

fig_dc = go.Figure()
fig_dc.add_trace(
        go.Indicator(mode = "number",
        value = filtered_dict['Population'],
        #delta = {'position': "top", 'reference': 320},
        domain = {'row': 0, 'column': 0},
        title = {'text': 'Population
 '}
        ))
fig_dc.add_trace(
        go.Indicator(mode = "number",
        value = filtered_dict1['Confirmed'],
        #delta = {'position': "top", 'reference': 320},
        domain = {'row': 0, 'column': 1},
        title = {'text': 'Confirmed
 Case', 'font.color': "lightblue"}
        ))
fig_dc.add_trace(
        go.Indicator(mode = "number",
        value = filtered_dict1['Deaths'],
        #delta = {'position': "top", 'reference': 320},
        domain = {'row': 0, 'column': 2},
        title = {'text': 'Deaths
 Case', 'font.color': "red"}
        ))
fig_dc.add_trace(
        go.Indicator(mode = "number",
        value = filtered_dict1['Recovered'],
        #delta = {'position': "top", 'reference': 320},
        domain = {'row': 0, 'column': 3},
        title = {'text': 'Recovered
 Case', 'font.color': "green"}
        ))
fig_dc.update_layout(
        grid = {'rows': 1, 'columns': 4, 'pattern': "independent"},
        width = 700,
        height = 200,
        )
st.plotly_chart(fig_dc)

def dataf(latest):
    total_d = pd.DataFrame({
        'Status':['Confirmed', 'Deaths', 'Recovered', 'Active'],
        'Cases':(latest['Confirmed'].iloc[0],
                 latest['Deaths'].iloc[0],
                 latest['Recovered'].iloc[0],
                 latest['Active'].iloc[0])})
    return total_d

tt = dataf(latest[latest["Country"]== city])
if st.checkbox("View Bar chart",False):
    bar = px.bar(tt, x= 'Status', y= 'Cases',color = 'Status')
    st.plotly_chart(bar)

st.header(f"View Daily Cases for {city}")
chartopt = st.radio("Select type of Chart",("Line Chart","Scatter Chart"))
daily_c = st.selectbox("Select option",('Daily New Cases', 'Daily New Recoveries','Daily New Deaths'))

city1= covid[covid["Country"]== city]
new_c  = px.line(city1, x = city1["Date"], y = city1["New cases"], title= "New Cases in {}".format(city), width= 700, height= 450)
new_cs  = px.scatter(city1, x = city1["Date"], y = city1["New cases"], title= "New Cases in {}".format(city), width= 700, height= 450)

new_d  = px.line(city1, x = city1["Date"], y = city1["New deaths"], title= "New Deaths in {}".format(city), width= 700, height= 450)
new_ds  = px.scatter(city1, x = city1["Date"], y = city1["New deaths"], title= "New Deaths in {}".format(city), width= 700, height= 450)

new_r  = px.line(city1, x = city1["Date"], y = city1["New recovered"], title= "New Recovered in {}".format(city), width= 700, height= 450)
new_rs  = px.scatter(city1, x = city1["Date"], y = city1["New recovered"], title= "New Recovered in {}".format(city), width= 700, height= 450)

if daily_c =='Daily New Cases':
    if chartopt == "Line Chart":
        st.plotly_chart(new_c)
    else:
        st.plotly_chart(new_cs)
elif daily_c =='Daily New Recoveries':
    if chartopt == "Line Chart":
        st.plotly_chart(new_r)
    else:
        st.plotly_chart(new_rs)
elif daily_c =='Daily New Deaths':
    if chartopt == "Line Chart":
        st.plotly_chart(new_d)
    else:
        st.plotly_chart(new_ds)

st.header(f" View Cases for {city} : ")
case_type = st.selectbox("Select case type : ", ['Confirmed', 'Deaths', 'Recovered', 'Confirmed, Deaths and Recovered'])

case_c  = go.Line(x = pd.to_datetime(city1["Date"]), y = city1["Confirmed"], name = 'TOTAL CONFIRMED CASES')
case_d  = go.Line( x = pd.to_datetime(city1["Date"]), y = city1["Deaths"], name = 'TOTAL DEATHS')
case_r  = go.Line(x = pd.to_datetime(city1["Date"]), y = city1["Recovered"], name = 'TOTAL RECOVERED')

if case_type == 'Confirmed':
    figc = go.Figure(case_c)
    figc.update_layout(title = "Confirmed Cases in {}".format(city))
    st.plotly_chart(figc)
elif case_type == 'Deaths':
    figd = go.Figure(case_d)
    figd.update_layout(title = "Deaths Cases in {}".format(city))
    st.plotly_chart(figd)
elif case_type == 'Recovered':
    figr = go.Figure(case_r)
    figr.update_layout(title = "Recovered Cases in {}".format(city))
    st.plotly_chart(figr)
elif case_type == 'Confirmed, Deaths and Recovered':
    fign = go.Figure([case_c, case_d, case_r])
    fign.update_layout(legend_orientation='h', title = "Confirmed, Deaths and Recovered Cases in {}".format(city))
    st.plotly_chart(fign)

st.header(f"View Cases for {city} by Month/Day/Date")

a= alt.Chart(covid1[covid1["Country"]==city],width=500,height=400).mark_bar().encode(
    x="day(Date):O",
    y="month(Date):O",
    color=alt.Color('sum(New deaths)',scale=alt.Scale(range=['ivory', 'red'])),
    tooltip="sum(New deaths)"
)

b= alt.Chart(covid1[covid1["Country"]==city],width=500,height=400).mark_text().encode(
    x="day(Date):O",
    y="month(Date):O",
    text="sum(New deaths)"
)

c= alt.Chart(covid1[covid1["Country"]==city],width=900,height=300).mark_bar().encode(
    x="date(Date):O",
    y="month(Date):O",
    color=alt.Color('sum(New deaths)',scale=alt.Scale(range=['ivory', 'red'])),
    tooltip="sum(New deaths)"
)

d= alt.Chart(covid1[covid1["Country"]==city],width=900,height=300).mark_text(angle=270).encode(
    x="date(Date):O",
    y="month(Date):O",
    text="sum(New deaths)"
)

an= alt.Chart(covid1[covid1["Country"]==city],width=500,height=400).mark_bar().encode(
    x="day(Date):O",
    y="month(Date):O",
    color=alt.Color('sum(New cases)',scale=alt.Scale(range=['azure', 'DodgerBlue'])),
    tooltip="sum(New cases)"
)

bn=alt.Chart(covid1[covid1["Country"]==city],width=500,height=400).mark_text().encode(
    x="day(Date):O",
    y="month(Date):O",
    text="sum(New cases)"
)

cn= alt.Chart(covid1[covid1["Country"]==city],width=900,height=300).mark_bar().encode(
    x="date(Date):O",
    y="month(Date):O",
    color=alt.Color('sum(New cases)',scale=alt.Scale(range=['azure', 'DodgerBlue'])),
    tooltip="sum(New cases)"
)

dn=alt.Chart(covid1[covid1["Country"]==city],width=900,height=300).mark_text(angle=270).encode(
    x="date(Date):O",
    y="month(Date):O",
    text="sum(New cases)"
)

opc = st.radio("Select the option",('New case', 'New deaths'))
op = st.radio("Select the option",('Day and Month','Date and Month'))

if op == 'Day and Month':
    if opc == "New deaths":
        st.altair_chart(a+b)
    else:
        st.altair_chart(an+bn)
elif op == 'Date and Month':
    if opc == "New deaths":
        st.altair_chart(c+d)
    else:
        st.altair_chart(cn+dn)

st.header("View Countries with Highest Cases: ")
opt_selected = st.selectbox("", options=['Top Confirmed Cases', 'Top Death Cases', 'Top Recovered Cases', 'Highest Death Percentage', 'Highest Confirmed Percentage', 'Highest Recovered Percentage'])
country_count = st.slider('No. of countries :',
                          min_value=2, max_value=10,
                          value=5, key='incident_count')

#confirmed
table_data_c = latest.sort_values("Confirmed",ascending=False)[["Country","Confirmed"]].head(country_count)
table_data_c.reset_index(inplace = True,drop = True)

fig1_c = ff.create_table(table_data_c, height_constant=30)
fig2_c = px.bar(table_data_c, y='Confirmed',x='Country',color='Country',height=400)
fig2_c.update_layout(title='Top Confirmed Cases Country',xaxis_title='Country',yaxis_title='Total Confirmed Case',template="plotly_dark")

#death
table_data_d = latest.sort_values("Deaths",ascending=False)[["Country","Deaths"]].head(country_count)
table_data_d.reset_index(inplace = True,drop = True)

fig1_d = ff.create_table(table_data_d, height_constant=30)
fig2_d = px.bar(table_data_d, y='Deaths',x='Country',color='Country',height=400)
fig2_d.update_layout(title='Top Death Cases Country',xaxis_title='Country',yaxis_title='Total Death Case',template="plotly_dark")

#Recovered
table_data_r = latest.sort_values("Recovered",ascending=False)[["Country","Recovered"]].head(country_count)
table_data_r.reset_index(inplace = True,drop = True)

fig1_r = ff.create_table(table_data_r, height_constant=30)
fig2_r = px.bar(table_data_r, y='Recovered',x='Country',color='Country',height=400)
fig2_r.update_layout(title='Top Recovered Cases Country',xaxis_title='Country',yaxis_title='Total Recovered Case',template="plotly_dark")

#confirmedp
conp= latest["Confirmed"] / latest["Population"] * 100
latest_p = latest.copy()
latest_p["Confirmed Percentage"] = conp
con_p = latest_p.sort_values("Confirmed Percentage",ascending=False)[["Country","Confirmed Percentage"]].head(country_count)
con_p.reset_index(inplace = True,drop = True)

fig1_cp = ff.create_table(con_p, height_constant=30)
fig2_cp = px.bar(con_p, y='Confirmed Percentage',x='Country',color='Country',height=400)
fig2_cp.update_layout(title='Top Confirmed Percentage Country',xaxis_title='Country',yaxis_title='Total Confirmed Percentage',template="plotly_dark")

#death per
deathp= latest["Deaths"] / latest["Confirmed"] * 100
latest_p = latest.copy()
latest_p["Death Percentage"] = deathp
death_p = latest_p.sort_values("Death Percentage",ascending=False)[["Country","Death Percentage"]].head(country_count)
death_p.reset_index(inplace = True,drop = True)

fig1_dp = ff.create_table(death_p, height_constant=30)
fig2_dp = px.bar(death_p, y='Death Percentage',x='Country',color='Country',height=400)
fig2_dp.update_layout(title='Top Death Percentage Country',xaxis_title='Country',yaxis_title='Total Death Percentage',template="plotly_dark")

#recoveredp
recp= latest["Recovered"] / latest["Confirmed"] * 100
latest_p = latest.copy()
latest_p["Recovered Percentage"] = recp
rec_p = latest_p.sort_values("Recovered Percentage",ascending=False)[["Country","Recovered Percentage"]].head(country_count)
rec_p.reset_index(inplace = True,drop = True)

fig1_rp = ff.create_table(rec_p, height_constant=30)
fig2_rp = px.bar(rec_p, y='Recovered Percentage',x='Country',color='Country',height=400)
fig2_rp.update_layout(title='Top Recovered Percentage Country',xaxis_title='Country',yaxis_title='Total Recovered Percentage',template="plotly_dark")

if opt_selected == 'Top Confirmed Cases':
    st.plotly_chart(fig2_c)
    st.plotly_chart(fig1_c)
elif  opt_selected == 'Top Death Cases':
    st.plotly_chart(fig2_d)
    st.plotly_chart(fig1_d)
elif  opt_selected == 'Top Recovered Cases':
    st.plotly_chart(fig2_r)
    st.plotly_chart(fig1_r)
elif  opt_selected == 'Highest Confirmed Percentage':
    st.plotly_chart(fig2_cp)
    st.plotly_chart(fig1_cp)
elif  opt_selected == 'Highest Death Percentage':
    st.plotly_chart(fig2_dp)
    st.plotly_chart(fig1_dp)
else:
    st.plotly_chart(fig2_rp)
    st.plotly_chart(fig1_rp)

breakline()
st.header("View Countries with Least Cases: ")
type_of_case = st.selectbox('Select type of case : ',
                            ['Confirmed', 'Active', 'Deaths', 'Recovered'],
                            key = 'least_cases')
selected_count = st.slider('No. of countries :',
                           min_value=1, max_value=10,
                           value=5, key = 'least_cases')
sorted_country_df = latest[latest[type_of_case] > 0].sort_values(type_of_case, ascending= True)
def bubble_chart(n):
    fig = px.scatter(sorted_country_df.head(n), x="Country", y=type_of_case, size=type_of_case, color="Country",
               hover_name="Country", size_max=60)
    fig.update_layout(
    title=str(n) +" Countries with least " + type_of_case.lower() + " cases",
    xaxis_title="Countries",
    yaxis_title= type_of_case + " Cases",
    width = 800
    )
    st.plotly_chart(fig);
bubble_chart(selected_count)

st.header("View Covid-19 details by Date")
cty = st.selectbox(" Select Country",covid1["Country"][:191], key="cities")
ddd = st.date_input(
     "Select the Date",value = datetime.date(2020, 2, 1),min_value = datetime.date(2020, 2, 1), max_value= datetime.date(2021, 3, 13))
st.write('The selected date is:', ddd)

city_v = covid1[(covid1['Date'] == pd.Timestamp(ddd)) & (covid1['Country'] == cty)][["Country","Date","Confirmed", "Deaths", "Recovered", "Active"]].reset_index(drop=True)
st.dataframe(city_v)

st.markdown("
Countries with zero cases
",
            unsafe_allow_html=True)
case_type = st.selectbox("Select case type : ",
                         ['Confirmed', 'Active', 'Deaths'], 1,
                         key= 'zero_cases')
temp_df = latest[latest[case_type] == 0]
st.write(' Countries with zero ' + case_type.lower() + ' cases :')
if len(temp_df) == 0:
    st.error('There are no records present where ' + case_type.lower() + ' cases are zero!')
else:
    temp_df = temp_df[['Country', 'Confirmed', 'Deaths', 'Recovered', 'Active']].reset_index(drop=True)
    st.write(temp_df)

breakline()

st.title("Prediction for Confirmed cases")
covid3 =covid1.groupby(["Date"]).agg({"Confirmed":'sum',"Recovered":'sum',"Deaths":'sum',"New cases":"sum"})

covid3["Days Since"]=covid3.index-covid3.index[0]
covid3["Days Since"]=covid3["Days Since"].dt.days

st.header('Linear Regression')

train_ml=covid3.iloc[:int(covid3.shape[0]*0.90)]
valid_ml=covid3.iloc[int(covid3.shape[0]*0.90):]
model_scores=[]
r2_scores=[]

lin_reg=LinearRegression(normalize=True)
lin_reg.fit(np.array(train_ml["Days Since"]).reshape(-1,1),np.array(train_ml["Confirmed"]).reshape(-1,1))
accuracy = lin_reg.score(np.array(train_ml["Days Since"]).reshape(-1,1),np.array(train_ml["Confirmed"]).reshape(-1,1))

prediction_valid_linreg=lin_reg.predict(np.array(valid_ml["Days Since"]).reshape(-1,1))

model_scores.append(np.sqrt(mean_squared_error(valid_ml["Confirmed"],prediction_valid_linreg)))

prediction_linreg=lin_reg.predict(np.array(covid3["Days Since"]).reshape(-1,1))
linreg_output=[]
for i in range(prediction_linreg.shape[0]):
    linreg_output.append(prediction_linreg[i][0])

figp=go.Figure()
figp.add_trace(go.Scatter(x=covid3.index, y=covid3["Confirmed"],
                    mode='lines+markers',name="Train Data for Confirmed Cases"))
figp.add_trace(go.Scatter(x=covid3.index, y=linreg_output,
                    mode='lines',name="Linear Regression Best Fit Line",
                    line=dict(color='black', dash='dot')))
figp.update_layout(title="Confirmed Cases Linear Regression Prediction",
                 xaxis_title="Date",yaxis_title="Confirmed Cases",legend=dict(x=0,y=1,traceorder="normal"))
st.plotly_chart(figp)

st.write("Root Mean Square Error for Linear Regression: ",np.sqrt(mean_squared_error(valid_ml["Confirmed"],prediction_valid_linreg)))
st.write(f'Training Accuracy: {round(accuracy*100,3)} %')

st.header('Polynomial Regression')
train_ml=covid3.iloc[:int(covid3.shape[0]*0.90)]
valid_ml=covid3.iloc[int(covid3.shape[0]*0.90):]

degree_num = st.slider('No. of Degree :',
                          min_value=1, max_value=6,
                          value=5, key='degree')

poly = PolynomialFeatures(degree = degree_num)

train_poly=poly.fit_transform(np.array(train_ml["Days Since"]).reshape(-1,1))
valid_poly=poly.fit_transform(np.array(valid_ml["Days Since"]).reshape(-1,1))
y=train_ml["Confirmed"]

linreg=LinearRegression(normalize=True)
linreg.fit(train_poly,y)
accuracy_poly = linreg.score(train_poly,y)

prediction_poly=linreg.predict(valid_poly)
rmse_poly=np.sqrt(mean_squared_error(valid_ml["Confirmed"],prediction_poly))
model_scores.append(rmse_poly)

comp_data=poly.fit_transform(np.array(covid3["Days Since"]).reshape(-1,1))

predictions_poly=linreg.predict(comp_data)

figpp=go.Figure()
figpp.add_trace(go.Scatter(x=covid3.index, y=covid3["Confirmed"],
                    mode='lines+markers',name="Train Data for Confirmed Cases"))
figpp.add_trace(go.Scatter(x=covid3.index, y=predictions_poly,
                    mode='lines',name="Polynomial Regression Best Fit",
                    line=dict(color='black', dash='dot')))
figpp.update_layout(title="Confirmed Cases Polynomial Regression Prediction",
                 xaxis_title="Date",yaxis_title="Confirmed Cases",
                 legend=dict(x=0,y=1,traceorder="normal"))

st.plotly_chart(figpp)
st.write("Root Mean Squared Error for Polynomial Regression: ",rmse_poly)
st.write(f' Training Accuracy: {round(accuracy_poly*100,3)} %')

st.header('SVM Model')
c_num = st.slider('Penalty Parameter, C :',
                          min_value=1, max_value=10,
                          value=5, key='C')

degrees_num = st.slider('No. of degree :',
                          min_value=1, max_value=10,
                          value=5, key='degreesvm')
#Intializing SVR Model
svm=SVR(C=c_num,degree=degrees_num,kernel='poly',epsilon=0.01)

#Fitting model on the training data
svm.fit(np.array(train_ml["Days Since"]).reshape(-1,1),np.array(train_ml["Confirmed"]).reshape(-1,1))
accuracy_svm = svm.score(np.array(train_ml["Days Since"]).reshape(-1,1),np.array(train_ml["Confirmed"]).reshape(-1,1))

prediction_valid_svm=svm.predict(np.array(valid_ml["Days Since"]).reshape(-1,1))

model_scores.append(np.sqrt(mean_squared_error(valid_ml["Confirmed"],prediction_valid_svm)))

prediction_svm=svm.predict(np.array(covid3["Days Since"]).reshape(-1,1))
figs=go.Figure()
figs.add_trace(go.Scatter(x=covid3.index, y=covid3["Confirmed"],
                    mode='lines+markers',name="Train Data for Confirmed Cases"))
figs.add_trace(go.Scatter(x=covid3.index, y=prediction_svm,
                    mode='lines',name="Support Vector Machine Best fit Kernel",
                    line=dict(color='black', dash='dot')))
figs.update_layout(title="Confirmed Cases Support Vectore Machine Regressor Prediction",
                 xaxis_title="Date",yaxis_title="Confirmed Cases",legend=dict(x=0,y=1,traceorder="normal"))

st.plotly_chart(figs)
st.write("Root Mean Square Error for Support Vectore Machine: ",np.sqrt(mean_squared_error(valid_ml["Confirmed"],prediction_valid_svm)))
st.write(f'Training Accuracy: {round(accuracy_svm*100,3)} %')

breakline()

new_date=[]
new_prediction_lr=[]
new_prediction_poly=[]
for i in range(1,18):
    new_date_poly=poly.fit_transform(np.array(covid3["Days Since"].max()+i).reshape(-1,1))
    new_prediction_poly.append(linreg.predict(new_date_poly)[0])
new_prediction_svm=[]
for i in range(1,18):
    new_date.append(covid3.index[-1]+timedelta(days=i))
    new_prediction_lr.append(lin_reg.predict(np.array(covid3["Days Since"].max()+i).reshape(-1,1))[0][0])
    new_prediction_svm.append(svm.predict(np.array(covid3["Days Since"].max()+i).reshape(-1,1))[0])

pd.set_option('display.float_format', lambda x: '%.6f' % x)
model_predictions=pd.DataFrame(zip(new_date,new_prediction_lr,new_prediction_poly,new_prediction_svm),
                               columns=["Dates","Linear Regression Prediction","Polynonmial Regression Prediction","SVM Prediction"])

breakline()

st.header('Prediction for future cases')
model_predictions.head()
st.dataframe(model_predictions)


import time
import sys
from binarytree import Node

def rod_cut(nodo, total, arreglo, n, cont, mayor):
	"""Función para calcular el máximo ganancias (en dinero)
	dependiendo del tamaño de la varilla y si se corta o no """

	if n == len(arreglo):
		# Cuando lleva al último nivel, guardamos los cortes de
        # las varillas con su precio máximo en el nodo hoja
		total += arreglo[cont - 1]
		nodo.value = total
		if mayor[0] < total:
			# Guardamos en la lista el número de la ganancia máxima
			mayor[0] = total
	else:
		# Si no es el último nivel, creamos los dos nodos izq y derecha,
        # y vamos expandiendo el árbol por izq y der
		nodo.left = Node(0)
		nodo.right = Node(0)
		n += 1  # Contador para los niveles del árbol (k = 1, k = 2, etc)
		rot_cut_izq(nodo.left, total, arreglo, n, cont, mayor)
		rot_cut_der(nodo.right, total, arreglo, n, cont, mayor)

def rot_cut_izq(nodo, total, arreglo, n, cont, mayor):
    """Función para ir expandiendo el árbol por la izquierda"""

    cont += 1  #Guarda el tamaño de la varilla sin cortar
    rod_cut(nodo, total, arreglo, n, cont, mayor)

def rot_cut_der(nodo, total, arreglo, n, cont, mayor):
    """Función para ir expandiendo el árbol por la derecha"""

    total += arreglo[cont - 1]  # Cada vez que se corta, vamos sumando el precio máximo de la longitud de la varilla
    cont = 1  # Se reinicia el contador cuando se corta la varilla
    rod_cut(nodo, total, arreglo, n, cont, mayor)

root = Node(0)  # Creamos el nodo raiz
root.left = None
root.right = None
arreglo = [1, 5, 8, 9, 10, 13]
n = 1
cont = 1
total = 0
mayor = [-sys.maxsize - 1]  # Menor valor de un entero en python

inicio = time.time()
rod_cut(root, total, arreglo, n, cont, mayor)
fin = time.time()

print(root)  #Imprime el árbol en forma gráfica

print("Mayor", mayor[0])
print("Tiempo en segundos - Backtracking: ", fin - inicio)


#Minimum Loss.
def minimumLoss(price):
    minimumLossObtained = None
    for i in range(0,len(price)):
        for j in range(i+1,len(price)):
            if price[i] > price[j]:
                if minimumLossObtained == None or minimumLossObtained > (price[i] - price[j]):
                    minimumLossObtained = price[i] - price[j]
    return minimumLossObtained
if __name__ == '__main__':
    n = int(input())
    price = list(map(int, input().split()))
    result = minimumLoss(price)
    print(result)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# File : find_alpha.py
# Description : Find best value for alpha.
# Auteur : Nils Schaetti <nils.schaetti@unine.ch>
# Date : 01.02.2017 17:59:05
# Lieu : Neuchâtel, Suisse
#
# This file is part of the PAN18 author profiling challenge code.
# The PAN18 author profiling challenge code is a set of free software:
# you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Foobar is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
#

# Imports
import os
import torch
import dataset
import numpy as np
from torch.autograd import Variable
from tools import settings, functions

################################################
# MAIN
################################################

# Argument parser
args = functions.argument_parser_execution()

# Image augmentation and normalization
image_transform = functions.image_transformer('val')

# For each alpha value
for alpha in np.arange(0.9, 1.1, 0.1):
    print(u"Alpha {}".format(alpha))
    # Counters
    total_images_success = 0.0
    total_tweets_success = 0.0
    total_both_success = 0.0
    total = 0.0
    total_diff = 0.0

    # For each language
    for lang in ['en', 'es', 'ar']:
        # Load models and voc
        image_model, tweet_model, tweet_voc = functions.load_models(
            model_type=args.image_model,
            n_gram=args.n_gram,
            lang=lang,
            cuda=args.cuda
        )

        # Counters
        images_success = 0.0
        tweets_success = 0.0
        both_success = 0.0
        count = 0
        diff = 0

        # Make to output directory
        output_dir = os.path.join(args.output_dir, lang)
        if not os.path.exists(output_dir):
            os.mkdir(output_dir)
        # end

        # Transformer
        text_transform = functions.tweet_transformer(lang, args.n_gram, voc=tweet_voc)

        # Author profiling data set
        profiling_dataset = dataset.AuthorProfilingDataset(root=args.input_dataset, download=False, lang=lang,
                                                           text_transform=text_transform, image_transform=image_transform,
                                                           train=False, filter_robot=True)
        pan18loader = torch.utils.data.DataLoader(profiling_dataset, batch_size=1, shuffle=True)

        # For the data set
        for data in pan18loader:
            # Images, tweets and labels
            tweets, images, labels = data

            # Variable and CUDA
            images, tweets, labels = Variable(images), Variable(tweets), Variable(labels)
            if args.cuda:
                images, tweets, labels = images.cuda(), tweets.cuda(), labels.cuda()
            # end if

            # Tweets batch size
            tweets_batch_size = tweets.size(1)

            # Remove images and tweet dimension
            tweets = tweets.view(-1, settings.min_length)
            images = images.view(-1, 3, settings.image_size, settings.image_size)

            # Compute prob. for tweets and images
            images_probs = image_model(images)
            tweets_probs = tweet_model(tweets)

            # Resize to images and tweet dimension and transpose
            tweets_probs = tweets_probs.view(-1, tweets_batch_size, 2)
            images_probs = images_probs.view(-1, 10, 2)

            # Tweet and image prob
            tweets_prob = torch.mean(tweets_probs, 1)
            image_prob = torch.mean(images_probs, 1)

            # Take the max as predicted
            _, images_prediction = torch.max(torch.mean(images_probs, 1), 1)
            _, tweets_prediction = torch.max(torch.mean(tweets_probs, 1), 1)

            # Both prediction
            _, both_prediction = torch.max(
                (torch.mean(images_probs, 1) * alpha + torch.mean(tweets_probs, 1) * (1.0 - alpha)) / 2.0,
                1
            )

            # Both prob
            both_prob = (torch.mean(images_probs, 1) * alpha + torch.mean(tweets_probs, 1) * (1.0 - alpha)) / 2.0

            # labels
            if int(labels) == 0:
                prob_diff = float(both_prob[0, 0] - both_prob[0, 1])
            else:
                prob_diff = float(both_prob[0, 1] - both_prob[0, 0])
            # end if

            # Add to correctly classified profiles
            images_success += int((images_prediction == labels).sum())
            tweets_success += int((tweets_prediction == labels).sum())
            both_success += int((both_prediction == labels).sum())
            diff += prob_diff

            # Add to total
            count += labels.size(0)
        # end for

        # Total success
        total_images_success += images_success
        total_tweets_success += tweets_success
        total_both_success += both_success
        total_diff += diff
        total += count

        # Accuracies
        images_accuracy = images_success / count * 100.0
        tweets_accuracy = tweets_success / count * 100.0
        diff_accuracy = diff / count
        both_accuracy = both_success / count * 100.0

        # Print language accuracy
        print(u"\tLang {}, Images accuracy {}, Tweets accuracy {}, Both accuracy {}, Diff {}".format(
            lang,
            images_accuracy,
            tweets_accuracy,
            both_accuracy,
            diff_accuracy)
        )
    # end for

    # Accuracies
    total_images_accuracy = total_images_success / total * 100.0
    total_tweets_accuracy = total_tweets_success / total * 100.0
    total_diff_accuracy = total_diff / total
    total_both_accuracy = total_both_success / total * 100.0

    # Print total accuracy
    print(u"Alpha {}, Images accuracy {}, Tweets accuracy {}, Both accuracy {}, Diff {}".format(
        alpha,
        total_images_accuracy,
        total_tweets_accuracy,
        total_both_accuracy,
        total_diff_accuracy)
    )
# end for


import tensorflow as tf
import numpy as np

from .aggregators import *
from .layers import Dense

class DGRec(object):

    def __init__(self, args, support_sizes, placeholders):
        self.support_sizes = support_sizes
        if args.aggregator_type == "mean":
            self.aggregator_cls = MeanAggregator
        elif args.aggregator_type == "seq":
            self.aggregator_cls = SeqAggregator
        elif args.aggregator_type == "maxpool":
            self.aggregator_cls = MaxPoolingAggregator
        elif args.aggregator_type == "meanpool":
            self.aggregator_cls = MeanPoolingAggregator
        elif args.aggregator_type == "gcn":
            self.aggregator_cls = GCNAggregator
        elif args.aggregator_type == "attn":
            self.aggregator_cls = AttentionAggregator
        else:
            raise Exception("Unknown aggregator: ", self.aggregator_cls)
        self.input_x = placeholders['input_x']
        self.input_y = placeholders['input_y']
        self.mask_y = placeholders['mask_y']
        self.mask = tf.cast(self.mask_y, dtype=tf.float32)
        self.point_count = tf.reduce_sum(self.mask)
        self.support_nodes_layer1 = placeholders['support_nodes_layer1']
        self.support_nodes_layer2 = placeholders['support_nodes_layer2']
        self.support_sessions_layer1 = placeholders['support_sessions_layer1']
        self.support_sessions_layer2 = placeholders['support_sessions_layer2']
        self.support_lengths_layer1 = placeholders['support_lengths_layer1']
        self.support_lengths_layer2 = placeholders['support_lengths_layer2']

        self.training = args.training
        self.concat = args.concat
        if args.act == 'linear':
            self.act = lambda x:x
        elif args.act == 'relu':
            self.act = tf.nn.relu
        elif args.act == 'elu':
            self.act = tf.nn.elu
        else:
            raise NotImplementedError
        self.batch_size = args.batch_size
        self.hidden_size = args.hidden_size
        self.samples_1 = args.samples_1
        self.samples_2 = args.samples_2
        self.num_samples = [self.samples_1, self.samples_2]
        self.n_items = args.num_items
        self.n_users = args.num_users
        self.emb_item = args.embedding_size
        self.emb_user = args.emb_user
        self.max_length = args.max_length
        self.model_size = args.model_size
        self.dropout = args.dropout
        self.dim1 = args.dim1
        self.dim2 = args.dim2
        self.weight_decay = args.weight_decay
        self.global_only = args.global_only
        self.local_only = args.local_only

        self.dims = [self.hidden_size, args.dim1, args.dim2]
        self.dense_layers = []
        self.loss = 0
        self.global_step = tf.Variable(0, name='global_step', trainable=False)
        self.lr = tf.maximum(1e-5, tf.train.exponential_decay(args.learning_rate,
                                                            self.global_step,
                                                            args.decay_steps,
                                                            args.decay_rate,
                                                            staircase=True))
        self.optimizer = tf.train.AdamOptimizer(learning_rate=self.lr)
        self.build()

    def global_features(self):
        self.user_embedding = tf.get_variable('user_embedding', [self.n_users, self.emb_user],\
                                        initializer=tf.glorot_uniform_initializer())
        feature_layer1 = tf.nn.embedding_lookup(self.user_embedding, self.support_nodes_layer1)
        feature_layer2 = tf.nn.embedding_lookup(self.user_embedding, self.support_nodes_layer2)
        dense_layer = Dense(self.emb_user,
                            self.hidden_size if self.global_only else self.hidden_size // 2,
                            act=tf.nn.relu,
                            dropout=self.dropout if self.training else 0.)
        self.dense_layers.append(dense_layer)
        feature_layer1 = dense_layer(feature_layer1)
        feature_layer2 = dense_layer(feature_layer2)
        return [feature_layer2, feature_layer1]

    def local_features(self):
        '''
        Use the same rnn in decode function
        '''
        initial_state_layer1 = self.lstm_cell.zero_state(self.batch_size*self.samples_1*self.samples_2, dtype=tf.float32)
        initial_state_layer2 = self.lstm_cell.zero_state(self.batch_size*self.samples_2, dtype=tf.float32)
        inputs_1 = tf.nn.embedding_lookup(self.embedding, self.support_sessions_layer1)
        inputs_2 = tf.nn.embedding_lookup(self.embedding, self.support_sessions_layer2)
        outputs1, states1 = tf.nn.dynamic_rnn(cell=self.lstm_cell,
                                            inputs=inputs_1,
                                            sequence_length=self.support_lengths_layer1,
                                            initial_state=initial_state_layer1,
                                            dtype=tf.float32)
        outputs2, states2 = tf.nn.dynamic_rnn(cell=self.lstm_cell,
                                            inputs=inputs_2,
                                            sequence_length=self.support_lengths_layer2,
                                            initial_state=initial_state_layer2,
                                            dtype=tf.float32)
        # outputs: shape[batch_size, max_time, depth]
        local_layer1 = states1.h
        local_layer2 = states2.h
        dense_layer = Dense(self.hidden_size,
                            self.hidden_size if self.local_only else self.hidden_size // 2,
                            act=tf.nn.relu,
                            dropout=self.dropout if self.training else 0.)
        self.dense_layers.append(dense_layer)
        local_layer1 = dense_layer(local_layer1)
        local_layer2 = dense_layer(local_layer2)
        return [local_layer2, local_layer1]

    def global_and_local_features(self):
        #global features
        global_feature_layer2, global_feature_layer1 = self.global_features()
        local_feature_layer2, local_feature_layer1 = self.local_features()
        global_local_layer2 = tf.concat([global_feature_layer2, local_feature_layer2], -1)
        global_local_layer1 = tf.concat([global_feature_layer1, local_feature_layer1], -1)
        return [global_local_layer2, global_local_layer1]

    def aggregate(self, hidden, dims, num_samples, support_sizes,
            aggregators=None, name=None, concat=False, model_size="small"):
        """ At each layer, aggregate hidden representations of neighbors to compute the hidden representations
            at next layer.
        Args:
            samples: a list of samples of variable hops away for convolving at each layer of the
                network. Length is the number of layers + 1. Each is a vector of node indices.
            input_features: the input features for each sample of various hops away.
            dims: a list of dimensions of the hidden representations from the input layer to the
                final layer. Length is the number of layers + 1.
            num_samples: list of number of samples for each layer.
            support_sizes: the number of nodes to gather information from for each layer.
            batch_size: the number of inputs (different for batch inputs and negative samples).
        Returns:
            The hidden representation at the final layer for all nodes in batch
        """

        # length: number of layers + 1
        hidden = hidden
        new_agg = aggregators is None
        if new_agg:
            aggregators = []
        for layer in range(len(num_samples)):
            if new_agg:
                dim_mult = 2 if concat and (layer != 0) else 1
                # aggregator at current layer
                if layer == len(num_samples) - 1:
                    aggregator = self.aggregator_cls(dim_mult*dims[layer], dims[layer+1], act=lambda x : x,
                            dropout=self.dropout if self.training else 0.,
                            name=name, concat=concat, model_size=model_size)
                else:
                    aggregator = self.aggregator_cls(dim_mult*dims[layer], dims[layer+1], act=self.act,
                            dropout=self.dropout if self.training else 0.,
                            name=name, concat=concat, model_size=model_size)
                aggregators.append(aggregator)
            else:
                aggregator = aggregators[layer]
            # hidden representation at current layer for all support nodes that are various hops away
            next_hidden = []
            # as layer increases, the number of support nodes needed decreases
            for hop in range(len(num_samples) - layer):
                dim_mult = 2 if concat and (layer != 0) else 1
                neigh_dims = [self.batch_size * support_sizes[hop],
                              num_samples[len(num_samples) - hop - 1],
                              dim_mult*dims[layer]]
                h = aggregator((hidden[hop],
                                tf.reshape(hidden[hop + 1], neigh_dims)))
                next_hidden.append(h)
            hidden = next_hidden
        return hidden[0], aggregators

    def decode(self):
        self.lstm_cell = lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(self.hidden_size)
        initial_state = lstm_cell.zero_state(self.batch_size, dtype=tf.float32)
        time_major_x = tf.transpose(self.input_x)
        inputs = tf.nn.embedding_lookup(self.embedding, time_major_x)
        outputs, state = tf.nn.dynamic_rnn(cell=lstm_cell,
                                            inputs=inputs,
                                            initial_state=initial_state,
                                            time_major=True,
                                            dtype=tf.float32,
                                            scope='decode_rnn')
        # outputs: shape[max_time, batch_size, depth]
        slices = tf.split(outputs, num_or_size_splits=self.max_length, axis=0)
        return [tf.squeeze(t,[0]) for t in slices]

    def step_by_step(self, features_0, features_1_2, dims, num_samples, support_sizes,
            aggregators=None, name=None, concat=False, model_size="small"):
        self.aggregators = None
        outputs = []
        for feature0 in features_0:
            hidden = [feature0, features_1_2[0], features_1_2[1]]
            output1, self.aggregators = self.aggregate(hidden, dims, num_samples, support_sizes,
                                        aggregators=self.aggregators, concat=concat, model_size=self.model_size)
            outputs.append(output1)
        return tf.stack(outputs, axis=0)

    def build(self):
        self.embedding = embedding = tf.get_variable('item_embedding', [self.n_items, self.emb_item],\
                                        initializer=tf.glorot_uniform_initializer())
        features_0 = self.decode() # features of zero layer nodes.
        #outputs with shape [max_time, batch_size, dim2]
        if self.global_only:
            features_1_2 = self.global_features()
        elif self.local_only:
            features_1_2 = self.local_features()
        else:
            features_1_2 = self.global_and_local_features()
        outputs = self.step_by_step(features_0, features_1_2, self.dims, self.num_samples, self.support_sizes,
                                concat=self.concat)
        concat_self = tf.concat([features_0, outputs], axis=-1)

        # exchange first two dimensions.
        self.transposed_outputs = tf.transpose(concat_self, [1,0,2])

        self.loss = self._loss()
        self.sum_recall = self._recall()
        self.sum_ndcg = self._ndcg()
        grads_and_vars = self.optimizer.compute_gradients(self.loss)
        clipped_grads_and_vars = [(tf.clip_by_value(grad, -5.0, 5.0) if grad is not None else None, var)
                        for grad, var in grads_and_vars]
        self.opt_op = self.optimizer.apply_gradients(clipped_grads_and_vars, global_step=self.global_step)

    def _loss(self):
        reg_loss = 0.
        xe_loss = 0.
        fc_layer = Dense(self.dim2 + self.hidden_size, self.emb_item, act=lambda x:x, dropout=self.dropout if self.training else 0.)
        self.dense_layers.append(fc_layer)
        self.logits = logits = tf.matmul(fc_layer(tf.reshape(self.transposed_outputs, [-1, self.dim2+self.hidden_size])), self.embedding, transpose_b=True)
        for dense_layer in self.dense_layers:
            for var in dense_layer.vars.values():
                reg_loss += self.weight_decay * tf.nn.l2_loss(var)
        for aggregator in self.aggregators:
            for var in aggregator.vars.values():
                reg_loss += self.weight_decay * tf.nn.l2_loss(var)
        reshaped_logits = tf.reshape(logits, [self.batch_size, self.max_length, self.n_items])
        xe_loss += tf.nn.sparse_softmax_cross_entropy_with_logits(labels=self.input_y,
                                                            logits=reshaped_logits,
                                                            name='softmax_loss')
        xe_loss *= self.mask
        return tf.reduce_sum(xe_loss) / self.point_count + reg_loss

    def _ndcg(self):
        predictions = tf.transpose(self.logits)
        targets = tf.reshape(self.input_y, [-1])
        pred_values = tf.expand_dims(tf.diag_part(tf.nn.embedding_lookup(predictions, targets)), -1)
        tile_pred_values = tf.tile(pred_values, [1, self.n_items-1])
        ranks = tf.reduce_sum(tf.cast(self.logits[:,1:] > tile_pred_values, dtype=tf.float32), -1) + 1
        ndcg = 1. / (log2(1.0 + ranks))
        mask = tf.reshape(self.mask, [-1])
        ndcg *= mask
        return tf.reduce_sum(ndcg)

    def _recall(self):
        predictions = self.logits
        targets = tf.reshape(self.input_y, [-1])
        recall_at_k = tf.nn.in_top_k(predictions, targets, k=20)
        recall_at_k = tf.cast(recall_at_k, dtype=tf.float32)
        mask = tf.reshape(self.mask, [-1])
        recall_at_k *= mask
        return tf.reduce_sum(recall_at_k)

def log2(x):
    numerator = tf.log(x)
    denominator = tf.log(tf.constant(2, dtype=numerator.dtype))
    return numerator / denominator


#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

import datetime as dt
import json
import os

import jsonschema

from rally import api
from rally import consts
from rally import exceptions
from rally.task.processing import charts

OLD_TASK_RESULT_SCHEMA = {
    "type": "object",
    "$schema": consts.JSON_SCHEMA,
    "properties": {
        "key": {
            "type": "object",
            "properties": {
                "kw": {
                    "type": "object"
                },
                "name": {
                    "type": "string"
                },
                "pos": {
                    "type": "integer"
                },
            },
            "required": ["kw", "name", "pos"]
        },
        "sla": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "criterion": {
                        "type": "string"
                    },
                    "detail": {
                        "type": "string"
                    },
                    "success": {
                        "type": "boolean"
                    }
                }
            }
        },
        "hooks": {"type": "array"},
        "result": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "atomic_actions": {
                        "type": "object"
                    },
                    "duration": {
                        "type": "number"
                    },
                    "error": {
                        "type": "array"
                    },
                    "idle_duration": {
                        "type": "number"
                    },
                    "output": {"type": "object"}
                },
                "required": ["atomic_actions", "duration", "error",
                             "idle_duration"]
            },
            "minItems": 0
        },
        "load_duration": {
            "type": "number",
        },
        "full_duration": {
            "type": "number",
        },
        "created_at": {
            "type": "string"
        }
    },
    "required": ["key", "sla", "result", "load_duration", "full_duration"],
    "additionalProperties": False
}

class FailedToLoadResults(exceptions.RallyException):
    error_code = 225
    msg_fmt = "ERROR: Invalid task result format in %(source)s\n\n\t%(msg)s"

def _update_atomic_actions(atomic_actions, started_at):
    """Convert atomic actions in old format to latest one."""
    new = []
    for name, duration in atomic_actions.items():
        finished_at = started_at + duration
        new.append({
            "name": name,
            "started_at": started_at,
            "finished_at": finished_at,
            "children": []}
        )
        started_at = finished_at
    return new

def _update_old_results(tasks_results, path):
    """Converts tasks results in old format to latest one."""
    task = {"version": 2,
            "title": "Task loaded from a file.",
            "description": "Auto-ported from task format V1.",
            "uuid": "n/a",
            "env_name": "n/a",
            "env_uuid": "n/a",
            "tags": [],
            "status": consts.TaskStatus.FINISHED,
            "subtasks": []}

    start_time = None

    for result in tasks_results:
        try:
            jsonschema.validate(
                result, OLD_TASK_RESULT_SCHEMA)
        except jsonschema.ValidationError as e:
            raise FailedToLoadResults(source=path,
                                      msg=str(e))

        iter_count = 0
        failed_iter_count = 0
        min_duration = None
        max_duration = None

        for itr in result["result"]:
            if start_time is None or itr["timestamp"] < start_time:
                start_time = itr["timestamp"]
            # NOTE(chenhb): back compatible for atomic_actions
            itr["atomic_actions"] = _update_atomic_actions(
                itr["atomic_actions"], started_at=itr["timestamp"])

            iter_count += 1
            if itr.get("error"):
                failed_iter_count += 1

            duration = itr.get("duration", 0)

            if max_duration is None or duration > max_duration:
                max_duration = duration

            if min_duration is None or min_duration > duration:
                min_duration = duration

        durations_stat = charts.MainStatsTable(
            {"total_iteration_count": iter_count})

        for itr in result["result"]:
            durations_stat.add_iteration(itr)

        created_at = dt.datetime.strptime(result["created_at"],
                                          "%Y-%d-%mT%H:%M:%S")
        updated_at = created_at + dt.timedelta(
            seconds=result["full_duration"])
        created_at = created_at.strftime(consts.TimeFormat.ISO8601)
        updated_at = updated_at.strftime(consts.TimeFormat.ISO8601)
        pass_sla = all(s.get("success") for s in result["sla"])
        runner_type = result["key"]["kw"]["runner"].pop("type")
        for h in result["hooks"]:
            trigger = h["config"]["trigger"]
            h["config"] = {
                "description": h["config"].get("description"),
                "action": (h["config"]["name"], h["config"]["args"]),
                "trigger": (trigger["name"], trigger["args"])}
        workload = {"uuid": "n/a",
                    "name": result["key"]["name"],
                    "position": result["key"]["pos"],
                    "description": result["key"].get("description",
                                                     ""),
                    "full_duration": result["full_duration"],
                    "load_duration": result["load_duration"],
                    "total_iteration_count": iter_count,
                    "failed_iteration_count": failed_iter_count,
                    "min_duration": min_duration,
                    "max_duration": max_duration,
                    "start_time": start_time,
                    "created_at": created_at,
                    "updated_at": updated_at,
                    "args": result["key"]["kw"]["args"],
                    "runner_type": runner_type,
                    "runner": result["key"]["kw"]["runner"],
                    "hooks": result["hooks"],
                    "sla": result["key"]["kw"]["sla"],
                    "sla_results": {"sla": result["sla"]},
                    "pass_sla": pass_sla,
                    "contexts": result["key"]["kw"]["context"],
                    "contexts_results": [],
                    "data": sorted(result["result"],
                                   key=lambda x: x["timestamp"]),
                    "statistics": {
                        "durations": durations_stat.to_dict()},
                    }
        task["subtasks"].append(
            {"title": "A SubTask",
             "description": "",
             "workloads": [workload]})
    return [task]

def _update_new_results(tasks_results):
    for task_result in tasks_results["tasks"]:
        try:
            jsonschema.validate(task_result, api._Task.TASK_SCHEMA)
        except jsonschema.ValidationError as e:
            raise exceptions.RallyException(
                "ERROR: Invalid task result format\n\n\t%s" % str(e)) from None
        task_result.setdefault("env_name", "n/a")
        task_result.setdefault("env_uuid", "n/a")
        for subtask in task_result["subtasks"]:
            for workload in subtask["workloads"]:
                workload.setdefault("contexts_results", [])
                workload["runner_type"], workload["runner"] = list(
                    workload["runner"].items())[0]
                workload["name"], workload["args"] = list(
                    workload.pop("scenario").items())[0]

    return tasks_results["tasks"]

def load(path):
    with open(os.path.expanduser(path)) as f:
        raw_tasks_results = f.read()

    try:
        tasks_results = json.loads(raw_tasks_results)
    except ValueError:
        raise FailedToLoadResults(
            source=path, msg="error while loading JSON.") from None

    if isinstance(tasks_results, list):
        return _update_old_results(tasks_results, path)
    elif isinstance(tasks_results, dict) and "tasks" in tasks_results:
        return _update_new_results(tasks_results)
    else:
        raise FailedToLoadResults(
            source=path, msg="Wrong format")


from functions.page7_func import *

# 人脸检测
def page7():
    st.title("人脸检测")
    image_file = st.sidebar.file_uploader("上传一张含有人脸的图片", type=['jpg', 'png', 'jpeg'], key='page7_file_upload')
    if image_file is not None:
        original_image = Image.open(image_file)
        st.text("原始图像")
        st.image(original_image)
        enhance_type = st.sidebar.radio("增强类型",
                                        ["原始图像", "灰度", "对比度", "亮度", "模糊度"])

        if enhance_type == '灰度':
            rgb_array_img = np.array(original_image.convert('RGB'))
            img = cv2.cvtColor(rgb_array_img, 1)
            gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            st.text("处理灰度后:")
            st.image(gray_img)

        elif enhance_type == '对比度':
            c_rate = st.sidebar.slider("Contrast", 0.5, 3.5)
            enhancer = ImageEnhance.Contrast(original_image)
            contrast_img = enhancer.enhance(c_rate)
            st.text("处理对比度后:")
            st.image(contrast_img)

        elif enhance_type == '亮度':
            c_rate = st.sidebar.slider("Brightness", 0.5, 3.5)
            enhancer = ImageEnhance.Brightness(original_image)
            brightness_img = enhancer.enhance(c_rate)
            st.text("处理亮度后:")
            st.image(brightness_img)

        elif enhance_type == '模糊度':
            rgb_array_img = np.array(original_image.convert('RGB'))
            blur_rate = st.sidebar.slider("Brightness", 0.5, 3.5)
            img = cv2.cvtColor(rgb_array_img, 1)
            blur_img = cv2.GaussianBlur(img, (11, 11), blur_rate)
            st.text("处理模糊度后:")
            st.image(blur_img)

        # Face Detection
        feature = ["人脸", "笑容", "眼睛", "黑白简笔化", "卡通化"]
        feature_choice = st.sidebar.selectbox("功能选择", feature)
        if st.button("开始检测"):
            if feature_choice == '人脸':
                result_img, result_faces = detect_faces(original_image)
                st.image(result_img)
                st.success("找到 {} 张人脸".format(len(result_faces)))

            elif feature_choice == '笑容':
                result_img = detect_smiles(original_image)
                st.image(result_img)

            elif feature_choice == '眼睛':
                result_img = detect_eyes(original_image)
                st.image(result_img)

            elif feature_choice == '黑白简笔化':
                result_canny = cannize_image(original_image)
                st.image(result_canny)

            elif feature_choice == '卡通化':
                result_img = cartonize_image(original_image)
                st.image(result_img)


import sqlite3

conn = sqlite3.connect("series.sqlite")
c = conn.cursor()

def migrate(req):
    c.execute(req)
    conn.commit()

migrate("""CREATE TABLE series(
    id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
    name TEXT,
    api_id INTEGER,
    season INTEGER,
    episode INTEGER
    )""")


#
# @lc app=leetcode.cn id=47 lang=python3
#
# [47] 全排列 II
#

# @lc code=start
from typing import List, Set

class Solution:
    def search(self) -> List[List[int]]:
        ret: List[List[int]] = []
        isLeast = len(self.indexTaken) + 1 == len(self.nums)
        # to prevent duplication
        valueTaken = set()
        for i, x in enumerate(self.nums):
            if (i in self.indexTaken) or (x in valueTaken):
                continue
            if isLeast:
                return [[x]]
            valueTaken.add(x)
            self.indexTaken.add(i)
            rest = self.search()
            self.indexTaken.remove(i)
            ret.extend(map(lambda list: [x, *list], rest))
        return ret

    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        self.nums = nums
        self.indexTaken: Set[int] = set()
        return self.search()
# @lc code=end


import sqlite3

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

# file name of the userinfo
filename = 'usersinfo.sqlite3'

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

def run():

    '''
    Initialize the sqlfile.
    '''

    conn = sqlite3.connect(filename)
    cur = conn.cursor()
    cur.execute('CREATE TABLE IF NOT EXISTS Favs (id TEXT, fav1lati REAL,'
        ' fav1lon REAL, fav2lati REAL, fav2lon REAL)')
    conn.commit()
    conn.close()

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

def get(user, option=None):

    '''
    Return the user info according to the option.
    '''

    if user is None:
        raise ValueError("user can't be none")
        return None

    conn = sqlite3.connect(filename)
    cur = conn.cursor()

    if option is None:
        cur.execute('SELECT * FROM Favs WHERE id = ?', (user,))
        locations = cur.fetchone()
        conn.close()
        return locations
    else:
        location = [None, None]
        latS = option + 'lati'
        lonS = option + 'lon'
        sqllat = 'SELECT {lat} FROM Favs WHERE id = ?'.format(lat=latS, lon=lonS)
        sqllon = 'SELECT {lon} FROM Favs WHERE id = ?'.format(lat=latS, lon=lonS)

        cur.execute(sqllat, (user,))
        col = cur.fetchone()
        if col is not None:
            location[0] = col[0]

        cur.execute(sqllon, (user,))
        col = cur.fetchone()
        if col is not None:
            location[1] = col[0]

        conn.close
        return location

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

def edit(user, option, lat, lon):

    '''
    Edit the user info to lat, lon in the option columns
    '''

    conn = sqlite3.connect(filename)
    cur = conn.cursor()

    latS = option + 'lati'
    lonS = option + 'lon'

    sqllat = 'SELECT {lat} FROM Favs WHERE id = ?'.format(lat=latS, lon=lonS)
    sqllon = 'SELECT {lon} FROM Favs WHERE id = ?'.format(lat=latS, lon=lonS)
    cur.execute(sqllat, (user,))
    collat = cur.fetchone()
    cur.execute(sqllon, (user,))
    collon = cur.fetchone()

    if collat is None or collon is None:
        cur.execute('INSERT INTO Favs (id, {lat}, {lon}) VALUES ( ?, ?, ?)'.format(lat=latS, lon=lonS), (user, lat, lon))
        conn.commit()
    else:
        cur.execute('UPDATE Favs SET {lat} = ? WHERE id = ?'.format(lat=latS), (lat, user))
        cur.execute('UPDATE Favs SET {lon} = ? WHERE id = ?'.format(lon=lonS), (lon, user))
        conn.commit()

    cur.execute('SELECT * FROM Favs')
    for row in cur :
        print(row)

    conn.close()
    return ["END", None]

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

if __name__ == "__main__":

    '''
    For testing
    '''

    user = input("Enter the user")
    run()
    print(str(get(user)))
    edit(user, 'fav2', 40, 75)
    print(str(get(user)))


# https://school.programmers.co.kr/learn/courses/30/lessons/42578

def solution(clothes):
    answer = 1
    c_dict = {}

    for c_name, c_type in clothes:
        try:
            c_dict[c_type].append(c_name)
        except:
            c_dict[c_type] = [c_name]

    for c in c_dict.values():
        answer *= len(c) + 1

    return answer - 1


n = int(input())
for i in range(n):
    s = input()
    overs = len(s) // 6
    extra_balls = len(s) % 6
    if extra_balls > 0:
        overs += extra_balls / 10

    runs = 0
    wickets = 0
    for c in s:
        if c == 'W':
            wickets += 1
        else:
            runs += int(c)

    print(f"{overs:.1f} {'Overs' if overs > 1 else 'Over'} {runs} {'Runs' if runs > 1 else 'Run'} {wickets} {'Wickets' if wickets > 1 else 'Wicket'}.")


import tkinter as tk
from tkinter import *
import webbrowser

class ParentWindow(Frame):
    def __init__(self, master):
        Frame.__init__(self, master)
        self.master.title("Web Page Generator")
        self.btn = Button(self.master, text="Default HTML Page", width=30, height=2, command=self.defaultHTML)
        self.btn.grid(padx=(10,10) , pady=(10,10))

        #Creates button to select destination of files from destination directory
        self.btn = Button(text="Submit Custom Text",  width=30, height=2, command=self.customtext)
        #Positions destination button in GUI using tkinter grid()
        #on the next row under the source button
        self.btn.grid(row=1, column=0, padx=(20, 10), pady=(15, 10))

        #Creates entry for web selection
        self.btn = Entry(width=75)
        #Positions entry in GUI using tkinter grid() padx and pady are the same as
        #the button to ensure they will line up
        self.btn.grid(row=1, column=1, columnspan=2, padx=(20, 10), pady=(15, 10))

    def defaultHTML(self):
        htmlText = "Stay tuned for our amazing summer sale!"
        htmlFile = open("index.html", "w")
        htmlContent = "\n\n
" + htmlText + "
\n\n"
        htmlFile.write(htmlContent)
        htmlFile.close()
        webbrowser.open_new_tab("index.html")

    def customtext(self):
        customText = self.btn.get()
        customFile = open("index.html", "w")
        customContent = "\n\n
" + customText + "
\n\n"
        customFile.write(customContent)
        customFile.close()
        webbrowser.open_new_tab("index.html")

if __name__ == "__main__":
    root = tk.Tk()
    App = ParentWindow(root)
    root.mainloop()


import json
import leveldb
from settings import LEVELDB_PATH
from pysyncobj import SyncObj, SyncObjConf, replicated

ldb = leveldb.LevelDB(LEVELDB_PATH)

class KVStorage(SyncObj):
    def __init__(self, selfAddress, partnerAddrs, dumpFile=None):
        self.ldb = ldb
        conf = SyncObjConf(
            fullDumpFile=dumpFile,
        )
        super(KVStorage, self).__init__(selfAddress, partnerAddrs, conf)

    def get(self, key):
        try:
            if not isinstance(key, bytes):
                key = key.encode()
            value = self.ldb.Get(key)
            value = json.loads(value.decode())
        except KeyError:
            value = ""
        return value

    # @replicated
    def set(self, key, value):
        if isinstance(key, bytes):
            key = key.decode()
        if isinstance(value, bytes):
            value = value.decode()
        value = json.dumps(value)
        self.ldb.Put(key.encode(), value.encode())

    @replicated
    def pop(self, key):
        self.ldb.Delete(key)