"""
Copy Rights, All Rights Reserved 2020
File name: shift_load_excel.py

Description:
Script collects the parsed user inputs (shift plan data from UI) in the form of python dict object
and appends the contents to the excel sheet.

Code Changes:
Release Date    Revision Date   Changes By      Description
------------    -------------   -----------     ------------
                August 2020     Sabarish AC         Initial
                August 2020     Sayan H          Code Updation
"""
import pandas as pd
from openpyxl import load_workbook, Workbook
from openpyxl.styles import Alignment, colors
import os
import sys
sys.path.append('C:\\ctpt\\ctpt-backup\\resource_integrate\\backend')
sys.path.append('C:\\ctpt\\ctpt-backup\\resource_integrate')
from format_excel import formatExcel
from util import util

const = util.excelConstants()
cfg = util.get_conf()

class ACCShiftPlan():
    def __init__(self, asso_list, *args):
        proj_dir = os.path.dirname(os.path.abspath(__file__))
        #self.excel_file = os.path.join(proj_dir, 'CTPT ACC SHIFT PLAN.xlsx')
        self.log = util.get_logger_obj()
        self.associates = asso_list
        #self.accPlan = asso_acc_list
        #self.offPlan = asso_off_list
        #self.assos_roaster_plan = assos_roaster_plan    # dict with key ('asso_plan') and values (dates in tuples)
        self.team = args[0]
        self.month = args[1]
        self.year = args[2]
        self.shore = args[3]
        self.excel_file = '-'.join([args[0], 'ACC', 'SHIFT', 'PLAN.xlsx'])
        self.sheetName = '-'.join([self.team, self.year])
        self.format_excel_inst = formatExcel(self.excel_file, self.sheetName)

    """
    Save the excel dataframe to excel workbook.
    """
    def __save__(self, wb_inst):
        wb_inst.save(self.excel_file)

    """
    Fetch the existing dataframe contents fron the excel workbook.
    """
    def __existing_dataframe__(self):
        self.ex_df = pd.read_excel(self.excel_file, sheet_name=self.sheetName, engine='openpyxl')
        return self.ex_df

    """
    Check if excel sheet exists, if not, creates a new excel sheet
    """
    def check_excel_exists(self):
        if not os.path.exists(self.excel_file):
            # If file not exists, create excel using pandas.
            self.log.info('Excel file not existing!!, Creating....')
            self.create_excel()
            self.log.info('File created....')
        return True

    """
    Create if excel file has the given sheet names.
    """
    def check_excel_sheet_exists(self, wb_inst):
        # Check if given sheet is present else create the sheet.
        if self.sheetName not in wb_inst.sheetnames:
            wb_inst.create_sheet(self.sheetName)
            # Save the excel file.
            self.__save__(wb_inst)
        # Just ensure excel has sheets (that you defined..)
        wb_existing = Workbook()
        self.log.debug('Listing out sheets present in the excel: ', self.excel_file)
        self.log.debug('Worksheets: ', wb_existing)
        for sheet in wb_existing:
            self.log.debug('Sheets Present in excel file are: ', sheet.title)

    """
    Create Excel if not exists.
    """
    def create_excel(self):
        initial_excel = Workbook()
        if self.sheetName:
            self.log.debug('Adding user defined sheet name: ', str(self.sheetName))
            initial_excel.create_sheet(self.sheetName, 0)    # Insert at first position.
            self.log.debug('Remove default sheet name..')
            initial_excel.remove(initial_excel['Sheet'])
        initial_excel.save(self.excel_file)

    """
    Function to add overall shift plan headers for a month.
    """
    def add_headers_to_sheet(self):
        self.log.debug('MONTH : ' + self.month)
        if util.generate_month_days(self.month):
            days_list = util.generate_month_days(self.month)
            self.log.debug('days in month: ' + str(self.month) + '--> ' + str(days_list[0]))
            first_headers = ['Month', 'Shore', 'Day Number ->']
            first_headers.extend(days_list[0])
            first_headers.append('SHIFT DAYS STATS')
            pre_req_excel = pd.ExcelWriter(self.excel_file, engine='openpyxl')
            # We create first header here for the excel. (Month, Shore, Day Number -->, series of day no.s)
            # We create second header here for the excel. (Team Member, series of Week days)
            header_df1 = self.create_dataframe_for_headers(first_headers, pre_req_excel)
            second_header = util.generate_weekdays_for_month(self.year, self.month, len(days_list[0]))
            header_df2 = self.create_dataframe_for_headers(second_header, pre_req_excel)

            # Create a Pandas Excel writer using XlsxWriter as the engine.
            excel_writer = pd.ExcelWriter(self.excel_file, engine='openpyxl')
            # OPen existng workbook
            excel_writer.book = load_workbook(self.excel_file)
            # copy the existing contents in sheet
            excel_writer.sheets = dict((ex_content.title, ex_content) for ex_content in excel_writer.book.worksheets)
            # Read the excel file
            existing_df = self.__existing_dataframe__()

            if existing_df.empty:    # Means, checks if excel is completely empty.
                self.log.debug('empty excel!!')
                row_index = 0   # set starting row index to 0.

            elif existing_df.columns.values.all() and self.month:
                row_index = len(existing_df)+3   # set starting row index to 0.
            # Fill the headers to excel (2 rows are filled)
            header_df1.to_excel(excel_writer, sheet_name=self.sheetName, index=False, header=True, startrow=row_index)
            header_df2.to_excel(excel_writer, sheet_name=self.sheetName, index=False, header=True, startrow=row_index+1, startcol=2)
            excel_writer.save()
            # Now perform excel formatting on saved headers.
            self.do_formatting_to_headers(days_list[0], header_df1)

    """
    Formats the Excel Headers with merging, bordering and color highlighting.
    """
    def do_formatting_to_headers(self, month_days, h_df):
        self.format_excel_inst.merge_required_header_cell(column_size=len(h_df.columns))
        _new_ex_df = self.__existing_dataframe__()
        # Evaluate month days last index.
        _month_end_col_index = const.THIRD_COLUMN + len(util.generate_month_days(self.month)[0])
        # Number of shift category sum.
        _shift_sum_cols = len(cfg.get('shift_category')) # Adding 2 columns (Night & Evening Shifts)
        # Start index for shift category sum.
        _start_index_shift_sum = _month_end_col_index + 1
        # Evaluate shift category sum's last index.
        _shift_sum_end_index = _start_index_shift_sum + _shift_sum_cols
        # Start index for shift category hours.
        _start_index_shift_hours = _shift_sum_end_index + 1
        _indices_switcher = {
            31: _shift_sum_end_index + 1,
            30: _shift_sum_end_index,
            29: _shift_sum_end_index - 1,
            28: _shift_sum_end_index - 2
        }
        # Evaluate Shift Category Hours SUm Last Index.
        _end_index_shift_hours = _start_index_shift_hours + _shift_sum_cols
        self.format_excel_inst.set_background_color_multicells(srow=len(_new_ex_df), erow=len(_new_ex_df)+1, scol=const.FIRST_COLUMN \
            , ecol=const.SECOND_COLUMN, BGColor=const.HCOL1_TO_HCOL2)
        self.format_excel_inst.set_background_color_multicells(srow=len(_new_ex_df), erow=len(_new_ex_df)+1, scol=const.THIRD_COLUMN \
            , ecol=const.THIRD_COLUMN, BGColor=const.HCOL3)
        self.format_excel_inst.set_background_color_multicells(srow=len(_new_ex_df), erow=len(_new_ex_df)+1, scol=const.FOURTH_COLUMN \
        , ecol=_month_end_col_index, BGColor=const.HMONTH_DAYS)
        self.format_excel_inst.set_background_color_multicells(srow=len(_new_ex_df), erow=len(_new_ex_df), scol=_start_index_shift_sum, \
            ecol=_shift_sum_end_index, BGColor=const.HSHIFT_SUM)
        self.format_excel_inst.set_background_color_multicells(srow=len(_new_ex_df)+1, erow=len(_new_ex_df)+1, scol=_start_index_shift_sum, \
            ecol=_shift_sum_end_index, BGColor=const.HSHIFT_SUM_PARAMS)
        self.format_excel_inst.set_background_color_multicells(srow=len(_new_ex_df)+1, erow=len(_new_ex_df)+1, scol=_indices_switcher[len(month_days)], \
            ecol=_end_index_shift_hours, BGColor=const.HSHIFT_SUM_PARAMS)

    """
    Staticmethod (No Relationship With Class): Create Dataframe for the given column headers.
    """
    @staticmethod
    def create_dataframe_for_headers(headers, excel_writer):
        days_keys_dict = dict.fromkeys(headers, None)
        # Create dataframe object for headers.
        dump_pre_reqs_df = pd.DataFrame(columns=headers)
        return dump_pre_reqs_df

    """
    Function to fill respective associate shift to respective cells (based on day number).
    """
    def fill_shift_row_cells(self, shift_df=None, shift_type='LEAVE', asso_name='Sabarish AC', start_row=2):
        __pos_index = cfg['shift_category'].index(shift_type) + 1
        self.log.debug('Positional index for ' + str(shift_type) + " is " + str(__pos_index))
        self.format_excel_inst.fill_cell_values(col=3, row=start_row, value=asso_name)
        print(f'dataframe for final shift plan to fill in excel : {shift_df}')
        for key, val in shift_df.items():
            self.format_excel_inst.fill_cell_values(col=(const.column_start + int(key)), row=start_row, \
                value=val, shift=shift_type)
        self.fill_shift_sum_row_cells(shift_df, shift_type, asso_name, start_row=start_row, ps_index=__pos_index)

    """
    Function to fill respective associate shift sum to respective cell.
    """
    def fill_shift_sum_row_cells(self, sh_df, sh_type, name, start_row=2, ps_index=0, shift_val=0):
        _ex_df = self.__existing_dataframe__()
        # Flag to evaluate shift category hours.
        _shift_hour = ''
        if sh_type in const.SHIFT_CATEGORY_HOURS:
            _shift_hour = '-'.join([sh_type, 'HOURS'])
        # Initialize _is_df flag to True, If no specific shift exists for an associate -> set it to False.
        _is_df = True
        days_in_month = util.generate_month_days(self.month)
        if not sh_df: # and sh_type!='LEAVE' and sh_type!='HOLIDAY':
            _is_df = False  # Setting flag to False as there are no shift plan existing.
            self.log.critical(f'No {sh_type} plan given for associate id: {str(name)}')
        # Fetch the counts of each shifts (ACC, NACC, EACC, GEN, OFF, LEAVE)
        _shift_count = util.fetch_shift_counts(dataframe=_ex_df, df_exists=_is_df)
        # SUM INDEX FOR ACC, GEN HOURS
        col_sum_index = const.column_start + len(days_in_month[0]) + ps_index
        # TOTAL SHIFT HOURS ON ALL SHIFTS
        col_hours_index = col_sum_index + len(cfg['shift_category'])
        # SUM INDEX FOR NACC & EACC SHIFT HOURS.
        col_nacc_eacc_index = col_sum_index + 4
        self.log.debug(f'col sum index : {col_sum_index}')
        self.log.debug(f'col hours index : {col_hours_index}')
        # Evaluate column index for associate total hours for the month (ACC, NACC, EACC & GEN)
        col_total_hours_index = const.column_start + len(days_in_month[0]) + len(cfg['shift_category']) + 5
        self.format_excel_inst.fill_cell_values(col=col_sum_index, row=start_row, value=_shift_count[sh_type], shift=sh_type)
        # Fill Shift Category (ACC, NACC, EACC & GEN) hours
        if _shift_hour:
            # Using Ternary Operator to fill sum hour values for NACC/EACC & ACC/GEN.
            self.format_excel_inst.fill_cell_values(col=col_nacc_eacc_index, row=start_row, value=_shift_count[_shift_hour],
                shift=sh_type)  if sh_type==cfg.get('shift_category')[5] or sh_type==cfg.get('shift_category')[6] else \
                self.format_excel_inst.fill_cell_values(col=col_hours_index, row=start_row, value=_shift_count[_shift_hour],
                    shift=sh_type)
            self.format_excel_inst.fill_cell_values(col=col_total_hours_index, row=start_row, value=_shift_count['TOTAL-HOURS'],
                shift=sh_type, bgcolor=const.HSHIFT_TOTAL_HOURS)
        self.log.debug(f'Filled Cells with {sh_type} to excel!!')

    """
    Convert user shift plan to object dictionary.
    """
    def convert_to_shift_dict(self, shift_plan='', gen_shift_keys=[], gen_shift_values=[]):
        _ex_df = self.__existing_dataframe__()
        # shift_plan --> format: ['1A', '2A', .... '7G']
        if not gen_shift_keys and not gen_shift_values:
            shift_k = [int(shft.split(':')[0]) for idx, shft in enumerate(shift_plan.split(' ')) if shft.split(':')[0].isdigit()]
            shift_v = [shft for shft in shift_plan if shft!=' ' and shft!=':' and not shft.isdigit()]
            shift_dict = dict(zip(shift_k, shift_v))
        # For generating general key-value pair dict.
        elif gen_shift_keys and gen_shift_values:
            shift_dict = dict(zip(gen_shift_keys, gen_shift_values))
        else:
            shift_dict = {}
        return shift_dict

    """
    Append the associate shift plan to excel workbook (Avoid overwritting)
    """
    def append_contents_to_excel(self, asso_id, acc_plan, nacc_plan, eacc_plan, off_plan, leave_plan, tcs_holiday_plan):
        print(f'evening shift plan : {eacc_plan}')
        __asso_name = self.associates[asso_id]
        self.log.info(f'Appending contents for associate Name: {str(__asso_name)}, ID: {str(asso_id)}')
        _ex_df = self.__existing_dataframe__()
        #_acc = self.convert_to_shift_dict(shift_plan=self.accPlan[asso_id])
        self.log.debug(f'Filling ACC Plan for associate id: {str(__asso_name)}, ID: {str(asso_id)}, ACC Plan: {acc_plan}')
        # Fill the cells with corresponding associates shifts.
        self.fill_shift_row_cells(shift_df=acc_plan, shift_type=cfg.get('shift_category')[0], asso_name=self.associates[asso_id], start_row=len(_ex_df)+2)
        #_off = self.convert_to_shift_dict(self.offPlan[asso_id])
        # Fill Night Shift Plans.
        self.fill_shift_row_cells(shift_df=nacc_plan, shift_type=cfg.get('shift_category')[5], asso_name=self.associates[asso_id], start_row=len(_ex_df)+2)
        self.log.debug(f'Filling NACC Plan for associate Name: {str(__asso_name)}, id: {str(asso_id)}, NACC Plan: {nacc_plan}')
        # Fill Evening Shift Plans.
        self.fill_shift_row_cells(shift_df=eacc_plan, shift_type=cfg.get('shift_category')[6], asso_name=self.associates[asso_id], start_row=len(_ex_df)+2)
        self.log.debug(f'Filling EACC Plan for associate Name: {str(__asso_name)}, id: {str(asso_id)}, EACC Plan: {eacc_plan}')
        # Fill OFF Plans
        self.log.debug(f'Filling OFF Plan for associate Name: {str(__asso_name)}, id: {str(asso_id)}, OFF Plan: {off_plan}')
        self.fill_shift_row_cells(shift_df=off_plan, shift_type=cfg.get('shift_category')[2], asso_name=self.associates[asso_id], start_row=len(_ex_df)+2)
        # Fill LEAVE Plans
        self.log.debug(f'Filling LEAVE Plan for associate Name: {str(__asso_name)}, id: {str(asso_id)}, LEAVE Plan: {leave_plan}')
        self.fill_shift_row_cells(shift_df=leave_plan, shift_type=cfg.get('shift_category')[3], asso_name=self.associates[asso_id], start_row=len(_ex_df)+2)
        # Fill HOLIDAY Plans
        self.log.debug(f'Filling HOLIDAY Plan for associate Name: {str(__asso_name)}, id: {str(asso_id)}, HOLIDAY Plan: {tcs_holiday_plan}')
        self.fill_shift_row_cells(shift_df=tcs_holiday_plan, shift_type=cfg.get('shift_category')[4], asso_name=self.associates[asso_id], start_row=len(_ex_df)+2)
        # Collect the days that has ACC, OFF, LEAVE & TCS_HOLIDAY shifts.
        _AOLHList = list(acc_plan.keys()) + list(off_plan.keys()) + list(nacc_plan.keys()) + list(eacc_plan.keys()) + list(leave_plan.keys()) + list(tcs_holiday_plan.keys())
        # Collect the days in a month.
        days_in_month = util.generate_month_days(self.month)
        # Find the difference b/w these 2 lists to collect remaining days as 'General' shifts.
        _gen_k = list(set(days_in_month[0]).difference(_AOLHList))
        _gen_v = ['G' for _k in _gen_k]
        _gen = self.convert_to_shift_dict(gen_shift_keys=_gen_k, gen_shift_values=_gen_v)
        self.log.debug(f'Filling GENERAL Plan for associate Name: {str(__asso_name)}, id: {str(asso_id)}, GENERAL Plan: {_gen}')
        self.fill_shift_row_cells(shift_df=_gen, shift_type=cfg.get('shift_category')[1], asso_name=self.associates[asso_id], start_row=len(_ex_df)+2)
        # Assign column index to fill sum of each shifts (default_col + no. of days in month + next cell)
        #_fill_shift_sum_column = const.column_start + len(days_in_month[0]) + 1

        if asso_id==len(self.associates)-1:
            self.format_excel_inst.merge_required_row_cells(asso_sum=len(self.associates), col=1, \
                value=self.month.upper(), month_days=len(days_in_month[0]))
            self.format_excel_inst.merge_required_row_cells(asso_sum=len(self.associates), col=2, \
                value=self.shore.upper(), month_days=len(days_in_month[0]))
        self.log.info(f'Associate Name: {str(__asso_name)}, ID: {str(asso_id)}: Appended Successfully!!')


import re
def mix_strings(s1, s2):

    new_s1 = re.sub('[^a-z]', '', s1)
    new_s2 = re.sub('[^a-z]', '', s2)

    count = 0
    dict_s1 = {}
    dict_s2 = {}
    arr = ''
    substr = ''
    arr = []

    for i in new_s1:
        if i in dict_s1:
            dict_s1[i] += 1
        else:
            dict_s1[i] = 1

    for i in new_s2:
        if i in dict_s2:
            dict_s2[i] += 1
        else:
            dict_s2[i] = 1

    dict_s1 = {k: v for k, v in sorted(dict_s1.items(), key=lambda item: (-item[1], item[0]))}

    dict_s2 = {k: v for k, v in sorted(dict_s2.items(), key=lambda item: (-item[1], item[0]))}

    dict_s1 = dict(filter(lambda x: x[1] > 1, dict_s1.items()))
    dict_s2 = dict(filter(lambda x: x[1] > 1, dict_s2.items()))

    for i in set(list(dict_s1.keys()) + list(dict_s2.keys())):
        if i in dict_s1 and i in dict_s2:

            if dict_s1[i] > dict_s2[i]:
                arr.append('1:' + i*dict_s1[i])

            elif dict_s1[i] == dict_s2[i]:
                arr.append('=:' + i*dict_s2[i])
            else:
                arr.append('2:' + i*dict_s2[i])
        else:
            if i in dict_s1:
                arr.append('1:' + i*dict_s1[i])
            else:
                arr.append('2:' + i*dict_s2[i])

    print(dict_s1, dict_s2)

    arr = sorted(arr, key=lambda x: (-len(x), x[0], ord(x[2:3])))

    return '/'.join(arr)

if __name__ == '__main__':

    print(mix_strings("my&friend&Paul has heavy hats! &", "my friend John has many many friends &"))
    print(mix_strings('mmmmm m nnnnn y&friend&Paul has heavy hats! &', "my frie n d Joh n has ma n y ma n y frie n ds n&"))
    print(mix_strings("Are the kids at home? aaaaa fffff", "Yes they are here! aaaaa fffff"))


from django import forms
from .models import Group
from socle.models import Subject,  Level

class GroupForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(GroupForm, self).__init__(*args, **kwargs)
        subjects = Subject.objects.filter(is_active=1)
        self.fields['subject']  = forms.ModelChoiceField(queryset=subjects)
        levels = Level.objects.order_by("ranking")
        self.fields['level']  = forms.ModelChoiceField(queryset=levels)

    class Meta:
        model = Group
        fields = ('name','labelname','color','level','is_hidden','assign','suiviparent','lock','subject','studentprofile' )

class GroupTeacherForm(forms.ModelForm):
	class Meta:
		model = Group
		fields = ('name','labelname','color','level','assign','is_hidden','suiviparent','lock','subject','studentprofile','recuperation')

	def __init__(self, *args, **kwargs):
		teacher = kwargs.pop('teacher')
		super(GroupTeacherForm, self).__init__(*args, **kwargs)
		if teacher:

			# subjects = teacher.subjects.all()
			# levels = teacher.levels.order_by("ranking")

			# if subjects :
			# 	self.fields['subject']	 = forms.ModelChoiceField(queryset=subjects,  required=True)
			# else :
			subjects = Subject.objects.filter(is_active=1)
			self.fields['subject']	 = forms.ModelChoiceField(queryset=subjects,  required=True)

			# if levels :
			# 	self.fields['level']	 = forms.ModelChoiceField(queryset=levels,  required=True)
			# else :
			subjects = Level.objects.exclude(pk=13).order_by("ranking")
			self.fields['level']	 = forms.ModelChoiceField(queryset=subjects,  required=True)


from django.contrib import admin
from django.urls import path
from . import views

''' using FBV '''

urlpatterns = [
    path('', views.index,name='index'),
    path('post/', views.post,name='post'),
    path('detail/<int:id>/', views.detail_view,name='detail'),
    path('create_post/', views.Create_post,name='create_post'),
    path('<int:pk>/update/', views.Updatepost.as_view(),name='update_post'),
    path('blogpost-like/<int:pk>', views.like_post, name="blogpost_like"),
    path('<int:id>/delete/', views.delete_post,name='delete_post'),
    path('like/', views.like_post, name='like-post'),
    # user
    path('register/', views.registerpage,name='register'),
    path('login/', views.loginpage,name='login'),
    path('logout/', views.logoutuser,name='logout'),
    path('profile/', views.profile,name='profile'),

 ]

# from .views import PostListView

# ''' using CBV '''

# urlpatterns = [
#     #path('', PostListView.as_view(),name='index'),

# ]


from ai.ai import ActivationFunction
from ai.neural_network import NeuralNetwork
class ScratchReLU01(ActivationFunction):

    BIAS = 1

    def __init__(self, input_count: int, hidden_layers_count: int, hidden_count: int,  output_count: int):
        super().__init__()

        # dtype = torch.float
        self.nn = NeuralNetwork(input_count, hidden_layers_count, hidden_count, output_count)

    def relu(self, x: float) -> float:
        if x < 0:
            return 0
        else:
            return 1

    def forward(self, inputs: list[float]) -> list[float]:

        for i in range(len(inputs) - ScratchReLU01.BIAS):
            self.nn.input.neurons[i].output = inputs[i]

        for i in range(len(self.nn.hidden_layers[0].neurons) - ScratchReLU01.BIAS):
            sum = 0
            for j in range(len(self.nn.input.neurons) - ScratchReLU01.BIAS):
                sum += self.nn.input.neurons[j].output * self.nn.hidden_layers[0].neurons[i].weights[j]

            self.nn.hidden_layers[0].neurons[i].output = self.relu(sum)

        for i in range(1, len(self.nn.hidden_layers)):
            for j in range(len(self.nn.hidden_layers[i].neurons) - ScratchReLU01.BIAS):
                sum = 0
                for k in range(len(self.nn.hidden_layers[i - 1].neurons) - ScratchReLU01.BIAS):
                    sum += self.nn.hidden_layers[i - 1].neurons[k].output * self.nn.hidden_layers[i].neurons[j].weights[k]

                self.nn.hidden_layers[i].neurons[j].output = self.relu(sum)

        last_hidden_layer = self.nn.hidden_layers[-1]
        for i in range(len(self.nn.output.neurons) - ScratchReLU01.BIAS):
            sum = 0
            for j in range(len(last_hidden_layer.neurons) - ScratchReLU01.BIAS):
                sum += last_hidden_layer.neurons[j].output * self.nn.output.neurons[i].weights[j]

            self.nn.output.neurons[i].output = self.relu(sum)

        return [n.output for n in self.nn.output.neurons]


from tkinter import *
from tkinter.simpledialog import *
from tkinter.filedialog import *
from tkinter.messagebox import *

class Edit():
    def popup(self, event):
        self.rightClick.post(event.x_root, event.y_root)

    def copy(self, *args):
        sel = self.text.selection_get()
        self.clipboard = sel

    def cut(self, *args):
        sel = self.text.selection_get()
        self.clipboard = sel
        self.text.delete(SEL_FIRST, SEL_LAST)

    def paste(self, *args):
        self.text.insert(INSERT, self.clipboard)

    def selectAll(self, *args):
        self.text.tag_add(SEL, "1.0", END)
        self.text.mark_set(0.0, END)
        self.text.see(INSERT)

    def undo(self, *args):
        self.text.edit_undo()

    def redo(self, *args):
        self.text.edit_redo()

    def find(self, *args):
        self.text.tag_remove('found', '1.0', END)
        target = askstring('Find', 'Search String:')

        if target:
            idx = '1.0'
            while 1:
                idx = self.text.search(target, idx, nocase=1, stopindex=END)
                if not idx: break
                lastidx = '%s+%dc' % (idx, len(target))
                self.text.tag_add('found', idx, lastidx)
                idx = lastidx
            self.text.tag_config('found', foreground='white', background='blue')

    def __init__(self, text, root):
        self.clipboard = None
        self.text = text
        self.rightClick = Menu(root)

def main(root, text, menubar):

    objEdit = Edit(text, root)

    editmenu = Menu(menubar)
    editmenu.add_command(label="Copy", command=objEdit.copy, accelerator="Ctrl+C")
    editmenu.add_command(label="Cut", command=objEdit.cut, accelerator="Ctrl+X")
    editmenu.add_command(label="Paste", command=objEdit.paste, accelerator="Ctrl+V")
    editmenu.add_command(label="Undo", command=objEdit.undo, accelerator="Ctrl+Z")
    editmenu.add_command(label="Redo", command=objEdit.redo, accelerator="Ctrl+Y")
    editmenu.add_command(label="Find", command=objEdit.find, accelerator="Ctrl+F")
    editmenu.add_separator()
    editmenu.add_command(label="Select All", command=objEdit.selectAll, accelerator="Ctrl+A")
    menubar.add_cascade(label="Edit", menu=editmenu)

    root.bind_all("<Control-z>", objEdit.undo)
    root.bind_all("<Control-y>", objEdit.redo)
    root.bind_all("<Control-f>", objEdit.find)
    root.bind_all("Control-a", objEdit.selectAll)

    objEdit.rightClick.add_command(label="Copy", command=objEdit.copy)
    objEdit.rightClick.add_command(label="Cut", command=objEdit.cut)
    objEdit.rightClick.add_command(label="Paste", command=objEdit.paste)
    objEdit.rightClick.add_separator()
    objEdit.rightClick.add_command(label="Select All", command=objEdit.selectAll)
    objEdit.rightClick.bind("<Control-q>", objEdit.selectAll)

    text.bind("<Button-3>", objEdit.popup)

    root.config(menu=menubar)

if __name__ == "__main__":
    print("Please run 'main.py'")


import os
import typing
import getpass
import datetime

import jk_typing
import jk_console
import jk_mediawiki
import jk_logging

from .impl.LocalWikiInstInfo import LocalWikiInstInfo
from .impl.LocalWikiScanner import LocalWikiScanner
from .MWManagementCtx import MWManagementCtx

def _formatMBytes(n:int) -> str:
	s = str(round(n, 1)) + "M"
	while len(s) < 7:
		s = " " + s
	return s
#

class _StatusOverviewResult(object):

	def __init__(self, table:jk_console.SimpleTable, pids:typing.List[int]):
		self.table = table
		self.pids = pids
	#

#

#
# This class manages the set of local MediaWiki installations.
#
class LocalMediaWikisMgr(object):

	################################################################################################################################
	## Constructors
	################################################################################################################################

	#
	# Constructor.
	#
	# @param		str wwwWikiRootDir			The directory where all local MediaWiki installations reside.
	#
	@jk_typing.checkFunctionSignature()
	def __init__(self, ctx:MWManagementCtx, wwwWikiRootDir:str, bVerbose:bool):
		if not os.path.isdir(wwwWikiRootDir):
			raise Exception("No such directory: \"{}\"".format(wwwWikiRootDir))
		self.__wwwWikiRootDir = os.path.abspath(wwwWikiRootDir)

		self.__userName = getpass.getuser()

		self.__bVerbose = bVerbose

		self.__wikiScanner = LocalWikiScanner(self.__wwwWikiRootDir)

		self.__ctx = ctx
	#

	################################################################################################################################
	## Public Properties
	################################################################################################################################

	#
	# The directory where all local MediaWiki installations reside.
	#
	@property
	def wwwWikiRootDir(self) -> str:
		return self.__wwwWikiRootDir
	#

	################################################################################################################################
	## Helper Methods
	################################################################################################################################

	#
	# Collects a list of installed mediawikis
	#
	@jk_typing.checkFunctionSignature()
	def _getStatusOverview(self, wikiName:typing.Union[str,None], bWithDiskSpace:bool, bVerbose:bool, log:jk_logging.AbstractLogger) -> _StatusOverviewResult:
		wikiInsts = self.__wikiScanner.wikis

		pids = []

		t = jk_console.SimpleTable()
		rowData = [ "Wiki", "MW Version", "SMW Version", "Status", "Last configuration", "Last use", "Cron Script Processes" ]
		if bWithDiskSpace:
			rowData.append("SizeRO")
			rowData.append("SizeRW")
		t.addRow(*rowData).hlineAfterRow = True
		r = jk_console.Console.RESET

		for wikiInst in wikiInsts:
			if wikiName:
				if wikiInst.name != wikiName:
					continue

			blog = jk_logging.BufferLogger.create()
			try:
				with blog.descend("Checking wiki: " + wikiInst.name) as log2:
					h = jk_mediawiki.MediaWikiLocalUserInstallationMgr(self.__ctx, wikiInst, log2)
					bIsRunning = h.isCronScriptRunning()
					c = jk_console.Console.ForeGround.STD_GREEN if bIsRunning else jk_console.Console.ForeGround.STD_DARKGRAY
					smVersion = h.getSMWVersion()
					lastCfgTime = h.getLastConfigurationTimeStamp()
					lastUseTime = h.getLastUseTimeStamp()
					processInfos = h.getCronProcesses()
					if processInfos:
						processPIDs = [ x["pid"] for x in processInfos ]
						pids.extend(processPIDs)
					rowData = [
						wikiInst.name,
						str(h.getVersion()),
						str(smVersion) if smVersion else "-",
						"running" if bIsRunning else "stopped",
						lastCfgTime.strftime("%Y-%m-%d %H:%M") if lastCfgTime else "-",
						lastUseTime.strftime("%Y-%m-%d %H:%M") if lastUseTime else "-",
						str(processPIDs) if bIsRunning else "-",
					]
					if pids:
						pids.extend(pids)
					if bWithDiskSpace:
						diskUsage = h.getDiskUsage()
						rowData.append(_formatMBytes(diskUsage.ro / 1048576))
						rowData.append(_formatMBytes(diskUsage.rw / 1048576))
					t.addRow(*rowData).color = c
			except jk_logging.ExceptionInChildContextException as ee:
				pass

			if blog.stats.hasAtLeastWarning or bVerbose:
				blog.forwardTo(log)

		return _StatusOverviewResult(t, pids)
	#

	################################################################################################################################
	## Public Methods
	################################################################################################################################

	def getWikiInstDirPath(self, wikiName:str):
		return self.__wikiScanner.getWikiInstDirPath(wikiName)
	#

	#
	# Scan the disk to list all existing Wikis (= running and not running).
	#
	# @return		str[] wikiNames			The names of the wikis available.
	#
	def listWikis(self) -> list:
		return self.__wikiScanner.wikiNames
	#

	#
	# Collects a list of mediawikis installed
	#
	@jk_typing.checkFunctionSignature()
	def getStatusOverviewAll(self, bWithDiskSpace:bool, bVerbose:bool, log:jk_logging.AbstractLogger) -> _StatusOverviewResult:
		return self._getStatusOverview(None, bWithDiskSpace, bVerbose, log)
	#

	#
	# Collects a list of mediawikis installed
	#
	@jk_typing.checkFunctionSignature()
	def getStatusOverviewOne(self, wikiName:str, bWithDiskSpace:bool, bVerbose:bool, log:jk_logging.AbstractLogger) -> _StatusOverviewResult:
		return self._getStatusOverview(wikiName, bWithDiskSpace, bVerbose, log)
	#

	#
	# Get a matrix that lists all wikis with all extensions.
	#
	@jk_typing.checkFunctionSignature()
	def getExtensionMatrix(self, log:jk_logging.AbstractLogger) -> jk_console.SimpleTable:
		# str[] wikiNames
		# MediaWikiLocalUserInstallationMgr[] wikis
		# MediaWikiExtensionInfo[] wikiExtensionInfos

		wikiInsts = self.__wikiScanner.wikis
		wikiNames = [ wikiInst.name for wikiInst in wikiInsts ]
		wikis = [ jk_mediawiki.MediaWikiLocalUserInstallationMgr(wikiInst, self.__userName, log) for wikiInst in wikiInsts ]
		wikiExtensionInfos = []

		allExtensionNames = set()
		for i, wikiName in enumerate(wikiNames):
			with log.descend("Scanning: {}".format(wikiName)) as log2:
				try:
					if self.__bVerbose:
						extInfos = []
						for extInfo in wikis[i].getExtensionInfos(log2):
							extInfos.append(extInfo)
					else:
						extInfos = list(wikis[i].getExtensionInfos())
				except jk_logging.ExceptionInChildContextException as ee:
					log2.error("Stopping scanning for {} because of errors.".format(wikiName))
					extInfos = None
				except Exception as ee:
					log2.error(ee)
					log2.error("Stopping scanning for {} because of errors.".format(wikiName))
					extInfos = None

			wikiExtensionInfos.append(extInfos)
			if extInfos:
				for extInfo in extInfos:
					allExtensionNames.add(extInfo.name)
		allExtensionNames = sorted(allExtensionNames)

		allExtensionsRowIndex = { name:(i+2) for i, name in enumerate(allExtensionNames) }

		# prepare data matrix

		columnNames = [ "" ] + allExtensionNames
		rowNames = [ "" ] + wikiNames
		rowNames2 = [ "" ] + [ str(w.getVersion()) for w in wikis ]
		_emptyList = [ "-" for x in wikiNames ]
		_emptyList2 = [ 0 for x in wikiNames ]

		table = jk_console.SimpleTable()
		table.addRow(*rowNames)
		table.addRow(*rowNames2).hlineAfterRow = True
		table.row(0).color = jk_console.Console.ForeGround.STD_LIGHTCYAN
		table.row(1).color = jk_console.Console.ForeGround.STD_LIGHTCYAN

		rawTimeData = []

		for extensionName in allExtensionNames:
			dataRow = [ extensionName ] + _emptyList
			table.addRow(*dataRow)[0].color = jk_console.Console.ForeGround.STD_LIGHTCYAN
			rawTimeData.append(list(_emptyList2))

		# fill with raw data

		dtEpoch = datetime.datetime(1970, 1, 1)
		for _x, h in enumerate(wikis):
			colNo = _x + 1
			if wikiExtensionInfos[_x]:
				for extInfo in wikiExtensionInfos[_x]:
					rowNo = allExtensionsRowIndex[extInfo.name]

					s = str(extInfo.version) if extInfo.version else None
					if extInfo.latestTimeStamp:
						if s is None:
							s = extInfo.latestTimeStamp.strftime("%Y-%m-%d")
						rawTimeData[rowNo - 2][_x] = (extInfo.latestTimeStamp - dtEpoch).total_seconds()

					if s:
						table.row(rowNo)[colNo].value = s
					else:
						table.row(rowNo)[colNo].value = "?"
			else:
				for rowNo in allExtensionsRowIndex.values():
					table.row(rowNo)[colNo].value = "err"

		for _y in range(0, len(rawTimeData)):
			row = rawTimeData[_y]
			maxX = -1
			maxT2 = 0
			maxT = 0

			for _x in range(0, len(row)):
				if row[_x] > maxT:
					maxT2 = maxT
					maxT = row[_x]
					maxX = _x
				cell = table.row(_y + 2)[_x + 1]
				if cell.value == "err":
					cell.color = jk_console.Console.ForeGround.STD_RED
				else:
					cell.color = jk_console.Console.ForeGround.STD_DARKGRAY

			for _x in range(0, len(row)):
				cell = table.row(_y + 2)[_x + 1]
				if (maxT > 0) and (row[_x] == maxT):
					cell.color = jk_console.Console.ForeGround.STD_YELLOW
				elif (maxT2 > 0) and (row[_x] == maxT2):
					cell.color = jk_console.Console.ForeGround.STD_LIGHTGRAY

		# return table

		return table
	#

#


import functools
import torch
import torch.nn as nn
from torch.nn.functional import softmax
import dataset.rst_tree as rsttree
from nltk import Tree
from networks.parser import SpanBasedParser

class EnsembleParser(nn.Module):
    def __init__(self, parsers, device):
        super(EnsembleParser, self).__init__()
        self.parsers = parsers
        self.device = device

    @classmethod
    def load_model(cls, model_paths, config, fields):
        models = []
        for model_path in model_paths:
            models.append(SpanBasedParser.load_model(model_path, config, fields))

        device = torch.device('cpu') if config.cpu else torch.device('cuda:0')
        return cls(models, device)

    def parse(self, doc):
        batch = doc.to_batch(self.device)
        output = self.__call__(batch)
        tree = output['tree'][0]
        tree = Tree.fromstring(tree)
        return tree

    def forward(self, batch):
        # run embedder
        ensemble_rnn_outputs = []
        for parser in self.parsers:
            ensemble_rnn_outputs.append(parser.embed(batch))

        # run top-down parser
        pred_trees = []
        for i in range(len(batch)):
            tree, _ = self.ensemble_greedy_tree(
                [rnn_outputs[i] for rnn_outputs in ensemble_rnn_outputs],
                batch.starts_sentence[i],
                batch.starts_paragraph[i],
                batch.parent_label[i])
            pred_trees.append(tree.convert().linearize())

        return {'tree': pred_trees}

    def ensemble_greedy_tree(self, ensemble_rnn_output, starts_sentence, starts_paragraph, parent_label):
        sentence_length = len(ensemble_rnn_output[0])  # no padded
        for i, parser in enumerate(self.parsers):
            parser.starts_sentence = starts_sentence
            parser.starts_paragraph = starts_paragraph
            parser.rnn_output = parser.edge_pad(ensemble_rnn_output[i])

        @functools.lru_cache(maxsize=None)
        def helper(left, right, parent_label=None):
            assert 0 <= left < right <= sentence_length
            if right - left == 1:  # 終了条件
                tag, word = 'text', str(left)
                tree = rsttree.LeafParseNode(left, tag, word)
                return tree, torch.zeros(1, device=self.device).squeeze()

            ensemble_split_scores = []
            for parser in self.parsers:
                ensemble_split_scores.append(parser.get_split_scores(left, right))

            split_scores = self._ensemble(ensemble_split_scores)
            split, split_loss = parser.predict_split(split_scores, left, right)

            ensemble_ns_label_scores = []
            ensemble_rela_label_scores = []
            for parser in self.parsers:
                feature = parser.get_feature_embedding(left, right, split, parent_label)
                ensemble_ns_label_scores.append(parser.f_ns(feature))
                ensemble_rela_label_scores.append(parser.f_rela(feature))

            ns_label_scores = self._ensemble(ensemble_ns_label_scores)
            rela_label_scores = self._ensemble(ensemble_rela_label_scores)
            ns, ns_loss = parser.predict_label(ns_label_scores, left, right,
                                               sentence_length, parser.ns_vocab, 0)
            rela, rela_loss = parser.predict_label(rela_label_scores, left, right,
                                                   sentence_length, parser.rela_vocab, 1)

            left_trees, left_loss = helper(left, split, (ns, rela))
            right_trees, right_loss = helper(split, right, (ns, rela))
            children = rsttree.InternalParseNode((':'.join((ns, rela)),), [left_trees, right_trees])
            return children, ns_loss + rela_loss + split_loss + left_loss + right_loss

        pred_tree, loss = helper(0, sentence_length, parent_label)
        return pred_tree, loss

    @staticmethod
    def _ensemble(ensemble_scores):
        # ensemble_scores: list of scores tensor
        ensemble_scores = [softmax(scores, dim=0) for scores in ensemble_scores]
        scores = torch.sum(torch.stack(ensemble_scores), dim=0)
        # scores = scores.data.cpu().numpy()  # numpyとして返す
        return scores


# -*- coding: utf-8 -*-
"""
Created on Thu Oct 13 10:29:07 2016

@author: d_floriello

Outages analysis
"""

import pandas as pd
import datetime
import numpy as np
from collections import OrderedDict
import matplotlib.pyplot as plt

out = pd.read_excel('C:/Users/d_floriello/Documents/ourages_fran_2016-10-12.xlsx')

today = datetime.datetime(2016, 10, 24)

out = out.ix[out['Fin Indispo'] >= today]

###############################################################################
def update_outages(out, today):
    out = out.ix[out['Fin Indispo'] >= today]
    ids = np.unique(out['ID Indisponibilité de production'])
    ixl = []
    for ii in ids:
        given = out.ix[out['ID Indisponibilité de production'] == ii]
        ixl.append(max(given.index.tolist()))
    out = out[['ID Indisponibilité de production', "Type d'indisponibilité", 'Filière',
       "Type de l'unité de production",  'Nom du producteur',
       'Puissance nominale', 'Puissance disponible restante', 'Cause',
       'Statut']]
    return out.ix[ixl]
###############################################################################
def get_statistics(out, by, varname):
    diz1 = OrderedDict()
    diz2 = OrderedDict()
#    categorical = ["Type d'indisponibilité", 'Filière',
#       "Type de l'unité de production",  'Nom du producteur','Cause',
#       'Statut']
    grouped = out.groupby(by = by)
    names = list(set(out[by].tolist()))
#    if varname in categorical:
    for i in names:
        il1 = []
        il2 = []
        for vn in list(set(out[varname].tolist())):
            il1.append(np.where(grouped.get_group(i)[varname] == vn)[0].size)
        il2 = [i/sum(il1) if sum(il1) > 0 else 0 for i in il1]
        diz1[i] = il1
        diz2[i] = il2
    df1 = pd.DataFrame.from_dict(diz1, orient = 'index')
    df2 = pd.DataFrame.from_dict(diz2, orient = 'index')
    df1.columns = [list(set(out[varname].tolist()))]
    df2.columns = [list(set(out[varname].tolist()))]

    return df1, df2
###############################################################################
def get_statistics_all(out):
    varnames = ["Type d'indisponibilité", 'Filière',
       "Type de l'unité de production",  'Nom du producteur',
       'Puissance nominale', 'Puissance disponible restante', 'Cause']
#    categorical = ["Type d'indisponibilité", 'Filière',
#       "Type de l'unité de production",  'Nom du producteur','Cause',
#       'Statut']
    for vn in varnames:
        remains = set(varnames).difference(vn)
        for rmn in remains:
            S, P = get_statistics(out, vn, rmn)
            print('Statistics of {} vs {}:'.format(vn, rmn))
            print(S)
            print(P)
            print('##################################')
###############################################################################
def get_simple_count(out, month, var):
    today = datetime.datetime(2016, month, 1)
    out2 = update_outages(out, today)
    print('num outages totali nel mese {}= {}'.format(month, out2.shape[0]))
    vn = set(list(out2[var]))
    cts = []
    for v in vn:
        print('percentage of {} outages = {}'.format(v, out2[var].ix[out2[var] == v].count()/out2.shape[0]))
        cts.append(out2[var].ix[out2[var] == v].count()/out2.shape[0])
    return cts
###############################################################################
def get_remaining_power(out, month):
    today = datetime.datetime(2016, month, 1)
    out2 = update_outages(out, today)
    out2 = out2.reset_index(drop = True)
    print('num outages totali nel mese {}= {}'.format(month, out2.shape[0]))
    remaining = perc = 0
    for r in range(out2.shape[0]):
        remaining += out2['Puissance nominale'].ix[r] - out2['Puissance disponible restante'].ix[r]
    perc = remaining/out2['Puissance nominale'].sum()
    return remaining, perc
###############################################################################
out2 = update_outages(out, today)

varnames = ['ID Indisponibilité de production', "Type d'indisponibilité", 'Filière',
       "Type de l'unité de production",  'Nom du producteur',
       'Puissance nominale', 'Puissance disponible restante', 'Cause',
       'Statut']

S, P = get_statistics(out2, varnames[2], varnames[6])
P.sum(axis = 1)

###############################################################################
##################################### 2015 ####################################
###############################################################################

out = pd.read_excel('C:/Users/d_floriello/Documents/out2015.xlsx')

nmn = ['num outages tot', 'tot indisp', '%tot indisp', 'altro_filiera', 'Hydraulique lacs',
 "Hydraulique fil de l'eau / éclusée",
 'Nucléaire',
 'Charbon',
 'Autre',
 'Gaz',
 'Marin',
 'Fioul',
 'Hydraulique STEP',
 'altro',
 'Indisponibilité planifiée', 'Indisponibilité fortuite']#,
# 'altro_prod',
# 'DIRECT ENERGIE',
# 'TOTAL',
# 'GDF-SUEZ',
# 'UNIPER',
# 'EDF',
# 'PSS POWER',
# 'ALPIQ']

diz = OrderedDict()
# il DataFrame risultante verra riempito da diz per righe.
# ogni entrata di diz sarà:
# 0: num outages totali;
# 1: indisponibilita totale in MWh(?)
# 2: indisponibilita inpercentuale
# 3: per ogni tipo di centrale la percentuale fuori uso di quel tipo sul totale outages
# 4: percentuale cause
# 5: percentuale produttori
mon = [1,2,3,4,5,6,7,8,9,10,11,12]
filiera = list(set(out['Filière']))
tipo = list(set(out["Type d'indisponibilité"]))
prod = list(set(out['Nom du producteur']))
cause = list(set(out['Cause']))
filiera = [i for i in filiera if isinstance(i, str)]
tipo = [i for i in tipo if isinstance(i, str)]
prod = [i for i in prod if isinstance(i, str)]
cause = [i for i in cause if isinstance(i, str)]
for m in mon:
    vec = []
    out2 = out.set_index(out['Fin Indispo'])
    atm = out2.ix[out2.index.month > m]
    ids = list(set(atm['ID Indisponibilité de production']))
    ind = tot = 0
    nfil = np.repeat(0, len(filiera)).tolist()
    ntip = np.repeat(0, len(tipo)).tolist()
    npro = np.repeat(0, len(prod)).tolist()
    ncau = np.repeat(0, len(cause)).tolist()
    if len(ids) > 0:
        vec.append([len(ids)]) ### num outages totali
        for i in ids:
#            print(ind)
#            print(type(ind))
#            print(tot)
#            print(type(tot))
            I = atm.ix[atm['ID Indisponibilité de production'] == i]
            M = I.ix[I['Version'] == np.max(I['Version'])]
            ind += M['Puissance nominale'].values[0] - M['Puissance disponible restante'].values[0]
            tot += M['Puissance nominale'].values[0]
#            print(ind)
#            print(type(ind))
#            print(tot)
#            print(type(tot))
            for fil in filiera:
                if fil == M['Filière'].values[0]:
                    indx = filiera.index(fil)
                    nfil[indx] += 1
            for tip in tipo:
                if tip == M["Type d'indisponibilité"].values[0]:
                   #print(M["Type d'indisponibilité"].values[0])
                   indx = tipo.index(tip)
                   ntip[indx] += 1
                   #print(ntip)
            for pro in prod:
                if pro == M['Nom du producteur'].values[0]:
                    indx = prod.index(pro)
                    npro[indx] += 1
            for cu in cause:
                if cu == M['Cause'].values[0]:
                    indx = cause.index(cu)
                    ncau[indx] += 1
        perc = ind/tot
        print(perc)
        vec.append([ind])
        vec.append([perc])
        print((np.array(ntip)/len(ids)).tolist())
        vec.append((np.array(nfil)/len(ids)).tolist())
        #vec.append((np.array(ntip)/len(ids)).tolist())
        vec.append([ntip[0]/len(ids)])
        vec.append([ntip[1]/len(ids)])
        #vec.append((np.array(npro)/len(ids)).tolist())
        #vec.append(ncau/ids.size)
        vec= [item for sublist in vec for item in sublist]
        #vec = np.array(vec).ravel().tolist()
        diz[str(m)] = vec
    else:
        diz[str(m)] = np.repeat(0,len(nmn)).tolist()

DF = pd.DataFrame.from_dict(diz, orient = 'index')
DF.columns = [nmn]
DF.shape

fs = pd.read_excel('C:/Users/d_floriello/Documents/Prezzi Francia e Svizzera (2015 -2016).xlsx', sheetname = '2015')
fs = fs[fs.columns[[2,3]]].set_index(fs['Data'])
plt.figure()
plt.plot(fs[fs.columns[0]].resample('D').mean())
plt.figure()
DF[DF.columns[3:13]].plot()

from pandas.tools import plotting

plt.figure()
plotting.parallel_coordinates(DF[DF.columns[3:13]])

for i in range(1,13,1):
    print(sorted(DF[DF.columns[3:13]].ix[DF.index == str(i)]))

nuc = []
hydro = []
gas = []
coal = []
rim = []
perc = []
for i in range(1,13,1):
    nuc.append(get_simple_count(out, i, 'Filière')[3])
    hydro.append(get_simple_count(out, i, 'Filière')[2] + get_simple_count(out, i, 'Filière')[5])
    gas.append(get_simple_count(out, i, 'Filière')[1])
    coal.append(get_simple_count(out, i, 'Filière')[0])
    rim.append(get_remaining_power(out, i)[0])
    perc.append(get_remaining_power(out, i)[1])

diz2 = OrderedDict()
diz2['nucleare'] = nuc
diz2['hydro'] = hydro
diz2['gas'] = gas
diz2['carbone'] = coal

diz3 = OrderedDict()
diz3['remaining power'] = rim
diz3['%remaining power'] = perc

D2 = pd.DataFrame.from_dict(diz2)
D3 = pd.DataFrame.from_dict(diz3)

plt.figure()
plt.plot(np.array(nuc))
plt.figure()
plt.plot(np.array(fs[fs.columns[0]].resample('M').mean()))
plt.figure()
D3['%remaining power'].plot()

plt.figure()
plt.scatter(np.array(D3['remaining power']), np.array(fs[fs.columns[0]].resample('M').mean()))


import torch
import torch.nn as nn
from torch.nn import functional as F

class ASPP(nn.Module):
    """
    Reference:
    Chen, Liang-Chieh, et al. *"Rethinking Atrous Convolution for Semantic Image Segmentation."*
    """

    def __init__(self, in_planes, inner_planes=256, dilations=(12, 24, 36)):
        super(ASPP, self).__init__()

        norm_layer = nn.BatchNorm2d
        self.conv1 = nn.Sequential(nn.AdaptiveAvgPool2d((1, 1)),
                                   nn.Conv2d(in_planes, inner_planes, kernel_size=1, padding=0,
                                   dilation=1, bias=False),
                                   norm_layer(inner_planes),
                                   nn.ReLU(inplace=True))
        self.conv2 = nn.Sequential(nn.Conv2d(in_planes, inner_planes, kernel_size=1, padding=0,
                                   dilation=1, bias=False),
                                   norm_layer(inner_planes),
                                   nn.ReLU(inplace=True))
        self.conv3 = nn.Sequential(nn.Conv2d(in_planes, inner_planes, kernel_size=3,
                                   padding=dilations[0], dilation=dilations[0], bias=False),
                                   norm_layer(inner_planes),
                                   nn.ReLU(inplace=True))
        self.conv4 = nn.Sequential(nn.Conv2d(in_planes, inner_planes, kernel_size=3,
                                   padding=dilations[1], dilation=dilations[1], bias=False),
                                   norm_layer(inner_planes),
                                   nn.ReLU(inplace=True))
        self.conv5 = nn.Sequential(nn.Conv2d(in_planes, inner_planes, kernel_size=3,
                                   padding=dilations[2], dilation=dilations[2], bias=False),
                                   norm_layer(inner_planes),
                                   nn.ReLU(inplace=True))

        self.out_planes = (len(dilations) + 2) * inner_planes

    def get_outplanes(self):
        return self.out_planes

    def forward(self, x):
        _, _, h, w = x.size()
        feat1 = F.interpolate(self.conv1(x), size=(h, w), mode='bilinear', align_corners=True)
        feat2 = self.conv2(x)
        feat3 = self.conv3(x)
        feat4 = self.conv4(x)
        feat5 = self.conv5(x)
        aspp_out = torch.cat((feat1, feat2, feat3, feat4, feat5), 1)
        return aspp_out

class DeepLabv3(nn.Module):

    def __init__(self, in_planes, num_classes=19, inner_planes=256, dilations=(12, 24, 36)):
        super(DeepLabv3, self).__init__()

        norm_layer = nn.BatchNorm2d

        self.aspp = ASPP(in_planes, inner_planes=inner_planes, dilations=dilations)
        self.head = nn.Sequential(
            nn.Conv2d(
                self.aspp.get_outplanes(), 256, kernel_size=3, padding=1, dilation=1, bias=False),
            norm_layer(256),
            nn.ReLU(inplace=True),
            nn.Dropout2d(0.1),
            nn.Conv2d(256, num_classes, kernel_size=1, stride=1, padding=0, bias=True))

    def forward(self, x):
        aspp_out = self.aspp(x)
        res = self.head(aspp_out)
        return res

class DeepLabv3plus(nn.Module):

    def __init__(self, in_planes, num_classes=19, inner_planes=256, dilations=(12, 24, 36)):
        super(DeepLabv3plus, self).__init__()

        norm_layer = nn.BatchNorm2d

        self.aspp = ASPP(in_planes, inner_planes=inner_planes, dilations=dilations)
        self.head = nn.Sequential(
            nn.Conv2d(self.aspp.get_outplanes(), 256, kernel_size=3,
                      padding=1, dilation=1, bias=False),
            norm_layer(256),
            nn.ReLU(inplace=True),
            nn.Dropout2d(0.1))
        self.final = nn.Conv2d(256, num_classes, kernel_size=1, stride=1, padding=0, bias=True)
        self.tail = nn.Sequential(
            nn.Conv2d(512, 256, kernel_size=3, stride=1, padding=1, bias=True),
            norm_layer(256),
            nn.ReLU(inplace=True),
            nn.Dropout2d(0.1),
            nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1, bias=True),
            norm_layer(256), nn.ReLU(inplace=True), nn.Dropout2d(0.1))
        self.low_conv = nn.Sequential(
            nn.Conv2d(256, 256, kernel_size=1), norm_layer(256), nn.ReLU(inplace=True))

    def forward(self, x):
        x1, _, _, x4 = x
        aspp_out = self.aspp(x4)
        low_feat = self.low_conv(x1)
        aspp_out = self.head(aspp_out)
        h, w = low_feat.size()[-2:]
        aspp_out = F.interpolate(aspp_out, size=(h, w), mode='bilinear', align_corners=True)
        aspp_out = torch.cat((low_feat, aspp_out), dim=1)
        aspp_out = self.tail(aspp_out)
        res = self.final(aspp_out)
        return res

    @torch.no_grad()
    def reinit_all_layers(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode="fan_out", nonlinearity="relu")
                # bias?
            elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)


###
#   Functions for converting between different formats for state vectors
#
#   'start':  p = [P, T0, ecc, inc, OMEGA, omega, mp ...]
#   'ortho':  p = [P, T0, ecosom, esinom, inc, OMEGA, mp ...]
#   'kepler': p = [a, ecc, inc, omega, OMEGA, f, mp ...]
#   'state':  p = [x, y, z, xdot, ydot, zdot ...]
###

import numpy as np
import equationsofmotion as eom

reload(eom)

pi = np.pi
sin, cos, tan = np.sin, np.cos, np.tan
sqrt = np.sqrt

###

def start_to_ortho(pstart, angles):
    '''
    convert from 'start' to 'ortho' format or vice versa

    pstart  = parameters, (NPL x 7) array
    angles  = can be 'deg' or 'rad'
    '''
    # set angle conversion factor for degrees/radians
    if angles == 'deg': ac = pi/180.
    if angles == 'rad': ac = 1.0

    # pull values from parameter array
    ps = np.swapaxes(pstart,0,1)

    P, T0, ecc, omega, inc, OMEGA, mp = np.copy(ps)
    esinom = ecc*sin(omega*ac)
    ecosom = ecc*cos(omega*ac)

    return np.swapaxes(np.array([P, T0, ecosom, esinom, inc, OMEGA, mp]),0,1)

def ortho_to_start(portho, angles):
    '''
    convert from 'start' to 'ortho' format or vice versa

    portho  = parameters, (NPL x 7) array
    angles  = can be 'deg' or 'rad'
    '''
    # set angle conversion factor for degrees/radians
    if angles == 'deg': ac = pi/180.
    if angles == 'rad': ac = 1.0

    # pull values from parameter array
    ps = np.swapaxes(portho,0,1)

    P, T0, ecosom, esinom, inc, OMEGA, mp = np.copy(ps)
    ecc   = sqrt(ecosom**2 + esinom**2)
    omega = np.arctan2(esinom,ecosom)/ac

    return np.swapaxes(np.array([P, T0, ecc, omega, inc, OMEGA, mp]),0,1)

def ortho_to_kep(portho, epoch, msys):
    '''
    convert from 'ortho' format to 'kepler' format

    portho  = parameters, (NPL x 7) array
    epoch   = transit epoch (days)
    msys    = mass of system (M_sol; Jacobian coordinates), length(NPL)

    input angles must be in RADIANS

    '''
    # set constants
    ghere = 2.9591220363e-4             # Newtons constant

    # pull values from parameter array
    ps = np.swapaxes(portho,0,1)

    P, T0, ecosom, esinom, inc, OMEGA, mp = np.copy(ps)
    ecc   = sqrt(ecosom**2 + esinom**2)
    omega = np.arctan2(esinom,ecosom)

    pomega = OMEGA + omega
    lamb0  = eom.getlamb(-omega+pi/2., ecc, pomega)                     # mean longitude
    M0     = lamb0 - pomega                                             # mean anomaly
    Me     = M0 + 2.*pi*(epoch-T0)/P                                    # mean anomaly at epoch

    lambe  = (Me+pomega) % (2*pi)                                       # mean longitude at epoch
    lambe[lambe>pi]  -= 2*pi                                            # range -pi < lambe < +pi
    lambe[lambe<-pi] += 2*pi

    f      = eom.getf(lambe, ecc, pomega)                               # true anomaly
    a      = np.power(ghere*msys[1:],1./3) * np.power(P/(2.*pi),2./3)   # semimajor axis

    return np.swapaxes(np.array([a, f, ecc, omega, inc, OMEGA, mp]),0,1)

def rotatekep(x,y,inc,omega,OMEGA):
    cosom = cos(omega); sinom = sin(omega)
    cosOM = cos(OMEGA); sinOM = sin(OMEGA)
    cosi  = cos(inc);   sini  = sin(inc)

    x1 = cosom*x - sinom*y
    y1 = sinom*x + cosom*y
    z1 = np.zeros_like(x1)

    x2 = x1
    y2 = cosi*y1 - sini*z1
    z2 = sini*y1 + cosi*z1

    x3 = cosOM*x2 - sinOM*y2
    y3 = sinOM*x2 + cosOM*y2
    z3 = z2

    return np.array([x3,y3,z3])

def kep_to_state(pkep,GMtot=1.0):
    '''
    Inputs: pkep  = Keplerian parameter vector [a, f, ecc, inc, omega, OMEGA, mp]
            GMtot = system total mass

    Outputs: state = position & velocity state vector [x,y,z,xdot,ydot,zdot]
    '''
    pkeps = np.swapaxes(pkep,0,1)

    a, f, ecc, omega, inc, OMEGA, mp = pkeps

    cosf  = cos(f)
    sinf  = sin(f)
    a1me2 = a*(1.0-ecc**2)

    r = a1me2/(1.0+ecc*cosf)

    x0 = r*cosf
    y0 = r*sinf

    vx0 = -sqrt(GMtot/a1me2)*sinf
    vy0 =  sqrt(GMtot/a1me2)*(ecc+cosf)

    xyz = np.swapaxes(rotatekep(x0,y0,inc,omega,OMEGA),0,1)
    xyzdot = np.swapaxes(rotatekep(vx0,vy0,inc,omega,OMEGA),0,1)

    return np.hstack([xyz, xyzdot])

def state_to_kep(state, mp, GMtot=1.0):
    '''
    Inputs: state = position & velocity state vector [x,y,z,xdot,ydot,zdot]
            GMtot = system total mass

    Outputs: pkep  = Keplerian parameter vector [a, f, ecc, inc, omega, OMEGA, mp]

    For all equations see Murray & Dermott chapter 2.8
    '''
    x,y,z,vx,vy,vz = np.swapaxes(state,0,1)

    rsq = x**2 + y**2 + z**2
    r   = sqrt(rsq)
    vsq = vx**2 + vy**2 + vz**2
    v   = sqrt(vsq)
    hx  = y*vz - z*vy
    hy  = z*vx - x*vz
    hz  = x*vy - y*vx
    hsq = hx**2 + hy**2 + hz**2
    h   = sqrt(hsq)

    rdot = sqrt(abs(vsq - hsq/rsq))
    rdot[vsq <= (hsq/rsq)] = 0.0

    rrdot = x*vx + y*vy + z*vz
    rdot[rrdot <= 0] *= -1

    a   = (2./sqrt(rsq) - vsq/GMtot)**-1
    ecc = sqrt(1. - hsq/(GMtot*a))
    inc = np.arccos(hz/h)

    sini  = sin(inc)

    sinOM = hx/(h*sini)
    cosOM = -hy/(h*sini)
    OMEGA = np.arctan2(sinOM,cosOM)

    sinomf =  z/(r*sini)
    cosomf = (1./cos(OMEGA))*(x/r + sin(OMEGA)*sinomf*hz/h)
    omf    = np.arctan2(sinomf,cosomf)

    OMEGA[sini==0] = 0.0
    omf[sini==0]   = np.arctan2(y/r,x/r)[sini==0]

    sinf = a*(1.-ecc**2)/(h*ecc)*rdot
    cosf = 1./ecc *(a*(1.-ecc**2)/r - 1)
    f    = np.arctan2(sinf,cosf)

    omega = (omf - f) % (2*pi)      # -pi < omega < pi
    omega[omega>pi]  -= (2*pi)
    omega[omega<-pi] += (2*pi)

    omega[ecc==0] = 0.0
    f[ecc==0] = omf[ecc==0]

    return np.swapaxes(np.array([a, f, ecc, omega, inc, OMEGA, mp]),0,1)


# Q23.Write a Python program to find the highest 3 values of corresponding keys in a
# # dictionary.
a={"a":100,"b":500,"c":300,"d":400,"e":300,"f":600,"g":700}
f=[]
w={}
d=[]
max1=0

max2=0
max3=0
for i in a:
    for j in a:
        if a[j]>max1:
            max1=a[j]
            n=j
        if a[j]>max2 and max1!=a[j]:
            max2=a[j]
            m=j
        if a[j]>max3 and max1!=a[j] and max2!=a[j]:
            max3=a[j]
            p=j
f.append(n)
f.append(m)
f.append(p)
d.append(max1)
d.append(max2)
d.append(max3)
for i in range (len(f)) :
    w.update({f[i]:d[i]})
print(w)


from ..toollib.bs import _to_bs
from ..config import config
import os

vote_up = config.get('vote_up')

def _get_author_info(bs_obj):
    ret = bs_obj.find('div', {'class': 'AuthorInfo'}).find_all('a')
    if ret:
        return ret[-1]
    return '匿名用户'

def _get_author_name(bs_obj):
    ret = _get_author_info(bs_obj)
    if ret == '匿名用户':
        return '匿名用户'
    return ret.text

def _get_author_url(bs_obj):
    ret = _get_author_info(bs_obj)
    if ret == '匿名用户':
        return ''
    return ret.get('href')

def _get_attr(bs_obj):
    return _get_author_name(bs_obj), _get_author_url(bs_obj), _get_vote(bs_obj)

def _get_vote(bs_obj):
    vote = bs_obj.find('button', {'class': 'VoteButton--up'}).text
    if vote.isdigit():
        return int(bs_obj.find('button', {'class': 'VoteButton--up'}).text)
    if 'K' in vote:
        return int(float(vote.strip('K')) * 1000)
    return 0

def _get_images(answer):
    noscripts = answer.find_all('noscript')
    if noscripts:
        images = []
        for item in noscripts:
            bs_obj = _to_bs('<' + item.text.strip('>').strip('lt;') + '/>')  # convert noscripts element to img
            src, width, height = bs_obj.img.attrs.get('src').replace('_b', ''), bs_obj.img.attrs.get(
                'data-rawwidth'), bs_obj.img.attrs.get('data-rawheight')
            images.append((src, width, height))
        return images
    return noscripts

def _get_answers(bs_obj):
    ret = []
    for item in bs_obj.find_all('div', {'class': 'List-item'}):
        if len(item.attrs.get('class')) == 1:
            ret.append(item)
    return ret

def _filter_answer(bs_obj):
    if _get_vote(bs_obj) < vote_up:
        return
    images = _get_images(bs_obj)
    if not images:
        return
    return images

#   def filter_tags(self, htmlstr):
#     print(htmlstr)
#     return
#     #先过滤CDATA
#     # re_cdata   = re.compile('//<!\[CDATA\[[^>]*//\]\]>',re.I) #匹配CDATA
#     # re_script  = re.compile('<\s*script[^>]*>[^<]*<\s*/\s*script\s*>',re.I)#Script
#     # re_style   = re.compile('<\s*style[^>]*>[^<]*<\s*/\s*style\s*>',re.I)#style
#     # re_br      = re.compile('<br\s*?/?>')#处理换行
#     re_h       = re.compile('</?\w+[^>]*>')#HTML标签
#     # re_comment = re.compile('<!--[^>]*-->')#HTML注释
#     # html          = re_cdata.sub('',htmlstr)#去掉CDATA

#     # html          = re_script.sub('',html) #去掉SCRIPT
#     # html          = re_style.sub('',html)#去掉style
#     # html          = re_br.sub('\n',html)#将br转换为换行
#     html          = re_h.sub('',htmlstr) #去掉HTML 标签
#     # html          = re_comment.sub('',html)#去掉HTML注释
#     #去掉多余的空行
#     # blank_line = re.compile('\n+')
#     # html          = blank_line.sub('\n',html)

#     return html


# nao entendi muito bem esse #16

primeiro = int(input('Primeiro termo: '))
razao = int(input('Razão: '))
decimo = primeiro + (10-1) * razao
for contador in range(primeiro, decimo + razao, razao):
    print('{} '.format(contador), end='> ')
print('OVER')


from django.conf.urls import url, include
# from rest_framework import routers

from . import views

# router = routers.DefaultRouter()
# router.register(r'locations', views.LocationViewSet)

urlpatterns = [
    # url(r'^', include(router.urls)),
    url(r'^time/$', views.current_datetime),
    url(r'^user/$', views.user_info),
    url(r'^dish/$', views.dish_list),
    url(r'^dish/(?P<id>[0-9]+)/$', views.dish_detail),
    url(r'^rate/(?P<id>[0-9]+)/$', views.post_rate),
    url(r'^current_location/$', views.current_location),
    url(r'^pickup_locations/$', views.pickup_location_list),
    url(r'^notification/$', views.notification_content),
    url(r'^notification/(?P<timestamp>[0-9]+)/$', views.notification_content_with_timestamp),
    url(r'^order/$', views.order_list),
    url(r'^order/bunch/$', views.create_orders),
    url(r'^order/history/(?P<id>[0-9]+)/$', views.history_order_user),
    url(r'^order/user/(?P<id>[0-9]+)/$', views.order_user),
    url(r'^order/(?P<id>[0-9]+)/$', views.order_amount),
    url(r'^payment/client_token/$', views.client_token),
    url(r'^payment/checkout/$', views.create_purchase_ios),
    url(r'^payment/checkout/android/$', views.create_purchase_android),

    # for debug only, commentted out in production
    # url(r'^location/(?P<id>[0-9]+)/$', views.location_detail),
]


from robot.api import ResultVisitor

class KeywordResults(ResultVisitor):

    def __init__(self, kw_list, ignore_library, ignore_type):
        self.kw_list = kw_list
        self.ignore_library = ignore_library
        self.ignore_type = ignore_type

    def start_keyword(self, kw):
        if (kw.libname not in self.ignore_library) and (kw.type not in self.ignore_type):
            kw_json = {
                "Name" : kw.name,
                "Status" : kw.status,
                "Time" : kw.elapsedtime
            }
            self.kw_list.append(kw_json)


"""
    My runtime beats 83.39 % of python3 submissions (as per leetcode).
"""
def backspace_string(s: str, t: str) -> bool:

    def back_space(strs: str) -> str:
        s1 = []
        for i in range(len(strs)):

            if strs[i] != "#":
                s1.append(strs[i])

            elif strs[i] == "#" and len(s1) != 0:
                s1.pop()

        return s1

    a = back_space(s)
    b = back_space(t)

    print(a, b)
    return a == b

# Driver Code Starts
if __name__ == "__main__":

    s = input()

    t = input()

    print(backspace_string(s, t))


from osv import osv
from osv import fields

class resource_calendar(osv.osv):
    '''
    Open ERP Model
    '''
    _inherit = "resource.calendar"
    _description = 'openerpmodel'

    _columns = {
            'attendance_ids' : fields.one2many('resource.calendar.attendance', 'calendar_id', 'Working Time'),
            'var_attendance':fields.boolean('Variable working Time', required=False),
            'var_attendance_ids' : fields.one2many('resource.calendar.variable.attendance', 'calendar_id', 'Variable Working Time'),
        }
resource_calendar()

class resource_calendar_variable_attendance(osv.osv):
    _name = "resource.calendar.variable.attendance"
    _description = "Resource Calendar"
    _columns = {
        'name' : fields.char("Name", size=64, required=True),
        'dayofweek': fields.selection([('0','Monday'),('1','Tuesday'),('2','Wednesday'),('3','Thursday'),('4','Friday'),('5','Saturday'),('6','Sunday')], 'Day of Week', required=True, select=True),
        'date_from' : fields.date('Starting Date'),
        'hour_from' : fields.float('Work from', required=True, help="Start and End time of working.", select=True),
        'hour_to' : fields.float("Work to", required=True),
        'calendar_id' : fields.many2one("resource.calendar", "Resource's Calendar", required=True),
    }
    _order = 'date_from, dayofweek, hour_from'

    _defaults = {
        'dayofweek' : '0'
    }
resource_calendar_variable_attendance()


revision = '022'
down_revision = '021'

from alembic import op
import sqlalchemy as sa
from sqlalchemy.engine import reflection
from sqlalchemy.sql import table, column

# A simple model of the workflow definitions table with only the field needed
wf_def = table('workflow_definitions_v2', column('namespace'))

# A simple model of the workflow executions table with only the field needed
wf_exec = table('workflow_executions_v2', column('workflow_namespace'))

# A simple model of the task executions table with only the field needed
task_exec = table('task_executions_v2', column('workflow_namespace'))

# A simple model of the action executions table with only the fields needed
action_executions = sa.Table(
    'action_executions_v2',
    sa.MetaData(),
    sa.Column('id', sa.String(36), nullable=False),
    sa.Column('workflow_name', sa.String(255)),
    sa.Column('workflow_namespace', sa.String(255), nullable=True)
)

def upgrade():

    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column(
        'workflow_definitions_v2',
        sa.Column(
            'namespace',
            sa.String(length=255),
            nullable=True
        )
    )

    inspect = reflection.Inspector.from_engine(op.get_bind())

    unique_constraints = [
        unique_constraint['name'] for unique_constraint in
        inspect.get_unique_constraints('workflow_definitions_v2')
    ]

    if 'name' in unique_constraints:
        op.drop_index('name', table_name='workflow_definitions_v2')

    op.create_unique_constraint(
        None,
        'workflow_definitions_v2',
        ['name', 'namespace', 'project_id']
    )

    op.add_column(
        'workflow_executions_v2',
        sa.Column(
            'workflow_namespace',
            sa.String(length=255),
            nullable=True
        )
    )

    op.add_column(
        'task_executions_v2',
        sa.Column(
            'workflow_namespace',
            sa.String(length=255),
            nullable=True
        )
    )

    op.add_column(
        'action_executions_v2',
        sa.Column('workflow_namespace', sa.String(length=255), nullable=True)
    )

    session = sa.orm.Session(bind=op.get_bind())
    values = []

    for row in session.query(action_executions):
        values.append({'id': row[0],
                       'workflow_name': row[1]})

    with session.begin(subtransactions=True):
        session.execute(wf_def.update().values(namespace=''))
        session.execute(wf_exec.update().values(workflow_namespace=''))
        session.execute(task_exec.update().values(workflow_namespace=''))

        for value in values:
            if value['workflow_name']:
                session.execute(action_executions.update().values(
                    workflow_namespace=''
                ).where(action_executions.c.id == value['id']))

    # this commit appears to be necessary
    session.commit()

# ### end Alembic commands ###


# -*- coding: utf-8 -*-
from Products.CMFCore.utils import getToolByName
from Products.Five.browser import BrowserView
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile

from bs4 import BeautifulSoup
from plone.app.contenttypes.interfaces import IFolder
from plone.dexterity.content import Container
from pyquery import PyQuery as pq
from requests.exceptions import ReadTimeout
from requests.exceptions import RequestException
from zope import schema
from zope.annotation.interfaces import IAnnotations
from zope.component import getAdapter, getAdapters
from zope.interface import implementer
from zope.interface import Interface

from genweb6.core import utils
from genweb6.upc import _
from genweb6.upc.content.packet import PACKETS_KEY

import plone.api
import re
import requests
import urllib.parse

class Ipacket(IFolder):
    """Marker interface for the packet"""

@implementer(Ipacket)
class Packet(Container):

    @property
    def b_icon_expr(self):
        return "box"

class IpacketDefinition(Interface):
    """A packet definition"""

    order = schema.Int(title=u"Order")
    URL_schema = schema.TextLine(title=u"The URL schema of the packet")

class View(BrowserView):

    template = ViewPageTemplateFile('templates/view.pt')

    def __init__(self, context, request):
        self.context = context
        self.request = request
        self.title = ''
        self.content = ''

    def __call__(self):
        return self.template()

    def get_catalog_content(self, path_to_search):
        """ Fem una consulta al catalog, en comptes de fer un PyQuery """
        raw_html = u''
        catalog = getToolByName(self.context, 'portal_catalog')

        objects = catalog(path=path_to_search)
        try:
            raw_html = objects[0]()
        except:
            raw_html = objects[0].getObject()()

        return raw_html

    def getHTML(self):
        packet_type = self.getType()
        adapter = getAdapter(self.context, IpacketDefinition, packet_type)
        adapter.packet_fields.update({'lang': utils.pref_lang()})

        url = adapter.URL_schema
        portal_url = getToolByName(self.context, "portal_url")
        portal = portal_url.getPortalObject()
        url_portal_nginx = portal.absolute_url()  # url (per dns) del lloc

        try:
            url = self.get_absolute_url(url % adapter.packet_fields)
            # check url to avoid autoreference, removing http(s) and final slash
            link_url = re.findall('https?://(.*)', url)[0].strip('/')  # url del contingut netejada
            parent_url = re.findall('https?://(.*)', self.context.absolute_url())[0].strip('/')  # url del pare netejada
            root_url = re.findall('https?://(.*)', url_portal_nginx)[0].strip('/')  # url (per dns) del lloc netejada
            if link_url != parent_url:
                if link_url.startswith(root_url):
                    # link intern, search through the catalog
                    relative_path = '/' + re.findall(root_url + '(.*)', link_url)[0]
                    url_to_search = '/'.join(portal.getPhysicalPath()) + relative_path
                    raw_html = self.get_catalog_content(url_to_search)
                    clean_html = re.sub(r'[\n\r]?', r'', raw_html)
                    doc = pq(clean_html)
                    match = re.search(r'This page does not exist', clean_html)
                    self.title = self.context.Title()  # titol per defecte
                    if not match:
                        if packet_type == 'contingut_genweb':
                            element = adapter.packet_fields['element']
                            if not element:
                                element = "#content-core"
                        else:
                            element = "#content-nucli"
                        content = pq('
').append(
                            doc(element).outerHtml()).html(method='html')
                        if not content:
                            content = _(u"ERROR. This element does not exist.") + " " + element
                    else:
                        content = _(u"ERROR: Unknown identifier. This page does not exist." + url)
                else:
                    # link extern, pyreq
                    raw_html = requests.get(url, timeout=5, verify=False)
                    clean_html = re.sub(r'[\n\r]?', r'', raw_html.text)
                    doc = pq(clean_html)
                    match = re.search(r'This page does not exist', clean_html)
                    self.title = self.context.Title()  # titol per defecte
                    if not match:
                        if packet_type == 'contingut_genweb':
                            element = adapter.packet_fields['element']
                            if not element:
                                element = "#content-core"
                        else:
                            element = "#content-nucli"
                        content = pq('
').append(
                            doc(element).outerHtml()).html(method='html')
                        if not content:
                            content = _(u"ERROR. This element does not exist.") + " " + element
                    else:
                        content = _(u"ERROR: Unknown identifier. This page does not exist." + url)
            else:
                content = _(u"ERROR. Autoreference")
        except ReadTimeout:
            content = _(u"ERROR. There was a timeout while waiting for '{0}'".format(self.get_absolute_url(self.data.url)))
        except RequestException:
            content = _(u"ERROR. This URL does not exist.")
        except:
            content = _(u"ERROR. Unexpected exception.")

        soup = BeautifulSoup(clean_html, "html.parser")
        body = soup.find_all("body")
        if body:
            class_body = body[0].get("class", [])
            valid_class = [valid for valid in class_body if valid.startswith('template-') or valid.startswith('portaltype-')]
            content = str('
' + content + '
')

        self.content = content

    def get_absolute_url(self, url):
        """
        Convert relative url to absolute
        """
        if not ("://" in url):
            base = self.context.__parent__.absolute_url() + '/'
            return urllib.parse.urljoin(base, url)
        else:
            # Already absolute
            return url

    def getPacket(self):
        return self.content

    def getTitle(self):
        # import pdb; pdb.set_trace()
        # si el contingut esta configurat i encara no tenim el content, l'obtenim
        # el titol sera el nom del contingut (llistat, paquet o genweb) o el nom de l'estudi
        if self.isAlreadyConfigured() and self.content == '':
            self.getHTML()
        return self.title

    def getType(self):
        annotations = IAnnotations(self.context)
        return annotations.get(PACKETS_KEY + '.type', None)

    def isAlreadyConfigured(self):
        annotations = IAnnotations(self.context)
        if annotations.get(PACKETS_KEY + '.type', None):
            return True
        else:
            return False

    def selectedPacket(self):
        annotations = IAnnotations(self.context)
        packet_key = annotations.get(PACKETS_KEY + '.type')
        packet_fields = annotations.get(PACKETS_KEY + '.fields')
        packet_mapui = annotations.get(PACKETS_KEY + '.mapui')

        return dict(packet_key=packet_key, value=packet_fields.get(packet_mapui.get('codi')), element=packet_fields.get(packet_mapui.get('element')))

    def show_extended_info(self):
        user = plone.api.user.get_current()

        if getattr(user, 'name', False):
            if user.name == 'Anonymous User':
                return False
        try:
            user_roles = set(plone.api.user.get_roles(user=user, obj=self.context) +
                             plone.api.user.get_roles(user=user))
        except:
            user_roles = set(plone.api.user.get_roles(user=user, obj=self.context))

        if 'Manager' in user_roles or \
           'WebMaster' in user_roles or \
           'Site Administrator' in user_roles or \
           'Owner' in user_roles:
            return True
        else:
            return False

    def absolute_url(self, url):
        """
        Convert relative url to absolute
        """
        if not ("://" in url):
            base = self.context.__parent__.absolute_url() + '/'
            return urllib.parse.urljoin(base, url)
        else:
            # Already absolute
            return url

class Configure(BrowserView):

    template = ViewPageTemplateFile('templates/configure.pt')

    def __init__(self, context, request):
        self.context = context
        self.request = request
        self.available_ptypes = sorted([adapter for adapter in getAdapters((self.context,), IpacketDefinition)], key=lambda adapter: adapter[1].order)

    def __call__(self):
        if self.request.form:
            form = self.request.form
            packet_type = form.get("packet_type", None)
            if packet_type:
                adapter = getAdapter(self.context, IpacketDefinition, packet_type)
                field_values = dict([(field, form[field]) for field in adapter.fields])
                adapter.packet_fields = field_values
                adapter.packet_type = packet_type
                adapter.packet_mapui = adapter.mapui
                return self.request.response.redirect(self.context.absolute_url())
        return self.template()

    def getAvailablePacketsInfo(self):
        return self.available_ptypes

    def getTitle(self):
        return self.context.Title()

    def selectedPacket(self):
        if self.isAlreadyConfigured():
            annotations = IAnnotations(self.context)
            packet_key = annotations.get(PACKETS_KEY + '.type')
            packet_fields = annotations.get(PACKETS_KEY + '.fields')
            packet_mapui = annotations.get(PACKETS_KEY + '.mapui')
            selected = dict(packet_key=packet_key, value=packet_fields.get(packet_mapui.get('codi')), element=packet_fields.get(packet_mapui.get('element')))
        else:
            selected = {'packet_key': '', 'value': '', 'element': ''}

        return selected

    def isAlreadyConfigured(self):
        annotations = IAnnotations(self.context)
        if annotations.get(PACKETS_KEY + '.type', None):
            return True
        else:
            return False

    def getType(self):
        annotations = IAnnotations(self.context)
        return annotations.get(PACKETS_KEY + '.type', None)


def analyze_system_performance(log_file):
    system_metrics = []
    with open(log_file, 'r') as file:
        for line in file:
            if 'system_performance' in line:
                system_metrics.append(line)
    return system_metrics

def analyze_system_events(log_file):
    system_events = []
    with open(log_file, 'r') as file:
        for line in file:
            if 'system_event' in line:
                system_events.append(line)
    return system_events

def summarize_system_performance(system_metrics, system_events):
    # Perform analysis and correlation logic based on system metrics and events
    summary = "System Performance Summary:\n"
    # ...
    return summary

# Usage example:
metrics_file = 'performance.log'
events_file = 'events.log'
system_metrics = analyze_system_performance(metrics_file)
system_events = analyze_system_events(events_file)
summary = summarize_system_performance(system_metrics, system_events)
print(summary)


import pytest
from asynctest import (
    mock as async_mock,
    TestCase as AsyncTestCase,
)

from ......messaging.request_context import RequestContext
from ......messaging.responder import MockResponder
from ......transport.inbound.receipt import MessageReceipt

from ...messages.presentation_proposal import PresentationProposal
from .. import presentation_proposal_handler as handler

class TestPresentationProposalHandler(AsyncTestCase):
    async def test_called(self):
        request_context = RequestContext.test_context()
        request_context.message_receipt = MessageReceipt()
        request_context.settings["debug.auto_respond_presentation_proposal"] = False

        with async_mock.patch.object(
                handler, "PresentationManager", autospec=True
        ) as mock_pres_mgr:
            mock_pres_mgr.return_value.receive_proposal = async_mock.CoroutineMock(
                return_value=async_mock.MagicMock()
            )
            request_context.message = PresentationProposal()
            request_context.connection_ready = True
            request_context.connection_record = async_mock.MagicMock()
            handler_inst = handler.PresentationProposalHandler()
            responder = MockResponder()
            await handler_inst.handle(request_context, responder)

        mock_pres_mgr.assert_called_once_with(request_context.profile)
        mock_pres_mgr.return_value.receive_proposal.assert_called_once_with(
            request_context.message, request_context.connection_record
        )
        assert not responder.messages

    async def test_called_auto_request(self):
        request_context = RequestContext.test_context()
        request_context.message = async_mock.MagicMock()
        request_context.message.comment = "hello world"
        request_context.message_receipt = MessageReceipt()
        request_context.settings["debug.auto_respond_presentation_proposal"] = True

        with async_mock.patch.object(
                handler, "PresentationManager", autospec=True
        ) as mock_pres_mgr:
            mock_pres_mgr.return_value.receive_proposal = async_mock.CoroutineMock(
                return_value="presentation_exchange_record"
            )
            mock_pres_mgr.return_value.create_bound_request = async_mock.CoroutineMock(
                return_value=(
                    mock_pres_mgr.return_value.receive_proposal.return_value,
                    "presentation_request_message",
                )
            )
            request_context.message = PresentationProposal()
            request_context.connection_ready = True
            handler_inst = handler.PresentationProposalHandler()
            responder = MockResponder()
            await handler_inst.handle(request_context, responder)

        mock_pres_mgr.assert_called_once_with(request_context.profile)
        mock_pres_mgr.return_value.create_bound_request.assert_called_once_with(
            presentation_exchange_record=(
                mock_pres_mgr.return_value.receive_proposal.return_value
            ),
            comment=request_context.message.comment,
        )
        messages = responder.messages
        assert len(messages) == 1
        (result, target) = messages[0]
        assert result == "presentation_request_message"
        assert target == {}

    async def test_called_not_ready(self):
        request_context = RequestContext.test_context()
        request_context.message_receipt = MessageReceipt()

        with async_mock.patch.object(
                handler, "PresentationManager", autospec=True
        ) as mock_pres_mgr:
            mock_pres_mgr.return_value.receive_proposal = async_mock.CoroutineMock()
            request_context.message = PresentationProposal()
            request_context.connection_ready = False
            handler_inst = handler.PresentationProposalHandler()
            responder = MockResponder()
            with self.assertRaises(handler.HandlerException):
                await handler_inst.handle(request_context, responder)

        assert not responder.messages


import os
import sys

dir_path = os.path.dirname(os.path.realpath(__file__))
dir_path = '/'.join(dir_path.split('/')[0:-1])
sys.path.insert(0, dir_path)
from Common.Bonanza_common_imports import *

category_list = '|'.join(BONANZA_CATEGORY_LIST)

def start_url_collection():
    jobs = []
    if DataCollectors_Configuration.ANTIQUES in category_list:
        thread_1 = Thread(target=antiques_url_collector.start_url_collection)
        thread_1.daemon = True
        jobs.append(thread_1)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.ART in category_list:
        thread_2 = Thread(target=art_url_collector.start_url_collection)
        thread_2.daemon = True
        jobs.append(thread_2)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.BABY in category_list:
        thread_3 = Thread(target=baby_url_collector.start_url_collection)
        thread_3.daemon = True
        jobs.append(thread_3)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.BOOKS in category_list:
        thread_4 = Thread(target=books_url_collector.start_url_collection)
        thread_4.daemon = True
        jobs.append(thread_4)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.BUSINESS in category_list:
        thread_5 = Thread(target=business_url_collector.start_url_collection)
        thread_5.daemon = True
        jobs.append(thread_5)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.CAMERAS in category_list:
        thread_6 = Thread(target=cameras_url_collector.start_url_collection)
        thread_6.daemon = True
        jobs.append(thread_6)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.CELL_PHONES in category_list:
        thread_7 = Thread(target=cell_phones_url_collector.start_url_collection)
        thread_7.daemon = True
        jobs.append(thread_7)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.COINS in category_list:
        thread_8 = Thread(target=coins_url_collector.start_url_collection)
        thread_8.daemon = True
        jobs.append(thread_8)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.COLLECTIBLES in category_list:
        thread_9 = Thread(target=collectibles_url_collector.start_url_collection)
        thread_9.daemon = True
        jobs.append(thread_9)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.COMPUTERS in category_list:
        thread_10 = Thread(target=computers_url_collector.start_url_collection)
        thread_10.daemon = True
        jobs.append(thread_10)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.CONSUMER_ELECTRONICS in category_list:
        thread_11 = Thread(target=consumer_electronics_url_collector.start_url_collection)
        thread_11.daemon = True
        jobs.append(thread_11)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.CRAFTS in category_list:
        thread_12 = Thread(target=crafts_url_collector.start_url_collection)
        thread_12.daemon = True
        jobs.append(thread_12)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.DIGITAL_GOODS in category_list:
        thread_13 = Thread(target=digital_goods_url_collector.start_url_collection)
        thread_13.daemon = True
        jobs.append(thread_13)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.DOLLS in category_list:
        thread_14 = Thread(target=dolls_url_collector.start_url_collection)
        thread_14.daemon = True
        jobs.append(thread_14)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.DVDS_MOVIES in category_list:
        thread_15 = Thread(target=dvds_movies_url_collector.start_url_collection)
        thread_15.daemon = True
        jobs.append(thread_15)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.ENTERTAINMENT in category_list:
        thread_16 = Thread(target=entertainment_url_collector.start_url_collection)
        thread_16.daemon = True
        jobs.append(thread_16)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.EVERYTHING_ELSE in category_list:
        thread_17 = Thread(target=everything_else_url_collector.start_url_collection)
        thread_17.daemon = True
        jobs.append(thread_17)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.FASHION in category_list:
        thread_18 = Thread(target=fashion_url_collector.start_url_collection)
        thread_18.daemon = True
        jobs.append(thread_18)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.HEALTH_BEAUTY in category_list:
        thread_19 = Thread(target=health_beauty_url_collector.start_url_collection)
        thread_19.daemon = True
        jobs.append(thread_19)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.HOME_GARDEN in category_list:
        thread_20 = Thread(target=home_garden_url_collector.start_url_collection)
        thread_20.daemon = True
        jobs.append(thread_20)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.JEWELLERY in category_list:
        thread_21 = Thread(target=jewellery_url_collector.start_url_collection)
        thread_21.daemon = True
        jobs.append(thread_21)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.MUSIC in category_list:
        thread_22 = Thread(target=music_url_collector.start_url_collection)
        thread_22.daemon = True
        jobs.append(thread_22)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.MUSICAL_INSTRUMENTS in category_list:
        thread_23 = Thread(target=musical_instruments_url_collector.start_url_collection)
        thread_23.daemon = True
        jobs.append(thread_23)
        # thread_1.start(23
        # thread_1.join()
    if DataCollectors_Configuration.PET_SUPPLIES in category_list:
        thread_24 = Thread(target=pet_supplies_url_collector.start_url_collection)
        thread_24.daemon = True
        jobs.append(thread_24)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.POTTERY in category_list:
        thread_25 = Thread(target=pottery_url_collector.start_url_collection)
        thread_25.daemon = True
        jobs.append(thread_25)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.SPECIALITY_SERVICES in category_list:
        thread_26 = Thread(target=speciality_services_url_collector.start_url_collection)
        thread_26.daemon = True
        jobs.append(thread_26)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.SPORTING_GOODS in category_list:
        thread_27 = Thread(target=sporting_goods_url_collector.start_url_collection)
        thread_27.daemon = True
        jobs.append(thread_27)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.SPORTS_MEM in category_list:
        thread_28 = Thread(target=sports_mem_url_collector.start_url_collection)
        thread_28.daemon = True
        jobs.append(thread_28)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.STAMPS in category_list:
        thread_29 = Thread(target=stamps_url_collector.start_url_collection)
        thread_29.daemon = True
        jobs.append(thread_29)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.TICKETS in category_list:
        thread_30 = Thread(target=tickets_url_collector.start_url_collection)
        thread_30.daemon = True
        jobs.append(thread_30)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.TOYS in category_list:
        thread_31 = Thread(target=toys_url_collector.start_url_collection)
        thread_31.daemon = True
        jobs.append(thread_31)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.TRAVEL in category_list:
        thread_32 = Thread(target=travel_url_collector.start_url_collection)
        thread_32.daemon = True
        jobs.append(thread_32)
        # thread_1.start()
        # thread_1.join()
    if DataCollectors_Configuration.VIDEO_GAMES in category_list:
        thread_33 = Thread(target=video_games_url_collector.start_url_collection)
        thread_33.daemon = True
        jobs.append(thread_33)
        # thread_1.start()
        # thread_1.join()
    for job in jobs:
        job.start()
    for job in jobs:
        if (job.is_alive()):
            job.join()

if __name__ == '__main__':
    start_url_collection()


import datetime

from django.core.management.base import BaseCommand
from django.db.models import Q
from django.utils import timezone
from oscar.core.loading import get_model
from waffle.models import Flag

from ecommerce.courses.models import Course

Partner = get_model('partner', 'Partner')

class Command(BaseCommand):
    help = 'Create demo course, its seats and publishes it to LMS. This should only be run in development environments!'

    def add_arguments(self, parser):
        parser.add_argument(
            '--partner',
            action='store',
            dest='partner_code',
            type=str,
            required=True,
            help='Code for the partner with which the course should be associated'
        )
        parser.add_argument(
            '--course-id',
            action='store',
            dest='course_id',
            type=str,
            default='course-v1:edX+DemoX+Demo_Course',
            help='ID of the course to be created/updated. Defaults to course-v1:edX+DemoX+Demo_Course.'
        )
        parser.add_argument(
            '--course-title',
            action='store',
            dest='course_title',
            type=str,
            default='edX Demonstration Course',
            help='Title of the course to be created/updated. Defaults to edX Demonstration Course.'
        )
        parser.add_argument(
            '--price',
            action='store',
            dest='price',
            type=int,
            default=149,
            help='Cost of the verified seat. Defaults to 149'
        )

    def handle(self, *args, **options):
        course_id = options['course_id']
        course_title = options['course_title']
        price = options['price']
        partner = Partner.objects.get(short_code=options['partner_code'])
        one_year = datetime.timedelta(days=365)
        expires = timezone.now() + one_year

        # Enable client-side checkout
        # TODO Use the management command in edx/devstack once https://github.com/jsocol/django-waffle/issues/199
        # is resolved.
        Flag.objects.update_or_create(name='enable_client_side_checkout', defaults={'everyone': True})

        # Create the course
        course, __ = Course.objects.update_or_create(id=course_id, partner=partner, defaults={
            'name': course_title,
            'verification_deadline': expires + one_year,
        })

        # Create the audit and verified seats
        audit_sku = None
        verified_sku = None
        if course.seat_products.exists():
            audit_seat = course.seat_products.filter(~Q(attributes__name='certificate_type')).first()
            audit_stock_record = audit_seat and audit_seat.stockrecords.first()
            if audit_stock_record:
                audit_sku = audit_stock_record.partner_sku
            verified_seat = course.seat_products.filter(attribute_values__value_text='verified').first()
            verified_stock_record = verified_seat and verified_seat.stockrecords.first()
            if verified_stock_record:
                verified_sku = verified_stock_record.partner_sku

        # Have to pass in the skus in case it is an update
        course.create_or_update_seat('', False, 0, sku=audit_sku)
        course.create_or_update_seat(
            'verified', True, price, expires=expires, create_enrollment_code=True, sku=verified_sku
        )
        self.stdout.write(
            self.style.SUCCESS('Created audit and verified seats for [{course_id}]'.format(course_id=course_id))
        )

        # Publish the data to the LMS
        if course.publish_to_lms():
            msg = 'An error occurred while attempting to publish [{course_id}] to LMS'.format(course_id=course_id)
            self.stderr.write(self.style.ERROR(msg))
        else:
            msg = 'Published course modes for [{course_id}] to LMS'.format(course_id=course_id)
            self.stdout.write(self.style.SUCCESS(msg))