import traceback
import datetime
import unicodedata
import operator
import csv
import grequests

from bs4 import BeautifulSoup

from resources import URLS

def scrap():
    rs = (grequests.get(u) for u in URLS.get('sillas'))
    items = []

    for response in grequests.map(rs):
        soup = BeautifulSoup(response.content, 'html.parser')

        containers = soup.find_all('div', class_='informationContainer')
        for container in containers:
            try:
                item_name = container.find_all('a')[1].get_text().strip()
                sku = container.find_all(class_='sku')[0].get_text().strip()[4:]
                price = get_price(container.find('b'))
                normal_price = get_normal_price(container.find_all('p', class_='normal-price'), price)

                percent_saving = difference(price, normal_price)
                saving = abs(price - normal_price)

                if percent_saving > 0:
                    items.append({
                        'name': item_name,
                        'sku': sku,
                        'normal': normal_price,
                        'price': price,
                        'saving': saving,
                        'percent': percent_saving,
                        'url': 'http://www.sodimac.cl/sodimac-cl/product/%s/' % (sku.replace('-', ''),)
                    })
            except Exception:
                print(traceback.format_exc())

    items = sorted(items, key=lambda k: k['percent'], reverse=True)
    to_csv(items)

def get_price(element):
    try:
        dirty_price = element.get_text() \
            .strip() \
            .replace("$", "") \
            .replace("C/U", "") \
            .replace("Caja", "") \
            .replace("Display", "") \
            .replace("ML", "") \
            .replace("Juego", "") \
            .replace("DSPL", "") \
            .replace("M2", "") \
            .replace("Pack", "") \
            .replace(".", "") \
            .strip()
        return int(dirty_price)
    except Exception as exception:
        print('No hay precio', exception, element.get_text())

def get_normal_price(elements, default_price):
    try:
        for element in elements:
            dirty_price = element.get_text() \
                .strip() \
                .replace("\n", "") \
                .replace("$", "") \
                .replace(".", "") \
                .replace("Caja", "") \
                .replace(" ", "") \
                .replace("Juego", "") \
                .replace("M2", "") \
                .replace("C/U", "")
            dirty_price = unicodedata.normalize('NFKD', dirty_price).replace(" ", "")

            if dirty_price.startswith('Ahorro'):
                continue
            elif dirty_price.startswith('Normal'):
                return int(dirty_price[7:])
            else:
                return default_price
        raise Exception('Precio no encontrado')
    except Exception as exception:
        print('Err normal price', exception)
        return default_price

def to_csv(items):
    data = []

    for item in items:
        data.append(
            (
                item['name'],
                item['sku'],
                item['normal'],
                item['price'],
                item['saving'],
                item['percent'],
                item['url'],
            )
        )

    filename = 'savings_{date:%d-%m-%Y_%H-%M-%S}.csv'.format(date=datetime.datetime.now())

    output = open(filename, 'w', newline='')
    out = csv.writer(output, delimiter=';', quotechar='|', quoting=csv.QUOTE_MINIMAL)

    out.writerow(['Nombre', 'sku', 'Precio normal', 'Precio Actual', 'Ahorro', '%', 'url'])
    out.writerows(data)
    del out
    output.close()

def print_items(items):
    for item in items:
        if item['normal'] == 1:
            continue

        try:
            percent_saving = difference(item['price'], item['normal'])
            saving = abs(item['price'] - item['normal'])

            if percent_saving > 0:
                print('Nombre: %s / %s' % (item['name'], item['sku']))
                print('Normal: ${:,.0f}'.format(item['normal']))
                print('Actual: ${:,.0f}'.format(item['price']))
                print('Ahorro: ${:,.0f} {}%'.format(saving, percent_saving))
                print()
        except Exception as exception:
            print('Skipping', item, exception)

def difference(value1, value2):
    return abs(int((((value1 - value2) / value2) * 100)))

if __name__ == "__main__":
    scrap()


import logging
import re

import requests

from .doi import get_redirect_url
from .utils import is_valid_url

logger = logging.getLogger("ZenodoAPI")

class ZenodoAPI:
    def __init__(self):
        self.base_url = "https://zenodo.org/api/records"

    def _get_record(self, recid):
        url = f"{self.base_url}/{recid}"
        logger.debug(f"Final URL: `{url}`")
        return requests.get(url).text, url

    def get_record(self, recid_or_doi):
        logger.debug(f"Fetching Zenodo record metadata for `{recid_or_doi}`")
        is_doi = "doi.org" in recid_or_doi
        if is_doi:
            try:
                record_url = get_redirect_url(recid_or_doi)
                match = re.search(r"[0-9]+", record_url)
                # fail if no match, it should not happen
                recid = match.group(0)
            except (ValueError, RuntimeError):
                logger.error(f"error with url: `{recid_or_doi}`. Skipping...")
                return
        else:
            recid = recid_or_doi

        return self._get_record(recid)


import numpy as np

def double_geometric(p, size):
    ''' This is a distribution (1-p)^{|z|} p / (2-p)

        zero - p / (2-p)
        +ve : (1-p) / (2-p)
        -ve : (1-p) / (2-p)
        then its geometric (unshifted) for both +ve and -ve with probability p
    '''
    A = np.random.geometric(p, size=size) #+ve
    B = -np.random.geometric(p, size=size) #-ve
    Ax = np.random.binomial(1, 0.5, size=size)
    Bx = 1 - Ax # choosing A or B equally

    Zero = np.random.binomial(1, p / (2-p), size=size) # places where it will be 0

    final = (A*Ax + B*Bx)*(1-Zero)
    return final


from dataclasses import dataclass
from reportlab.lib.styles import ParagraphStyle

import datetime
from decimal import ROUND_HALF_UP, Decimal

from dateutil.parser import parse
from reportlab.lib import colors, fonts, pagesizes, styles
from reportlab.lib.units import inch
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.platypus import (
    BaseDocTemplate,
    SimpleDocTemplate,
    Paragraph,
    PageBreak,
    Spacer,
    PageTemplate,
    FrameBreak,
    Table,
    TableStyle,
    Frame,
)
from reportlab.lib.enums import TA_CENTER, TA_RIGHT
from reportlab.platypus.flowables import KeepTogether
import reportlab.rl_config

from xlsxwriter import Workbook
from xlsxwriter.utility import xl_col_to_name

class DataFormatter:
    def __init__(self, data=None, filename=None, user_id=None):
        self.filename = filename
        self.user_id = user_id
        self.username = self.get_username()
        self.title = "Report Title"
        self.sub_title = ""

        self.columns = []
        self.data = data if data else []

        self.sections = []

        self.scalar_heading_column = 1

    def get_username(self):
        """
        override this method to build your username from the passed user id
        """
        return self.user_id

    def to_pdf(
        self,
        headings=None,
        orientation="letter",
        top_margin=None,
        filename=None,
        default_tablestyle=None,
    ):
        if not headings:
            headings = []
            if self.title:
                headings.append(self.title)
            if self.sub_title:
                headings.append(self.sub_title)

        filename = (
            filename
            if filename
            else self.filename.replace("xlsx", "pdf")
            if self.filename
            else None
        )

        pr = PDFReport(
            data=self.data,
            sections=self.sections,
            headings=headings,
            orientation=orientation,
            scalar_heading_column=self.scalar_heading_column,
            filename=filename,
            username=self.username,
        )
        pr.columns = self.columns
        if top_margin:
            pr.top_margin = top_margin
        if default_tablestyle:
            pr.DEFAULT_TABLE_STYLE = default_tablestyle

        pr.build()

    def to_excel(
        self,
        filename=None,
        sheetname=None,
        format_table=None,
    ):

        filename = (
            filename
            if filename
            else self.filename.replace("pdf", "xlsx")
            if self.filename
            else None
        )

        xr = XLSXReport(
            data=self.data,
            sections=self.sections,
            sheetname=sheetname,
            filename=filename,
            format_table=format_table,
            username=self.username,
        )
        xr.columns = self.columns

        xr.build()

@dataclass
class ReportSection:
    header: str
    columns: list
    data: list
    pagebreak: bool = False
    tablestyle: list = None
    footer: str = None
    footer_style: ParagraphStyle = None
    format_table: bool = False
    include_column_headers: bool = True
    space_before = 0.25 * inch
    space_after = 0.25 * inch

@dataclass
class Column:
    name: str
    heading: str = None
    font_size: float = 10
    bold: bool = False
    justify: str = "LEFT"
    scalar: str = ""
    decimal_positions: int = None
    currency: bool = False
    excel_formula: str = None
    datatype: str = "str"
    wrap: bool = False
    width: int = 10
    max_width: int = None
    paragraph_style = None
    include_commas: bool = False

    def __post_init__(self):
        self.heading = (
            self.heading.upper()
            if self.heading
            else self.name.replace("_", " ").upper()
        )
        self.justify = self.justify.upper()
        self.scalar = self.scalar.upper()

    def set_width(self, text_length):
        if not self.max_width or text_length > self.max_width:
            self.max_width = text_length if text_length > 10 else 10

@dataclass
class ExcelFormula:
    formula: str

class XLSXReport:
    def __init__(
        self,
        data=None,
        sections=None,
        headings=None,
        sheetname=None,
        filename="xlsx_report.xlsx",
        format_table=False,
        username=None,
        row_column_formats=None,
    ):
        self.data = data
        self.sections = sections
        self.sheetname = sheetname
        self.headings = headings
        self.filename = filename
        self.username = username
        self.format_table = format_table
        self.row_column_formats = row_column_formats

        if not self.headings:
            self.headings = ["XLSX Report"]

        self.columns = []

        self.workbook = None

    def setup_sheet(self):
        pass

    def pre_build(self):
        pass

    def post_build(self):
        pass

    def build(self):
        self.setup_sheet()

        self.workbook = Workbook(self.filename)
        self.pre_build()

        if self.data and len(self.data) > 0:
            self.build_section(
                ReportSection(
                    header=self.sheetname,
                    columns=self.columns,
                    data=self.data,
                    format_table=self.format_table,
                )
            )
        else:
            for section in self.sections:
                self.build_section(section)

        self.post_build()

        self.workbook.close()

    def build_section(self, section):
        headings = [x.heading for x in section.columns]

        #  data, format_table=False, sheetname="Sheet1"
        if len(section.data) > 0:
            #  set default columns widths
            for column in section.columns:
                heading_length = len(column.heading) + 2
                if heading_length > column.width:
                    if column.max_width and heading_length >= column.max_width:
                        column.width = column.max_width
                    else:
                        if heading_length > column.width:
                            column.width = heading_length

            #  determine column widths
            for row in section.data:
                for column in section.columns:
                    if not column.excel_formula:
                        if isinstance(row, dict):
                            if column.name in row:
                                value = row[column.name]
                            else:
                                value = ""
                        else:
                            if column.name in row.__dict__:
                                value = row.__dict__[column.name]
                            else:
                                value = ""

                        if not isinstance(value, ExcelFormula):
                            value_length = len(str(value).strip())
                            if value_length > column.width:
                                if (
                                    column.max_width
                                    and value_length >= column.max_width
                                ):
                                    column.width = column.max_width
                                else:
                                    if value_length > column.width:
                                        column.width = value_length

                        if not column.max_width:
                            column.set_width(
                                max(len(x) for x in str(value).split("
"))
                            )

            ws = self.workbook.add_worksheet(
                name=section.header.replace("/", "-").replace(",", "")[:31]
                if section.header
                else "Sheet1"
            )

            if section.include_column_headers:
                #  write header row
                ws.write_row(
                    row=0,
                    col=0,
                    data=headings,
                )

            for i, row in enumerate(section.data):
                height_rows = 1
                for j, column in enumerate(section.columns):
                    if isinstance(row, dict):
                        if column.name in row:
                            value = row[column.name]
                        else:
                            value = ""
                    else:
                        if column.name in row.__dict__:
                            value = row.__dict__[column.name]
                        else:
                            value = ""

                    cell_format = None
                    if isinstance(value, ExcelFormula):
                        value = (
                            value.formula.replace("?column-1", xl_col_to_name(j - 1))
                            .replace("?column-2", xl_col_to_name(j - 2))
                            .replace("?column+2", xl_col_to_name(j + 2))
                            .replace("?column", xl_col_to_name(j))
                        )
                        #
                        # value = (
                        #     value.formula.replace("?column-1", xl_col_to_name(j - 1))
                        #         .replace("?column-2", xl_col_to_name(j - 2))
                        #         .replace("?column+2", xl_col_to_name(j + 2))
                        #         .replace("?column", xl_col_to_name(j))
                        # )
                        #
                    elif column.excel_formula:
                        value = (
                            column.excel_formula.replace("?row", str(i + 2))
                            .replace("?column-1", xl_col_to_name(j - 1))
                            .replace("?column-2", xl_col_to_name(j - 2))
                            .replace("?column+2", xl_col_to_name(j + 2))
                            .replace("?column", xl_col_to_name(j))
                        )
                    else:
                        #  handle br in row for line breaks
                        if isinstance(value, str):
                            value = value.strip("\n")
                            num_rows = len(value.split("
"))
                            if num_rows > 1:
                                value = value.replace("
", "\n")
                                if num_rows > height_rows:
                                    height_rows = num_rows

                        if section.tablestyle:
                            for fmt in section.tablestyle:
                                attr = fmt[0]
                                from_cell = fmt[1]
                                to_cell = fmt[2]
                                modifier = fmt[3]
                                if from_cell == to_cell:
                                    if attr.lower() == "background":
                                        if from_cell[0] == j and from_cell[1] == i + 1:
                                            if from_cell == to_cell:
                                                if attr.lower() == "background":
                                                    if (
                                                        from_cell[0] == j
                                                        and from_cell[1] == i + 1
                                                    ):
                                                        f = self._get_column_format(
                                                            section.columns[j]
                                                        )
                                                        f[
                                                            "bg_color"
                                                        ] = modifier.hexval().replace(
                                                            "0x", "#"
                                                        )
                                                        cell_format = (
                                                            self.workbook.add_format(f)
                                                        )
                    if cell_format:
                        ws.write(i + 1, j, value, cell_format)
                    else:
                        ws.write(i + 1, j, value)

                if height_rows > 1:
                    ws.set_row(i + 1, 15.001 * height_rows)

            last_column_letter = xl_col_to_name(len(section.columns) - 1)

            if section.format_table:
                columns = []
                for i, column in enumerate(section.columns):
                    if column.scalar and column.scalar.upper() == "TOTAL":
                        columns.append(
                            {"header": column.heading, "total_function": "sum"}
                        )
                    elif column.scalar and column.scalar.upper() == "AVG":
                        columns.append(
                            {"header": column.heading, "total_function": "average"}
                        )
                    else:
                        columns.append({"header": column.heading})

                ws.add_table(
                    "A1:%s%s" % (last_column_letter, len(section.data) + 3),
                    {
                        "style": "Table Style Medium 15",
                        "total_row": 1,
                        "columns": columns,
                    },
                )
            else:
                for i, column in enumerate(section.columns):
                    if column.scalar == "TOTAL":
                        ws.write(
                            len(section.data) + 2,
                            i,
                            f"=SUM({xl_col_to_name(i)}2:{xl_col_to_name(i)}{len(section.data)+1})",
                        )
                    elif column.scalar == "AVG":
                        pass

            for i, column in enumerate(section.columns):
                ws.set_column(
                    i,
                    i,
                    column.max_width
                    if column.max_width and column.max_width < column.width
                    else column.width + 5,
                    self.workbook.add_format(self._get_column_format(column)),
                )

    @staticmethod
    def _get_column_format(column):
        f = dict(valign="top")

        if column.datatype.lower() in ["int", "integer"]:
            f["num_format"] = "#,##0"
        elif column.decimal_positions and column.decimal_positions > 0:
            f["num_format"] = "#,##0.000000000000"[: column.decimal_positions + 6]

        if column.datatype == "date":
            f["num_format"] = "mm/dd/yyyy"
        if column.datatype == "datetime":
            f["num_format"] = "mm/dd/yyyy HH:MM AM/PM"

        if column.justify == "CENTER":
            f["align"] = "center"
        elif column.justify == "RIGHT":
            f["align"] = "right"
        else:
            f["align"] = "left"

        if column.currency:
            if not column.decimal_positions:
                column.decimal_positions = 2
            f["num_format"] = "$ #,##0.000000000000"[: column.decimal_positions + 8]
            f["align"] = "right"

        if column.wrap:
            f["text_wrap"] = True

        return f

FORMAT_INT = "{0:,.0f}"

class PDFReport:
    def __init__(
        self,
        data=None,
        sections=None,
        headings=None,
        orientation="letter",
        scalar_heading_column=1,
        filename="pdf_report.pdf",
        username=None,
        date_format="%m/%d/%Y",
        include_column_headers=True,  # used only if sections is None
    ):
        self.headings = headings
        self.orientation = orientation
        self.data = data
        self.scalar_heading_column = scalar_heading_column
        self.filename = filename
        self.username = username
        self.sections = sections
        self.include_column_headers = include_column_headers

        #  Report Setup
        reportlab.rl_config.warnOnMissingFontGlyphs = 0
        pdfmetrics.registerFont(TTFont("Arial", "arial.ttf"))
        pdfmetrics.registerFont(TTFont("Arial Bold", "arialbd.ttf"))
        pdfmetrics.registerFont(TTFont("Arial Bold Italic", "arialbi.ttf"))
        pdfmetrics.registerFont(TTFont("Arial Italic", "ariali.ttf"))

        fonts.addMapping("Arial", 0, 0, "Arial")
        fonts.addMapping("Arial", 0, 1, "Arial Italic")
        fonts.addMapping("Arial", 1, 0, "Arial Bold")
        fonts.addMapping("Arial", 1, 1, "Arial Bold Italic")

        self.base_font = "Arial"
        self.bold_font = "Arial Bold"
        self.italic_font = "Arial Italic"
        self.bold_italic_font = "Arial Bold Italic"

        self.PAGE_HEIGHT = pagesizes.letter[1]
        self.PAGE_WIDTH = pagesizes.letter[0]

        self.DETAIL_STYLE = TableStyle(
            [
                ("GRID", (0, 0), (-1, -1), 0.25, colors.gray),
                ("FONTNAME", (0, 0), (-1, -1), self.base_font),
                ("FONTSIZE", (0, 0), (-1, -1), 8),
                ("BACKGROUND", (0, 0), (-1, 0), colors.transparent),
                ("TEXTCOLOR", (0, 0), (-1, 0), colors.black),
                ("ALIGNMENT", (0, 0), (-1, 0), "CENTER"),  # Center all Headings
                (
                    "ALIGNMENT",
                    (0, 1),
                    (-1, -1),
                    "LEFT",
                ),  # Left justify all remaining
                ("VALIGN", (0, 1), (-1, -1), "TOP"),
                ("VALIGN", (0, 0), (-1, 0), "BOTTOM"),
            ]
        )

        self.DEFAULT_TABLE_STYLE = [
            ("GRID", (0, 0), (-1, -1), 0.25, colors.gray),
            ("FONTNAME", (0, 0), (-1, -1), self.base_font),
            ("FONTSIZE", (0, 0), (-1, -1), 8),
            ("BACKGROUND", (0, 0), (-1, 0), colors.transparent),
            ("TEXTCOLOR", (0, 0), (-1, 0), colors.black),
            ("ALIGNMENT", (0, 0), (-1, 0), "CENTER"),  # Center all Headings
            ("ALIGNMENT", (0, 1), (-1, -1), "LEFT"),  # Left justify all remaining
            ("VALIGN", (0, 1), (-1, -1), "TOP"),
            ("VALIGN", (0, 0), (-1, 0), "BOTTOM"),
        ]

        self.HEADER_STYLE = TableStyle(
            [
                # ("GRID", (0, 0), (-1, -1), 0.25, colors.gray),
                ("FONTNAME", (0, 0), (-1, -1), self.base_font),
                ("FONTSIZE", (0, 0), (-1, -1), 10),
                ("FONTSIZE", (1, 1), (1, -1), 12),
                ("FONTSIZE", (1, 0), (1, 0), 16),
                ("BACKGROUND", (0, 0), (-1, 0), colors.transparent),
                ("TEXTCOLOR", (0, 0), (-1, 0), colors.black),
                ("ALIGNMENT", (0, 0), (0, -1), "LEFT"),
                ("ALIGNMENT", (1, 0), (1, -1), "CENTER"),
                ("ALIGNMENT", (2, 0), (2, -1), "RIGHT"),
                # ("BOTTOMPADDING", (0, 0), (-1, 0), 0.1 * inch),
                ("VALIGN", (0, 1), (-1, -1), "MIDDLE"),
            ]
        )

        self.style = styles.getSampleStyleSheet()
        self.styleN = self.style["Normal"]
        self.styleH = self.style["Heading1"]
        self.styleH2 = self.style["Heading2"]
        self.style_center = styles.getSampleStyleSheet()
        self.style_center_n = self.style_center["Normal"]
        self.style_center_n.alignment = TA_CENTER
        self.style_center_h = self.style_center["Heading1"]
        self.style_center_h.alignment = TA_CENTER
        self.style_right = styles.getSampleStyleSheet()
        self.style_right_n = self.style_right["Normal"]
        self.style_right_n.alignment = TA_RIGHT
        self.style_right_h = self.style_right["Heading1"]
        self.style_center_h.alignment = TA_RIGHT
        self.style_bullet = styles.getSampleStyleSheet()
        self.style_bullet_n = self.style_bullet["Bullet"]
        self.style_bullet_n.bulletFontName = "Symbol"
        self.style_bullet_n.leftIndent = 10

        self.report_story = []
        self.header_story = []

        self.row_heights = []
        self.report_period = ""

        if not self.headings:
            self.headings = ["QLF PDF Report"]

        self.report_story = []
        self.columns = []
        self.doc = None

        if self.orientation.upper() == "LANDSCAPE":
            self.pagesize = pagesizes.landscape(pagesizes.letter)
        else:
            self.pagesize = pagesizes.letter

        self.top_margin = 1.25 * inch + (0.5 * len(self.headings) - 1) * inch
        self.bottom_margin = 0.5 * inch
        self.left_margin = 0.5 * inch
        self.right_margin = 0.5 * inch

        self.date_format = date_format

    def setup_document(self):
        self.PAGE_HEIGHT = self.pagesize[1]
        self.PAGE_WIDTH = self.pagesize[0]

        self.doc = SimpleDocTemplate(
            self.filename,
            pagesize=self.pagesize,
            topMargin=self.top_margin,
            bottomMargin=self.bottom_margin,
            leftMargin=self.left_margin,
            rightMargin=self.right_margin,
        )

    def first_page(self, canvas, doc):
        """
        handle layout of the first page of the report

        NOTE: override this method to put custom headers in place

        Args:
            canvas (_type_): _description_
            doc (_type_): _description_
        """
        canvas.saveState()

        #  Print the headings
        style = self.styleN
        style.fontSize = 10

        header_data = []
        for i, heading in enumerate(self.headings):
            column_3 = ""
            if i == 0 and self.username:
                column_3 = f"Printed by: {self.username}"
            elif i == len(self.headings) - 1:
                column_3 = (
                    f"Printed: {datetime.date.today().strftime(self.date_format)}"
                )
            header_data.append(
                [
                    "",
                    heading,
                    column_3,
                ]
            )

        col_width = (self.PAGE_WIDTH - 1.0 * inch) / 3
        header_col_widths = (col_width, col_width, col_width)

        header_frame = Frame(
            x1=0.5 * inch,
            y1=self.PAGE_HEIGHT - 1.5 * inch,
            width=self.PAGE_WIDTH - 1.0 * inch,
            height=1 * inch,
        )
        header_table = Table(header_data, header_col_widths)
        header_table.setStyle(self.HEADER_STYLE)
        self.header_story.append(header_table)
        header_frame.addFromList(self.header_story, canvas)

        #  Print the page number
        canvas.setFont("Arial", 8)
        canvas.drawRightString(
            self.PAGE_WIDTH - 0.5 * inch, 0.4 * inch, "Page %d" % doc.page
        )
        canvas.restoreState()

    def subsequent_pages(self, canvas, doc):
        self.first_page(canvas, doc)

    def pre_build(self):
        pass

    def post_build(self):
        pass

    def build(self):
        self.setup_document()

        self.pre_build()

        if self.data and len(self.data) > 0:
            self.build_section(
                ReportSection(
                    header="",
                    columns=self.columns,
                    data=self.data,
                    include_column_headers=self.include_column_headers,
                )
            )
        else:
            for section in self.sections:
                self.build_section(section)

        self.post_build()

        self.doc.build(
            self.report_story,
            onFirstPage=self.first_page,
            onLaterPages=self.subsequent_pages,
        )

    def build_section(self, section):
        if section.header and section.header != "":
            self.report_story.append(Paragraph(section.header, style=self.styleH2))
        else:
            self.report_story.append(Spacer(1, section.space_before))

        for column in section.columns:
            if column.excel_formula and len(column.excel_formula) > 0:
                section.columns.remove(column)

        for col_number, column in enumerate(section.columns):
            #  add alignments from column defaults
            if column.justify != "LEFT":
                self.DEFAULT_TABLE_STYLE.append(
                    ("ALIGNMENT", (col_number, 1), (col_number, -1), column.justify)
                )
            if column.font_size and column.font_size > 0:
                self.DEFAULT_TABLE_STYLE.append(
                    (
                        "FONTSIZE",
                        (col_number, 1),
                        (col_number, -1),
                        column.font_size,
                    )
                )
            if column.bold:
                self.DEFAULT_TABLE_STYLE.append(
                    ("FONTNAME", (col_number, 1), (col_number, -1), self.bold_font)
                )

        report_data = []
        if section.include_column_headers:
            report_data.append([x.heading for x in section.columns])

        scalars = dict(TOTAL=dict(), AVG=dict(), COUNT=dict())
        for row in section.data:
            rr = []
            for column in section.columns:
                column_style = (
                    column.paragraph_style if column.paragraph_style else self.styleN
                )
                if column.justify == "CENTER":
                    column_style = self.style_center_n
                elif column.justify == "RIGHT" or column.currency:
                    column_style = self.style_right_n

                if isinstance(row, dict):
                    value = row[column.name]
                else:
                    value = row.__dict__[column.name]

                if value:
                    if column.datatype.lower() in ["int", "integer"]:
                        scalar_rounding = "0"
                        value = Decimal(value).quantize(
                            Decimal(scalar_rounding), rounding=ROUND_HALF_UP
                        )
                        if column.include_commas:
                            value = FORMAT_INT.format(value)
                    elif column.datatype.lower() == "date":
                        if not isinstance(value, datetime.date):
                            value = parse(value).date()
                        value = value.strftime("%m/%d/%Y")
                    elif column.datatype.lower() == "datetime":
                        if not isinstance(value, datetime.datetime):
                            value = parse(value)
                        value = value.strftime("%m/%d/%Y %I:%M%p")
                    elif column.decimal_positions:
                        scalar_rounding = "0.0000000000"[: column.decimal_positions + 2]
                        value = Decimal(value).quantize(
                            Decimal(scalar_rounding), rounding=ROUND_HALF_UP
                        )
                        if column.include_commas:
                            fmt = "{0:,.%sf}" % column.decimal_positions
                            value = fmt.format(value)
                    column_style.fontSize = column.font_size
                    display_value = value
                    if column.currency:
                        display_value = f"${value}"
                    rr.append(Paragraph(str(display_value), style=column_style))
                else:
                    rr.append("")
                string_value = str(value)
                x = max(len(x) for x in string_value.split("
"))
                # column.set_width(
                #     len(str(max(len(x) for x in string_value.split("
"))))
                # )
                column.set_width(max(len(x) for x in string_value.split("
")))
                for scalar in scalars:
                    if column.scalar == scalar:
                        if column.name not in scalars[scalar]:
                            scalars[scalar][column.name] = 0
                        if value:
                            scalar_rounding = "0.00"
                            if column.datatype.lower() in ["int", "integer"]:
                                scalar_rounding = "0"
                            if isinstance(value, str):
                                value = value.replace(",", "")
                            if column.decimal_positions:
                                scalar_rounding = "0.0000000000"[
                                    : column.decimal_positions + 2
                                ]
                            scalars[scalar][column.name] += Decimal(value).quantize(
                                Decimal(scalar_rounding),
                                rounding=ROUND_HALF_UP,
                            )

            report_data.append(rr)

        data_rows = len(report_data)
        for scalar in sorted(scalars):
            scalar_label_written = False
            if len(scalars[scalar]) > 0:
                #  add summary row:
                rr = []
                for column_number, column in enumerate(section.columns):
                    if column.name in scalars[scalar]:
                        if scalar == "TOTAL":
                            if column.include_commas:
                                if column.datatype.lower() in ["int", "integer"]:
                                    scalars[scalar][column.name] = FORMAT_INT.format(
                                        scalars[scalar][column.name]
                                    )
                                elif column.decimal_positions:
                                    fmt = "{0:,.%sf}" % column.decimal_positions
                                    scalars[scalar][column.name] = fmt.format(
                                        scalars[scalar][column.name]
                                    )
                            rr.append(scalars[scalar][column.name])
                        elif scalar == "AVG":
                            rr.append(
                                Decimal(
                                    scalars[scalar][column.name] / data_rows
                                ).quantize(Decimal("0.00"))
                            )
                        elif scalar == "COUNT":
                            rr.append(Decimal(data_rows).quantize(Decimal("0")))
                    else:
                        if not scalar_label_written and self.scalar_heading_column == (
                            column_number + 1
                        ):
                            column_style = (
                                column.paragraph_style
                                if column.paragraph_style
                                else self.styleN
                            )
                            rr.append(
                                Paragraph(
                                    f"{scalar} {section.header}", style=column_style
                                )
                            )
                            scalar_label_written = True
                        else:
                            rr.append("")
                report_data.append(rr)

        if len(self.row_heights) > 0:
            data_table = Table(
                report_data,
                colWidths=self.get_column_widths(section.columns),
                repeatRows=1,
                rowHeights=self.row_heights,
            )
        else:
            data_table = Table(
                report_data,
                colWidths=self.get_column_widths(section.columns),
                repeatRows=1,
            )

        data_table.setStyle(
            TableStyle(
                section.tablestyle if section.tablestyle else self.DEFAULT_TABLE_STYLE
            )
        )
        self.report_story.append(data_table)

        if section.footer and section.footer != "":
            self.report_story.append(Spacer(1, 0.1 * inch))
            self.report_story.append(
                Paragraph(
                    section.footer,
                    style=section.footer_style if section.footer_style else self.styleN,
                )
            )
        else:
            self.report_story.append(Spacer(1, section.space_after))

        if section.pagebreak:
            self.report_story.append(PageBreak())

    def get_column_widths(self, columns=None):
        if not columns:
            columns = self.columns

        column_widths = []

        #  get total width
        total_width = sum([x.max_width for x in columns])
        page_width = self.PAGE_WIDTH - self.left_margin - self.right_margin

        for column in columns:
            column_widths.append(page_width * column.max_width / total_width)

        return column_widths


import sqlite3

def readAssets(WorkerID):

    print("assets.py created")

    conn = sqlite3.connect('home.db')
    c =  conn.cursor()

    c.execute('SELECT * FROM AllocateTask WHERE WokerID = ?', (WorkerID, ))

    Dict = {}
    i = 0
    for row in c:
        Dict['AssetID'] = row[0]
        Dict['TaskID']=row[1]
        Dict['WorkerID']=row[2]
        Dict['TINEALLOCATE']=row[3]
        Dict['TIMEPERFORMED']=row[4]
    return Dict


# 输入：树
# 输出：当前节点的值为这个节点的原始值+所有比他大的节点的值。
# 维护一个变量，保存所有大于当前节点的节点值之和。

class Solution:
    def convertBST(self, root: TreeNode) -> TreeNode:
        def helper(root, sub):
            if not root:
                return None, sub

            root.right, sub = helper(root.right, sub)
            root.val += sub
            sub = root.val
            root.left, sub = helper(root.left, sub)
            return root, sub
        root, _ = helper(root, 0)
        return root

hot_100/二叉搜索树转为二叉累加树.py

二叉搜索树转为二叉累加树.py


# -*- coding: utf-8 -*-
"""
Created on Tue Mar 23 19:45:27 2021

@author: NTN-code
"""

import numpy as np
import cv2
from matplotlib import pyplot as plt

def main():
    # чтение изображения
    img = cv2.imread('C:\python\(((_OpenCV\image\corona.jpg')

    # конвертация в черно-белое цветовое пространство
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

    # бинаризация изображения
    ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

    # вывод изображения
    cv2.imshow('gray',gray)

    # Гаусово размытие
    thresh = cv2.GaussianBlur(thresh,(5,5),0)
    cv2.imshow('binary img',thresh)

    # избавление от шумов на изображении (удаление не нужных пикселей)
    kernel = np.ones((50,50),np.uint8)
    opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 1)
    cv2.imshow('noise',opening)

    # находим задние области
    sure_bg = cv2.dilate(opening,kernel,iterations=1)
    cv2.imshow('big',sure_bg)

    # поиск нужной области переднего плана
    dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5)
    cv2.imshow('small',dist_transform)

    # нахождение переднии области
    ret, sure_fg = cv2.threshold(dist_transform,0.01*dist_transform.max(),255,0)

    # нахождение безымянной области
    sure_fg = np.uint8(sure_fg)
    unknown = cv2.subtract(sure_bg,sure_fg)
    cv2.imshow('unknown',unknown)

    # нахождение маркеров
    ret, markers = cv2.connectedComponents(sure_fg)

    # счёт и цвет маркеров
    markers = markers+1

    # конвертируем пиксили имеющие 255 в 0
    markers[unknown==255] = 0

    # применение алгоритма водораздела
    markers = cv2.watershed(img,markers)
    img[markers == -1] = [255,0,0]
    cv2.imshow('finish',img)

    # создание сегментов
    dpi = plt.rcParams['figure.dpi']
    figsize = img.shape[1] / float(dpi), img.shape[0] / float(dpi)

    plt.figure(figsize=figsize)
    plt.imshow(markers, cmap="jet")
    filename = "markerswater.jpg"
    plt.axis('off')
    plt.savefig(filename, bbox_inches = 'tight', pad_inches = 0)

    cv2.waitKey(0)
    cv2.destroyAllWindows()

if __name__ == "__main__":
    main()


import time
import random
import psutil
from pathlib import Path
from SMWinservice import SMWinservice

class PythonCornerExample(SMWinservice):
    _svc_name_ = "My_Watchdog_for_Windows"
    _svc_display_name_ = "My_Watchdog_for_Windows"
    _svc_description_ = "That's a great winservice! :)"

    def start(self):
        self.isrunning = True

    def stop(self):
        self.isrunning = False

    def watch_process(process_name, exe_path):
        flag = 0
        for i in psutil.pids():
            if psutil.Process(i).name() == process_name:
                return flag
        if not flag:
            log_writer("检测到进程: " + process_name + " 不存在,启动该进程", ident=True)
            subprocess.Popen(exe_path, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    def check_self_if_alive():
        process_name = "python"
        command_prefix = "wmic process where \"caption like '%"
        command_suffix = "%'\" get /Format:csv"
        command = command_prefix + process_name + command_suffix
        is_alive = False
        count = 0
        output = os.popen(command)
        for line in output.readlines():
            if line.startswith('\n') or line.startswith('Node'):
                continue
            line_content = line.strip('\n')
            line_content_list = line_content.split(',')
            command_line = line_content_list[2]
            pid = line_content_list[28]
            if re.search(r"python  .*my_watchdog_for_windows_pc.py", command_line):
                print("发现运行中的Python程序: " + command_line + " PID为: " + pid)
                count += 1
        if count >= 2:
            is_alive = True
        return is_alive

    def main(self):
        # 开机时间5分钟以内, 先行等待, MACtype 加载完后才能渲染XYplorer
        while True:
            startup_duration = time.time() - psutil.boot_time()
            if startup_duration > 300:
                break
            else:
                time.sleep(1)
        if self.check_self_if_alive():
            print("已有一个 my_watchdog_for_windows_pc 在运行")
            return
        watch_process_list = list()
        watch_process_list.append(("XYplorer.exe", r'Z:\XYplorer\XYplorer.exe'))
        watch_process_list.append(("Foxmail.exe", r'"D:\Program Files\Foxmail\Foxmail.exe" /min'))
        while self.isrunning:
            for process_name, exe_path in watch_process_list:
                self.watch_process(process_name, exe_path)
            time.sleep(10)

if __name__ == '__main__':
    PythonCornerExample.parse_command_line()


import obd
import time
from options import mockMode
from connection import post
from sprints import measureSprint
import drive
import speedometer

# Set true if not connected to car
running = False

# Enable all debug information
obd.logger.setLevel(obd.logging.DEBUG)

connection = None

speedo = None

# Connect to elm327 plug
try:
    connection = obd.OBD() # auto-connects to USB or RF port
except:
    print("Could not connect to ELM327 plug")

# Stop logging after connection made
obd.logger.removeHandler(obd.console_handler)

if connection != None and connection.is_connected() == True:
    running = True
elif mockMode == True:
    print("Running in MOCK MODE")
    running = True

if running:
    drive.startDrive()
    speedo = speedometer.Speedometer()

while running == True:
    speedo.speedoLoop(connection)
    measureSprint(connection)


"""
echo.py

contains echo() and echoa()
"""

import datetime
import error
import database

async def echo(message, *args):
    """
    echo()

    echos message
    """

    # check for arguments:
    if args:
        return f"`{message.author}:` {' '.join(args)}"

    raise error.ArgumentRequiredError

async def echoa(message, *args):
    """
    echoa()

    echos message anonymously
    """

    # get admins from database
    admins = database.get("admins")

    # check for priviledges
    if any([
        str(message.author.id) in admins,
        message.channel.permissions_for(message.author).administrator,
    ]):

        if args:
            database.write("echoa", str(message.id), string='\n'.join([
                f"{datetime.datetime.now()}",
                f"{message.guild.id}: {message.guild.name}",
                f"{message.channel.id}: {message.channel.name}",
                f"{message.author.id}: {message.author}",
                f"{' '.join(args)}",
            ]))
            return ' '.join(args)

        raise error.ArgumentRequiredError

    raise error.AuthorisationError


from Components import Object, Key, Block
from Managers import GOST, registerThread

import requests
from threading import Thread, Lock
from json import dumps, loads

def speak(procces_func):
    def wrapper(self, obj, data, where, resp, thread, other, check):
        if other is None:
            data = {"data": self.createMsg(data)}
        else:
            data = {"data": self.createMsg(data), "other": other}

        if thread:
            with registerThread(self.connection):
                response = None
                try:
                    response = requests.post("http://" + obj.IP + "/" + where,
                                        data=data)
                except requests.exceptions.RequestException as e:
                    self.alert("Connection error with object. " + str(e), 5, obj)
                    return
                except requests.exceptions.HTTPError as e:
                    self.alert("Connection error with object. " + str(e), 5, obj)
                    return

                lock = Lock()
                with lock:
                    print(response.text)
                    if response.status_code != 200:
                        self.alert("Status code error: %d" % response.status_code, 6, obj)
                        return

                    if check:
                        resp = obj.checkMsg(response.text)
                    else:
                        resp = response.text

                    return procces_func(self, obj, data, where, resp, thread, other, check)
        else:
            response = None
            try:
                response = requests.post("http://" + obj.IP + "/" + where,
                                         data=data)
            except requests.exceptions.RequestException as e:
                self.alert("Connection error with object. " + str(e), 5, obj)
                return
            except requests.exceptions.HTTPError as e:
                self.alert("Connection error with object. " + str(e), 5, obj)
                return

            print(response.text)
            if response.status_code != 200:
                self.alert("Status code error: %d" % response.status_code, 6, obj)
                return

            if check:
                resp = obj.checkMsg(response.text)
            else:
                resp = response.text

            return procces_func(self, obj, data, where, resp, thread, other, check)

    return wrapper

class Main(Object):
    """docstring for Main"""

    def __init__(self, connection, name):

        obj = connection.getComponent(Object, "\"Name\"='%s'" % name)
        if obj is None:
            raise Exception("No such object " + name)

        super().__init__(obj.IP, name, 0, obj.key, obj.working, obj.ref)

        self.prevBlock = None
        self.lastBlock = None
        self.connection = connection

    def firstInit(self):
        dbMgr = self.connection.dbMgr
        dbMgr.transaction()

        objects = self.connection.getComponents(Object)
        for key, val in objects.items():
            val.key = None
            if not self.connection.updateComponent(val):
                dbMgr.rollback()
                self.alert("Update error while firstInit", 2)
                return {}

        keys = self.connection.getComponents(Key)
        if keys is not None:
            for key in keys:
                key.obj = None
                key.block = None
                if not self.connection.updateComponent(key):
                    dbMgr.rollback()
                    self.alert("Update error while firstInit", 2)
                    return {}

                if not self.connection.deleteComponent(key):
                    dbMgr.rollback()
                    self.alert("Delete error while firstInit", 3)
                    return {}

        blocks = self.connection.getComponents(Block)
        if blocks is not None:
            for bid, val in blocks.items():
                if not self.connection.deleteComponent(val):
                    dbMgr.rollback()
                    self.alert("Delete error while firstInit", 3)
                    return {}

        del blocks
        del keys
        del objects

        gost = GOST()
        keys = gost.genKeys()

        blockID = gost.genID()
        block = Block(1, blockID)

        if self.connection.createComponent(block) is None:
            dbMgr.rollback()
            self.alert("Create error while firstInit", 1)
            return None

        sign = gost.createSignature(keys[1], keys[0])
        key = Key(keys[1], block, self, sign, sign, True)

        if self.connection.createComponent(key) is None:
            dbMgr.rollback()
            self.alert("Create error while firstInit", 1)
            return None

        key.privateKey = keys[0]

        self.lastBlock = block
        self.key = key
        if not self.connection.updateComponent(self):
            dbMgr.rollback()
            self.alert("Update error while firstInit", 2)
            return {}

        objects = self.connection.getComponents(Object, "\"Type\"=1 OR \"Type\"=2")

        result = {}

        for name, obj in objects.items():
            keys = gost.genKeys()

            sign = gost.createSignature(keys[1], keys[0])
            key = Key(keys[1], block, obj, sign, sign)

            if self.connection.createComponent(key) is None:
                dbMgr.rollback()
                self.alert("Create error while firstInit", 1)
                return {}

            obj.working = True
            obj.key = key
            if not self.connection.updateComponent(obj):
                self.alert("Update error while firstInit", 2)
                return {}

            result[name] = keys

        if len(result) == 0:
            dbMgr.rollback()
            self.alert("No objects while firstInit", 4)
            return {}

        dbMgr.commit()

        config = self.connection.getSettings()
        config["params"]["nprvk"] = self.key.privateKey
        config["params"]["prvk"] = self.key.privateKey
        # config["params"]["init"] = '0'
        self.connection.setSettings(config)

        result[self.name] = (self.key.keyHash, self.key.publicKey)

        return result

    def requestNewKeys(self):
        if not self.lastBlock:
            print("No last block")
            return False

        dbMgr = self.connection.dbMgr
        dbMgr.transaction()

        gost = GOST()
        keys = gost.genKeys()

        blockID = gost.genID()
        block = Block(self.lastBlock.blockNumber + 1, blockID)

        if self.connection.createComponent(block) is None:
            dbMgr.rollback()
            self.alert("Create error while requestNewKeys", 1)
            return False

        key = Key(keys[1], block, self, gost.createSignature(keys[1], keys[0]), gost.createSignature(keys[1], self.key.privateKey))
        key.privateKey = keys[0]
        key.recived = True

        if self.connection.createComponent(key) is None:
            dbMgr.rollback()
            self.alert("Create error while requestNewKeys", 1)
            return False

        self.prevBlock = self.lastBlock
        self.lastBlock = block

        objects = self.connection.getComponents(Object, "(\"Type\"=1 OR \"Type\"=2) AND \"Working\"=true")

        # if len(objects) == 0:
        #     dbMgr.rollback()
        #     self.alert("No objects while requestNewKeys", 4)
        #     return False

        threads = []

        for name, obj in objects.items():
            thr = Thread(target=self.__shareRequestForSlavers, args=(obj, {}, "requestNewKey", None, True, None, True))
            threads.append(thr)
            thr.start()

        for thr in threads:
            thr.join()

        block.blockHash = gost.createSignature(block.blockWithKeys(self.connection, True), self.key.privateKey)
        if not self.connection.updateComponent(block):
            self.alert("Update error while requestNewKeys", 2)
            dbMgr.rollback()
            return False

        dbMgr.commit()

        config = self.connection.getSettings()
        config["params"]["nprvk"] = keys[0]
        self.connection.setSettings(config)

        return True

    def shareBlock(self):
        if not self.lastBlock:
            raise Exception("No last block")

        dbMgr = self.connection.dbMgr
        dbMgr.transaction()

        block = self.lastBlock

        objects = self.connection.getComponents(Object, "(\"Type\"=1 OR \"Type\"=2) AND \"Working\"=true")
        # if len(objects) == 0:
        #     dbMgr.rollback()
        #     self.alert("No objects while shareBlock", 4)
        #     return False

        threads = []
        for name, obj in objects.items():
            thr = Thread(target=self.__shareBlockForSlavers, args=(obj, {"block": block.blockWithKeys(self.connection),
                                                                         "hash": block.blockHash}, "updateBlock", None, True, None, True))
            threads.append(thr)
            thr.start()

        for thr in threads:
            thr.join()

        if self.prevBlock is not None:
            self.prevBlock.current = False
            if not self.connection.updateComponent(self.prevBlock):
                dbMgr.rollback()
                self.alert("Update error while shareBlock", 2)
                return False

        block.current = True
        if not self.connection.updateComponent(block):
            dbMgr.rollback()
            self.alert("Update error while shareBlock", 2)
            return False

        dbMgr.commit()

        config = self.connection.getSettings()
        config["params"]["prvk"] = config["params"]["nprvk"]
        config["params"]["nprvk"] = ''
        self.connection.setSettings(config)

        self.key.privateKey = config["params"]["prvk"]

        return True

    @speak
    def __shareBlockForSlavers(self, obj, data, where, resp, thread, other, check):
        if resp is None:
            self.alert("Share block: unsuccessful. Warning! Attempt treat system! Probably MITM", 8, obj)
            return
        elif resp == "Error":
            self.alert("Share block: unsuccessful. Something went wrong.", 7, obj)
            return

        self.alert("Share block: successful.", 0, obj)

        key = self.connection.getComponent(Key, "\"Object\"={} AND \"Block\"={}".format(obj.ref.id(), self.lastBlock.ref.id()))
        key.recived = True
        obj.key = key

        if not self.connection.updateComponent(key) or not self.connection.updateComponent(obj):
            self.alert("Update error while shareBlock", 2)
            return

    @speak
    def __shareRequestForSlavers(self, obj, data, where, resp, thread, other, check):
        if resp is None:
            self.alert("Generation keys: unsuccessful. Warning! Attempt treat system! Probably MITM", 8, obj)
            return
        elif resp == "Error":
            self.alert("Generation keys: unsuccessful. Something went wrong.", 7, obj)
            return

        try:
            gost = GOST()
            if gost.checkSignature(resp["NK"], resp["HH"], resp["NK"]):
                key = Key(resp["NK"], self.lastBlock, obj, resp["HH"], resp["OH"])

                self.connection.createComponent(key)

                self.alert("Generation keys: successful.", 0, obj)
            else:
                self.alert("Generation keys: unsuccessful. Not working key!", 7, obj)
        except KeyError:
            self.alert("Generation keys: unsuccessful. Critical! Key Compromise!", 9, obj)

class Slave(Object):
    """docstring for Slave"""

    def __init__(self, connection, name):
        obj = connection.getComponent(Object, "\"Name\"='%s'" % name)

        if obj is None:
            raise Exception("No such object " + name)

        super().__init__(obj.IP, name, 1, obj.key, obj.working, obj.ref)

        self.connection = connection

    def initKey(self, prvKey, mainKey):
        dbMgr = self.connection.dbMgr
        dbMgr.transaction()

        objects = self.connection.getComponents(Object)
        for key, val in objects.items():
            val.key = None
            if not self.connection.updateComponent(val):
                dbMgr.rollback()
                self.alert("Update error while initKey", 2)
                return False

        keys = self.connection.getComponents(Key)
        if keys is not None:
            for key in keys:
                key.obj = None
                key.block = None
                if not self.connection.updateComponent(key):
                    dbMgr.rollback()
                    self.alert("Update error while initKey", 2)
                    return False
                if not self.connection.deleteComponent(key):
                    dbMgr.rollback()
                    self.alert("Delete error while initKey", 3)
                    return False

        blocks = self.connection.getComponents(Block)
        if blocks is not None:
            for bid, val in blocks.items():
                if not self.connection.deleteComponent(val):
                    dbMgr.rollback()
                    self.alert("Delete error while initKey", 3)
                    return False

        del blocks
        del keys
        del objects

        self.key.privateKey = prvKey

        main = self.mainObject()
        key = Key(mainKey[1], None, main, mainKey[0], mainKey[0], True)

        if self.connection.createComponent(key) is None:
            dbMgr.rollback()
            self.alert("Create error while initKey", 1)
            return False

        main.key = key

        if not self.connection.updateComponent(main):
            dbMgr.rollback()
            self.alert("Update error while initKey", 2)
            return False

        dbMgr.commit()

        config = self.connection.getSettings()
        config["params"]["nprvk"] = prvKey
        config["params"]["prvk"] = prvKey
        # config["params"]["init"] = '0'
        self.connection.setSettings(config)

        return True

    def mainObject(self):
        return self.connection.getComponent(Object, "\"Type\"=0")

    @speak
    def requestBlock(self, obj, data, where, resp, thread, other, check):
        if resp == "Error":
            self.alert("Request block: unsuccessful. Something went wrong.", 7, obj)
            return False

        try:
            gost = GOST()
            main = self.mainObject()
            number = 1
            resp = loads(resp)
            n = len(resp)
            # print(n)
            if n > 0:
                prevBlock = self.connection.getComponent(Block, "\"Current\"=true")
                prevBlock.current = False
                if not self.connection.updateComponent(prevBlock):
                    self.alert("Update error while requestBlock", 2)
                    return False

            dbMgr = self.connection.dbMgr
            dbMgr.transaction()

            for block in resp:
                blockHash = block[1]
                block = block[0]

                blockString = dumps(block, sort_keys=True)
                print(main.key.publicKey)
                if not gost.checkSignature(blockString, blockHash, main.key.publicKey):
                    dbMgr.rollback()
                    self.alert("Request block: unsuccessful. Warning! Attempt treat system! Probably MITM CC", 8)
                    return False

                blockdb = Block(block["blockNumber"], block["id"], blockHash, True if number == n else False, block["createTime"])
                if not self.connection.createComponent(blockdb):
                    dbMgr.rollback()
                    self.alert("Create error while requestBlock", 1)
                    return False

                for ip, key in block["keys"].items():
                    oldObj = self.connection.getComponent(Object, "\"IP\"='{}'".format(ip))
                    if not gost.checkSignature(key["key"], key["oldHash"], oldObj.key.publicKey):
                        dbMgr.rollback()
                        self.alert("Request block: unsuccessful. Check signature", 7)
                        return False

                    newKey = Key(key["key"], blockdb, oldObj, key["hash"], key["oldHash"], True)
                    if not self.connection.createComponent(newKey):
                        dbMgr.rollback()
                        self.alert("Create error while requestBlock", 1)
                        return False

                    oldObj.key = newKey
                    if not self.connection.updateComponent(oldObj):
                        dbMgr.rollback()
                        self.alert("Update error while requestBlock", 2)
                        return False

                    if oldObj.name == main.name:
                        main = oldObj

                number += 1

            dbMgr.commit()
        except KeyError:
            self.alert("Request block: unsuccessful. Warning! Attempt treat system! Probably MITM", 9)

        return True

    def turn(self, on):
        objects = self.connection.getComponents(Object, "\"Working\"=true")

        if len(objects) == 0:
            self.alert("No objects while turn", 4)
            return False

        threads = []
        for name, obj in objects.items():
            if name == self.name:
                continue

            thr = Thread(target=self.__shareSelfState, args=(obj, {"turn": on}, "objectTurned", None, True, self.IP, False))
            threads.append(thr)
            thr.start()

        for thr in threads:
            thr.join()

        self.working = on
        if not self.connection.updateComponent(self):
            self.alert("Update error while turn", 2)
            return False

        return True

    def generateNewKeys(self, form):
        main = self.mainObject()

        try:
            resp = main.checkMsg(form["data"])
            if resp is None:
                self.alert("Generation keys: unsuccessful. Warning! Attempt treat system!", 8)
                return "Error"
        except KeyError:
            self.alert("Generation keys: unsuccessful. Warning! Attempt treat system!", 9)
            return "Error"

        gost = GOST()
        keys = gost.genKeys()
        sign = gost.createSignature(keys[1], keys[0])
        signOld = gost.createSignature(keys[1], self.key.privateKey)

        config = self.connection.getSettings()
        config["params"]["nprvk"] = keys[0]
        self.connection.setSettings(config)

        return self.createMsg({"NK": keys[1], "HH": sign, "OH": signOld})

    def updateBlock(self, form):
        main = self.mainObject()

        resp = None
        gost = GOST()

        try:
            resp = main.checkMsg(form["data"])
            if resp is None:
                self.alert("Update block: unsuccessful. Warning! Attempt treat system! CS", 8)
                return "Error"

            blockHash = resp["hash"]
            resp = resp["block"]

            key = resp["keys"][self.IP]

            if not gost.checkSignature(key["key"], key["hash"], key["key"]):
                self.alert("Update block: unsuccessful. Unable checkSignature! Attempt treat system!", 8)
                return "Error"

            dbMgr = self.connection.dbMgr
            dbMgr.transaction()

            block = Block(resp["blockNumber"], resp["id"], blockHash, True, resp["createTime"])
            if self.connection.createComponent(block) is None:
                dbMgr.rollback()
                self.alert("Create error while updateBlock", 1)
                return

            if int(resp["blockNumber"]) == 1:
                main.key.block = block
                if not self.connection.updateComponent(main.key):
                    dbMgr.rollback()
                    self.alert("Update error while updateBlock", 2)
                    return
            else:
                main.key.block.current = False
                if not self.connection.updateComponent(main.key.block):
                    dbMgr.rollback()
                    self.alert("Update error while updateBlock", 2)
                    return

            for IP, keyPack in resp["keys"].items():
                if IP == self.IP or (IP == main.IP and int(resp["blockNumber"]) == 1):
                    continue

                obj = self.connection.getComponent(Object, "\"IP\"='{}'".format(IP))
                key = Key(keyPack["key"], block, obj, keyPack["hash"], keyPack["oldHash"], True)
                if self.connection.createComponent(key) is None:
                    dbMgr.rollback()
                    self.alert("Create error while updateBlock", 1)
                    return

                obj.key = key
                if not self.connection.updateComponent(obj):
                    dbMgr.rollback()
                    self.alert("Update error while updateBlock", 2)
                    return

            dbMgr.commit()
        except KeyError:
            self.alert("Update block: unsuccessful. Warning! Attempt treat system! KE", 9)
            return "Error"

        msg = self.createMsg("OK")

        config = self.connection.getSettings()
        self.key.privateKey = config["params"]["nprvk"]
        config["params"]["prvk"] = config["params"]["nprvk"]
        config["params"]["nprvk"] = ''
        self.connection.setSettings(config)

        return msg

    @speak
    def __shareSelfState(self, obj, data, where, resp, thread, other, check):
        pass

if __name__ == "__main__":
    pass


# Global Imports
import random # Should be "from random import choice", but variable name consistency and conflicts
from os import system

# Init Board as List Casted From String for Readability and Consistency
board = list("123456789")

"""Fetches and Validates User Input"""
def get_choice():
    # Get Player Input
    choice = input("Enter a position 1-9:\n")
    # Check if input is valid
    while True:
        if choice in board:
            # If valid, return choice
            return choice
        # If invalid, inform player and re-prompt
        print("Invalid Position.")
        choice = get_choice()

"""Prints and Styles the Board"""
def print_board():
    # Top Line
    print(" _____")
    # Rows
    print(f"|{board[0]}|{board[1]}|{board[2]}|")
    print(f"|{board[3]}|{board[4]}|{board[5]}|")
    print(f"|{board[6]}|{board[7]}|{board[8]}|")
    # Bottom Line
    print(" ‾‾‾‾‾")

"""Checks For a Win on the Board"""
def check_win():
    # Check Horizontal
    for i in range(0, 9, 3):
        if board[0 + i] == board[1 + i] == board[2 + i]:
            return True
    # Check Vertical
    for i in range(3):
        if board[0 + i] == board[3 + i] == board[6 + i]:
            return True
    # Check Diagonal
    if board[0] == board[4] == board[8] or board[2] == board[4] == board[6]:
        return True
    # Return False if no win
    return False

"""Main Function"""
def main():
    # Random Turn
    player = random.choice(["X", "O"])
    # Init Turn Count
    turn = 9
    # Main Game Loop
    while True:
        # Inform Player of Turn
        print(f"{player}'s turn!")
        # Draw Board
        print_board()
        # Get Player Input
        choice = get_choice()
        # Update Board
        board[int(choice) - 1] = player
        # Decrement Turn Count
        turn -= 1
        # Check for Win/Draw
        if check_win():
            # Clear Console, Inform Player of Win, Break Loop
            system("clear")
            print(f"{player} wins!")
            break
        elif turn < 1:
            # Clear Console, Inform Player of Draw, Break Loop
            system("clear")
            print("Draw!")
            break
        # Flip Player
        player = "X" if player == "O" else "O"
        # Clear Console Window
        system("clear")
    # Print Board
    print_board()
    # Inform User of Game End
    print("Game Over.")

# Inform Runner that main.py is the Main File and Only Run on Direct Invocation
if __name__ == "__main__":
    # Main Function
    main()


import pytest

from openclean.data.types import Column
from openclean.data.schema import select_clause

def test_select_clause_without_duplicates(employees):
    """Test the select clause method that extracts a list of column names and
    their index positions frm a data frame schema.
    """
    colnames, colidxs = select_clause(employees.columns, 'Name')
    assert colnames == ['Name']
    assert colidxs == [0]
    colnames, colidxs = select_clause(employees.columns, 'Age')
    assert colnames == ['Age']
    assert colidxs == [1]
    colnames, colidxs = select_clause(employees.columns, ['Salary', 'Age'])
    assert colnames == ['Salary', 'Age']
    assert colidxs == [2, 1]
    colnames, colidxs = select_clause(employees.columns, employees.columns)
    assert colnames == ['Name', 'Age', 'Salary']
    assert colidxs == [0, 1, 2]

def test_select_clause_with_duplicates(dupcols):
    """Test the select clause method for a data frame schema with duplicate
    column names.
    """
    # -- Use only the columns name (returns the first 'A' column) -------------
    columns = ['Name', 'A']
    colnames, colidxs = select_clause(dupcols.columns, columns)
    assert colnames == ['Name', 'A']
    assert colidxs == [0, 1]
    # -- Use column objects (returns the second 'A' column) -------------------
    columns = [dupcols.columns[0], dupcols.columns[2]]
    colnames, colidxs = select_clause(dupcols.columns, columns)
    assert colnames == ['Name', 'A']
    assert colidxs == [0, 2]
    # -- Error if the column index is out of range ----------------------------
    columns = [dupcols.columns[0], Column(colid=10, name='A', colidx=20)]
    with pytest.raises(ValueError):
        select_clause(dupcols.columns, columns)
    # -- Error if the column index and the name don't match -------------------
    columns = [dupcols.columns[0], Column(colid=10, name='B', colidx=2)]
    with pytest.raises(ValueError):
        select_clause(dupcols.columns, columns)


# Exercise 5: Count all letters, digits, and special symbols from a given string

# Given:
# str1 = "P@#yn26at^&i5ve"

# Expected Outcome:
# Total counts of chars, digits, and symbols
# Chars = 8
# Digits = 3
# Symbol = 4

str1 = "P@#yn26at^&i5ve"

chars = []
digits = []
symbol = []

for i in str1:
    if i.isalpha():
        chars.append(i)
    elif i.isdigit():
        digits.append(i)
    else:
        symbol.append(i)

print('No. of Alphabet: ', len(chars))
print('No. of Digits: ', len(digits))
print('No. of Symbols: ', len(symbol))


def calculate_v(array, judge):
    if len(array) == 1:
        return array[0]
    else:
        new_arr = []
        if judge:
            for ii in range(0, len(array)-1, 2):
                new_arr.append(array[ii] | array[ii+1])
            judge = False
            return calculate_v(new_arr, judge)
        else:
            for ii in range(0, len(array)-1, 2):
                new_arr.append(array[ii] ^ array[ii+1])
            judge = True
            return calculate_v(new_arr, judge)

inp = input().split(" ")
n, m = int(inp[0]), int(inp[1])
lent = pow(2, n)
arr = [int(x) for x in input().split(" ")]
for i in range(m):
    inp = input().split(" ")
    p, b = int(inp[0]), int(inp[1])
    arr[p-1] = b
    res = calculate_v(arr, True)
    print(res)


import fixapp
import argparse
import logging
import quickfix as fix
from fixapp import (FixDecoder, parse_fix_options, print0,printv,printvv,printvvv)
from fixapp import BaseFixClient as FixClient
import datetime as dt
import time
import random
# from utils import *
class Session(object):
    def __init__(self,args):
        self.args         = args
        self.config_file  = args.config
        self.settings     = fix.SessionSettings(self.config_file)
        self.app          = FixClient()
        self.storeFactory = fix.FileStoreFactory(self.settings)
        self.logFactory   = fix.FileLogFactory(self.settings)
        self.initiator    = fix.SocketInitiator(self.app,self.storeFactory,self.settings,self.logFactory)

def trading_vol(order_dict):
    vol_dict={'MSFT':0,'AAPL':0,'BAC':0}
    list_id=list(order_dict)
    for id in list_id:
        vol_dict[order_dict[id][55]]+=int(order_dict[id][38])
    print("total trading volume",vol_dict)

# setting_dict={'SenderCompID':"OPS_CANDIDATE_3_8639",'TargetCompID':"DTL",'SocketConnectPort':5100,'SocketConnectHost':"fix.dytechlab.com"}
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='FIX Client')
    parser.add_argument('--config', default='configs/fix/DTL.cfg',type=str, help='Name of configuration file')
    args = parser.parse_args()

    #-==========================================================================

    logging.basicConfig(level=logging.DEBUG,format='%(message)s')#logging.ERROR,logging.WARNING,logging.INFO, logging.DEBUG
    random_list=[0,1,2,3,4,5,6,7,8,9,10,11]
    try:
        app = Session(args)
        app.initiator.start()
        # reset sequence when logon
        time.sleep(3)
        # app.app.resetSeqLogOn()

        #### REQUIREMENT 9^th

        _, o1 = parse_fix_options("  -54 1 -55 MSFT -40 1 -44 1.9 -38 10") # Limit order
        _, o2 = parse_fix_options("  -54 2 -55 MSFT -40 2 -44 1.9 -38 10") # Limit order
        _, o3 = parse_fix_options("  -54 1 -55 MSFT -40 1  -38 10") #Market order, no price
        _, o4 = parse_fix_options("  -54 2 -55 MSFT -40 1  -38 10") #Market order, no price

        _, o5 = parse_fix_options("  -54 1 -55 AAPL -40 1 -44 1.9 -38 10") # Limit order
        _, o6 = parse_fix_options("  -54 2 -55 AAPL -40 2 -44 1.9 -38 10") # Limit order
        _, o7 = parse_fix_options("  -54 1 -55 AAPL -40 1  -38 10") #Market order, no price
        _, o8 = parse_fix_options("  -54 2 -55 AAPL -40 1  -38 10") #Market order, no price

        _, o9 = parse_fix_options("  -54 1 -55 AAPL -40 1 -44 1.9 -38 10") # Limit order
        _, o10 = parse_fix_options("  -54 2 -55 AAPL -40 2 -44 1.9 -38 10") # Limit order
        _, o11 = parse_fix_options("  -54 1 -55 AAPL -40 1  -38 10") #Market order, no price
        _, o12 = parse_fix_options("  -54 2 -55 AAPL -40 1  -38 10") #Market order, no price

        # _, sell_options2 = parse_fix_options("  -54 2 -55 BAC -40 1  -38 10")#Short, Market order, no price

        # for SHORT order, change tag 54 to 5, but I won't list here to calculate PnL in 10^th requirement
        # for simple, I only list these order above, not list all.
        # list_options=[buy_options1,buy_options2,sell_options1,sell_options2]
        list_options=[o1,o2,o3,o4,o5,o6,o7,o8,o9,o10,o11,o12]
        for i in range(1000):
            random_option=list_options[random.choice(random_list)]
            app.app.OneOrder(**random_option)
            # app.app.buy(**random_option)
            # app.app.sell(**sell_options)
            time.sleep(0.25) # 5min=300sec, mean that we need to successfully sent each order in about 0.3sec
            if random.choice(random_list)==1:
                app.app.cancel_order(**random_option)

        time.sleep(1)
        #### REQUIREMENT 10^th
        transaction_list=app.app.transaction_list
        # trans_dict={'MSFT':[[],[]],'AAPL':[[None,None],[None,None]],'BAC':[[None,None],[None,None]]}
        trans_dict={'MSFT':[[],[]],'AAPL':[[],[]],'BAC':[[],[]]}
        # for a symbol:
            # [[all buy transaction],[all sell transaction]],total bought vol, total sold vol, average
# each symbol contain [total bought volume, total sold volume, bought trade vol, sold trade vol ]

        for trans in transaction_list:
            trans_dict[trans['Symbol']][int(trans['Side'])-1].append([trans['LastShares'],trans['LastPx']])
        import numpy as np

        PnL_all=0
        trading_vol_in_USD=0
        # print(transaction_list)
        for symbol in ['MSFT','AAPL','BAC']:
            PnL=0.0
            buy_trans=np.array(trans_dict[symbol][0])
            if len(buy_trans)==0:
                total_vol_buy=0.0
                total_buy_value=0.0
                avg_buy_price=0.0
            else:
                total_vol_buy=np.sum(buy_trans[:,0],axis=0)
                total_buy_value=buy_trans[:,0]@buy_trans[:,1] #multily by numpy arr will faster than seperated multiply in for loop
                avg_buy_price=total_buy_value/total_vol_buy #this number is also VWAP for buy side
                print("buy average price of {}: {} USD".format(symbol,avg_buy_price))
            sell_trans=np.array(trans_dict[symbol][1])
            if len(sell_trans)==0:
                total_vol_sell=0.0
                total_sell_value=0.0
                avg_sell_price=0.0
            else:
                total_vol_sell=np.sum(sell_trans[:,0],axis=0)
                total_sell_value=sell_trans[:,0]@sell_trans[:,1]
                avg_sell_price=total_sell_value/total_vol_sell#this number is also VWAP for sell side
                print("sell average price of {}: {} USD".format(symbol,avg_sell_price))
            # import pdb;pdb.set_trace()
            PnL +=(avg_sell_price-avg_buy_price)*min(total_buy_value,total_sell_value)
            PnL_all+=PnL
            # I use absolute value here because these orders are random, so we can't assure that the buy vol alway greater than the sell vol
            #vwap of the remaining stock
            # vwap=(total_sell_value)
            trading_vol_in_USD+=total_buy_value+total_sell_value
            print("total trading volume of {}:{} USD".format(symbol,total_buy_value+total_sell_value))
            if PnL>=0:
                print("profit of trading on {}: {} USD".format(symbol,PnL))
            else:
                print("loss of trading on {}: {} USD".format(symbol,-1*PnL))

            # trading_vol_in_USD+=float(trans['LastPx'])*float(trans['LastShares'])

        print("total trading volume of this session:{} USD".format(trading_vol_in_USD))
        if PnL_all>=0:
            print("profit of trading on {}: {} USD".format(symbol,PnL_all))
        else:
            print("loss of trading on {}: {} USD".format(symbol,-1*PnL_all))
        app.initiator.stop()

    except (fix.ConfigError , fix.RuntimeError) as e:
        print(e)


class Solution:
    def capitalizeTitle2(self, title: str) -> str:
        def upper(s: str):
            ret = s
            if 'a' < s and s < 'z':
                ret = chr(ord(s) - ord('a') + ord('A'))
            return ret
        def lower(s: str):
            ret = s
            if 'A' < s and s < 'Z':
                ret = chr(ord(s) - ord('A') + ord('a'))
            return ret
        title = [i for i in title]
        i = 0
        j = 0
        n = len(title)
        while i < n and j < n:
            while i < n and title[i] == ' ':
                i += 1
            j = i
            while j < n and title[j] != ' ':
                j += 1

            if j - i <= 2:
                for k in range(i, j):
                    title[k] = lower(title[k])
            else:
                title[i] = upper(title[i])
                for k in range(i+1, j):
                    title[k] = lower(title[k])
            i = j

        return ''.join(title)

    def capitalizeTitle(self, title: str) -> str:
        word_num = 0
        ans = []
        for i in range(len(title)):
            if title[i] == ' ':
                word_num = 0
            else:
                word_num += 1
                if word_num == 3:
                    ans[i - 2] = ans[i - 2].upper()
            ans.append(title[i].lower())
        return ''.join(ans)

if __name__ == '__main__':
    print(Solution().capitalizeTitle("First leTTeR of EACH Word"))


# -*- coding: utf-8 -*-
from django.shortcuts import render
from django.shortcuts import redirect
from django.http import HttpResponse, JsonResponse
import json
#IMPORTAMOS LA CONEXION PARA QUERY PERSONALIZADO
from django.db import connection, transaction
#dictfetchall
from principal.views import dictfetchall, notificacion_director
#models
from personal.models import Personal
from auditoria.models import Auditorias
from sac.models import Sac, PlanAccion
from areas.models import Procesos
from documentos.models import Documento, Revision

#importamos el form documento
from documentos.forms import DocumentacionForm
from procesos.forms import ReemplazarForm
from documentos.models import Documento, Revision
from normas.models import Normas

# Create your views here.
@notificacion_director
def jefe(request):

    #validar si existe usuario logeado
    if 'nombreUsuario' not in request.session:

        return render(request, 'seguridad/login.html', {})

    else:

        cursor = connection.cursor()
        query = "SELECT auditoria_auditorias.numero_auditoria FROM  auditoria_auditorias GROUP BY auditoria_auditorias.numero_auditoria "
        cursor.execute(query)
        rows = dictfetchall(cursor)

        #CONVIERTE  QuerySet  a list object
        num_auditorias_list= list(rows)

        context={
            'personal':Personal.objects.values('id', 'nombre').filter(estado=1),
            'auditorias':num_auditorias_list,
            'jefes':Personal.objects.values('id', 'nombre').all().filter(estado=1),
            'sacs':Sac.objects.values('id').all().filter(estado_cabecera=1),
        }

        return render(request, 'jefeArea/jefe.html', context)

def updateSacJefe(request):

    #validar si existe usuario logeado
    if 'nombreUsuario' not in request.session:

        return render(request, 'seguridad/login.html', {})

    else:

        if request.method == 'POST' and request.is_ajax():

            id_sac = request.POST.get('id_sac')
            descripcion_correcion = request.POST.get('descripcion_correcion')
            analisis_causa= request.POST.get('analisis_causa')

            if descripcion_correcion:

                descripcion = descripcion_correcion
            else:

                descripcion = None

            Sac.objects.filter(pk=id_sac).update(
                descripcion_correcion=descripcion,
                analisis_causa=analisis_causa,
                estado_cabecera = 3
            )
            if 'notificacionJefe' in request.session:
                del request.session['notificacionJefe']

            data = {
                'resultado':'ok_update',
                'mensaje': 'Datos Actualizados Correctamente !!',
            }
            return HttpResponse(json.dumps(data), content_type="application/json")

def insertPlanAccion(request):

    if 'nombreUsuario' not in request.session:

        return render(request, 'seguridad/login.html', {})

    else:

        if request.method == 'POST' and request.is_ajax():

            planes = request.POST.get('data')
            id_sac = request.POST.get('id_sac')

            import json
            planes_json = json.loads(planes)

            for plan in planes_json['gridData']:
                with transaction.atomic():
                    plan_accion = PlanAccion(
                        detalle_plan_accion = plan['detalle'],
                        plazo_plan_accion = plan['plazo'],
                        responsable_plan_accion_id = plan['responsable'],
                        sac_id = plan['id_sac'],
                        recursoHumano = plan['recursoHumano'],
                        detalleRecursoHumano = plan['detalleRecursoHumano'],
                        recursoTecnico = plan['recursoTecnico'],
                        detalleRecursoTecnico = plan['detalleRecursoTecnico'],
                        recursoFinanciero = plan['recursoFinanciero'],
                        detalleRecursoFinanciero = plan['detalleRecursoFinanciero']
                    )
                    plan_accion.save()

            Sac.objects.filter(pk=id_sac).update(
                sac_jefe = None
            )
            if 'notificacionJefe' in request.session:
                del request.session['notificacionJefe']

            json = {
                'resultado':'ok_insert',
                'mensaje': 'Datos Grabados Correctamente !!',
            }
            return JsonResponse(json, safe=False)

def updatePlan(request):

    if 'nombreUsuario' not in request.session:

        return render(request, 'seguridad/login.html', {})

    else:
        if request.method == 'POST' and request.is_ajax():

            id_plan = request.POST.get('id_plan')
            plan = request.POST.get('plan')
            plazo = request.POST.get('plazo')
            responsable_id = request.POST.get('responsable_id')

            PlanAccion.objects.filter(pk=id_plan).update(
                detalle_plan_accion=plan,
                plazo_plan_accion=plazo,
                responsable_plan_accion_id = responsable_id
            )

            json = {
                'resultado':'ok_update',
                'mensaje': 'Datos Grabados Correctamente !!',
            }
            return JsonResponse(json, safe=False)

def deletePlanAccion(request):

    if 'nombreUsuario' not in request.session:

        return render(request, 'seguridad/login.html', {})

    else:
        if request.method == 'POST' and request.is_ajax():

            id_plan = request.POST.get('id_plan')

            #eliminar plan
            PlanAccion.objects.filter(pk=id_plan).delete()
            #resultado
            json = {
                'resultado':'ok_delete',
                'mensaje': 'Datos Eliminados Correctamente !!',
            }
            return JsonResponse(json, safe=False)

def selectPlanAccion(request):

    if 'nombreUsuario' not in request.session:

        return render(request, 'seguridad/login.html', {})

    else:

            id_sac = request.GET['id_sac']

            cursor = connection.cursor()
            query = " SELECT sac_planaccion.detalle_plan_accion, sac_planaccion.plazo_plan_accion,  sac_planaccion.responsable_plan_accion_id "
            query = query + " FROM sac_planaccion "
            query = query + " WHERE sac_planaccion.sac_id=%s"
            params=[id_sac]

            cursor.execute(query, params)

            rows = dictfetchall(cursor)

            from sac.views import json_serial
            return HttpResponse(json.dumps(rows,  default=json_serial), content_type="application/json")

def selectPlanColab(request):

    if 'nombreUsuario' not in request.session:

        return render(request, 'seguridad/login.html', {})

    else:

        if request.method == 'POST' and request.is_ajax():

            id_plan = request.POST.get('id_plan')

            cursor = connection.cursor()
            query = " SELECT * "
            query = query + " FROM sac_planaccion "
            query = query + " WHERE sac_planaccion.id=%s"
            params=[id_plan]

            cursor.execute(query, params)

            rows = dictfetchall(cursor)

            from sac.views import json_serial
            return HttpResponse(json.dumps(rows,  default=json_serial), content_type="application/json")

@notificacion_director
def adminJefeDoc(request):

    """
    LISTADO DE DIRECTORIO POR ID USUARIO
    Y PROCESO VINCULADO
    """
    if 'nombreUsuario' not in request.session:

        return render(request, 'seguridad/login.html', {})

    else:

        cursor = connection.cursor()
        query = " SELECT DISTINCT areas_areas.area AS proceso "
        query = query + " FROM areas_area_proceso "
        query = query + " LEFT JOIN areas_areas ON areas_area_proceso.area_id = areas_areas.id  "
        #query = query + " LEFT JOIN areas_personal ON areas_area_proceso.id = areas_personal.procedimiento_id "
        query = query + " WHERE areas_area_proceso.personal_id =%s "
        params=[request.session['idUsuario']]
        cursor.execute(query, params)

        rows_directorios = dictfetchall(cursor)

        alldirectorys = []
        import os
        for directorios in rows_directorios:
            for root, dirs, files in os.walk('media/gestionDocumental'):
                for directory in dirs:
                    if directory == directorios['proceso']:

                        element = {}
                        element['directorio'] =  directory
                        element['ruta_absoluta'] = root+'/'+directory
                        alldirectorys.append(element)

        context={
            'archivos_list': alldirectorys,
            'documentoForm':DocumentacionForm,
            'reemplazarForm':ReemplazarForm
        }
        return render(request, 'jefeArea/directorios.html', context)

@notificacion_director
def estadoDocJefe(request):

    #validar si existe usuario logeado
    if 'nombreUsuario' not in request.session:

        #return render(request, 'seguridad/login.html', {})
        return redirect('login')
    else:

        context={
        }
        return render(request, 'jefeArea/estadoDocumentacion.html', context)

def updateDocJefe(request):

    #validar si existe usuario logeado
    if 'nombreUsuario' not in request.session:

        #return render(request, 'seguridad/login.html', {})
        return redirect('login')
    else:

        id_revision = request.POST.get('id_revision')
        id_documento = request.POST.get('id_documento')
        #estado 2=observacion 3=aprobado
        estado = request.POST.get('estado_documento')

        import datetime
        fecha_actual = datetime.datetime.now().strftime ("%Y-%m-%d")

        #existe observacion
        if estado == '2':

            observacion = request.POST.get('observaciones_documento')
        else:
            observacion = None

        Documento.objects.filter(pk=id_documento).update(
            estado = estado
        )

        Revision.objects.filter(pk=id_revision).update(
            fec_rev_director = fecha_actual,
            estado_rev_director = estado,
            observacion_rev_director = observacion
        )
        #borrar alerta
        if  'notificacionDocPorRevisar' in request.session  :
            del request.session['notificacionDocPorRevisar']

        return redirect('estadoDocJefe')

def selectNotLider(request):
        # validar si existe usuario logeado
    if 'nombreUsuario' not in request.session:

        # return render(request, 'seguridad/login.html', {})
        return redirect('login')

    else:
        if request.method == "POST" and request.is_ajax():

            cursor = connection.cursor()
            query = " SELECT DISTINCT areas_procesos.proceso, areas_procesos.estado_colaborador, areas_procesos.estado_encargado, "
            query = query + " areas_procesos.observaciones_encargado, areas_procesos.estado_lider, areas_procesos.observaciones_lider, "
            query = query + " areas_procesos.estado_admin "
            query = query + " FROM areas_procesos "
            query = query + " LEFT JOIN areas_area_proceso ON areas_procesos.id = areas_area_proceso.proceso_id "
            query = query + " WHERE areas_procesos.estado_encargado = 4"
            query = query + " AND areas_area_proceso.personal_id =%s "
            params=[request.session['idUsuario']]

            cursor.execute(query, params)

            rows=dictfetchall(cursor)
            list_rows = list(rows)

            return JsonResponse(list_rows, safe=False)

def GridDocumentacionDirector(request):

    # validar si existe usuario logeado
    if 'nombreUsuario' not in request.session:

        # return render(request, 'seguridad/login.html', {})
        return redirect('login')

    else:

        cursor = connection.cursor()
        query = " SELECT DISTINCT documentos_documento.id AS id_documento, documentos_documento.path, documentos_documento.descripcion, "
        query = query + " documentos_documento.version, documentos_documento.estado, documentos_documento.fec_subido, "
        query = query + " documentos_documento.nombre, areas_areas.area AS proceso,  areas_procesos.proceso AS procedimiento, "
        query = query + " personal_personal.nombre AS nombre_responsable, documentos_documento.procedimiento_id "
        query = query + " FROM documentos_documento "
        query = query + " LEFT JOIN areas_areas ON documentos_documento.proceso_id = areas_areas.id "
        query = query + " LEFT JOIN areas_procesos ON documentos_documento.procedimiento_id = areas_procesos.id "
        query = query + " LEFT JOIN personal_personal ON documentos_documento.subido_por_id = personal_personal.id "
        query = query + " LEFT JOIN documentos_revision ON documentos_documento.id = documentos_revision.documento_id "
        query = query + " WHERE documentos_revision.director_id =%s "
        params = [request.session['idUsuario']]

        cursor.execute(query, params)

        rows = dictfetchall(cursor)

        if rows:
            #RETORNA
            return JsonResponse(rows, safe=False)
        else:
            #RETORNA MENSAJE DE NO EXISTEN
            json = {
            'resultado':'no_ok',
            'mensaje': 'no existen Documentos',
            }
            return JsonResponse(json, safe=False)