import glob
import os
import re
from collections import OrderedDict
import lxml.etree as ET
from orchestrator.cots.gdal.gdal_dataset_info import GdalDatasetInfo
from orchestrator.plugins.common.earth_explorer.maja_earth_explorer_l2_image_file_writer import \
    EarthExplorerL2ImageFileWriter
from orchestrator.common.logger.maja_logging import configure_logger
LOGGER = configure_logger(__name__)

WAVELENGTH = OrderedDict([("B1", 443),
                          ("B2", 490),
                          ("B3", 560),
                          ("B4", 665),
                          ("B5", 705),
                          ("B6", 740),
                          ("B7", 783),
                          ("B8", 842),
                          ("B8A", 865),
                          ("B9", 945),
                          ("B10", 1375),
                          ("B11", 1610),
                          ("B12", 2190)])

RESOLUTION = OrderedDict([("B1", 60),
                          ("B2", 10),
                          ("B3", 10),
                          ("B4", 10),
                          ("B5", 20),
                          ("B6", 20),
                          ("B7", 20),
                          ("B8", 10),
                          ("B8A", 20),
                          ("B9", 60),
                          ("B10", 60),
                          ("B11", 20),
                          ("B12", 20)])

BAND_ID = [str(x) for x in range(13)]
DETECTOR_ID = [str(x) for x in range(12)]

class MajaSentinel2L2ImageWriter(EarthExplorerL2ImageFileWriter):

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

    def can_write(self, plugin_name):
        return (plugin_name == "SENTINEL2")

def get_root():
    # <Earth_Explorer_Header xmlns="http://eop-cfi.esa.int/CFI"
    # xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" schema_version="1.00"
    # xsi:schemaLocation="http://eop-cfi.esa.int/CFI ./SSC_PDTQLK_QuickLook.xsd"
    # xsi:type="PDTQLK_Header_Type">
    xmlns = "http://eop-cfi.esa.int/CFI"
    xsi = "http://www.w3.org/2001/XMLSchema-instance"
    schemaLocation = "http://eop-cfi.esa.int/CFI ./SSC_PDTQLK_QuickLook.xsd"
    typeXsi = "PDTQLK_Header_Type"
    root = ET.Element("Earth_Explorer_Header", attrib={"schema_version": "1.00",
                                                       "{" + xsi + "}schemaLocation": schemaLocation,
                                                       "{" + xsi + "}type": typeXsi},
                      nsmap={'xsi': xsi, None: xmlns})
    return root

def extract_site_id_from_folder_name(dir_name):
    """
    Return the tile id from the folder name
    :param dir_name:
    :return:
    """
    try:
        return re.search(r"S2A_OPER_SSC_L2VALD_(.+?)_\d{8}\.DBL\.DIR", os.path.basename(dir_name)).group(1)
    except AttributeError:
        LOGGER.error(r"No pattern 'S2A_OPER_SSC_L2VALD_(.+?___)_\d{8}\.DBL\.DIR' found in %s", dir_name)

def extract_acquisition_date_from_folder_name(dir_name):
    """
    Return the tile id from the folder name
    :param dir_name:
    :return:
    """
    try:
        return re.search(r"S2A_OPER_SSC_L2VALD_.+?_(\d{8})\.DBL\.DIR", os.path.basename(dir_name)).group(1)
    except AttributeError:
        LOGGER.error(r"No pattern 'S2A_OPER_SSC_L2VALD_.+?____(\d{8})\.DBL\.DIR' found in %s", dir_name)

def get_fixed_header(root, basename_out, mission, validity_time, version, source):
    a1 = ET.SubElement(root, "Fixed_Header")
    a1_sub = ET.SubElement(a1, "File_Name")
    a1_sub.text = basename_out
    a1_sub = ET.SubElement(a1, "File_Description")
    a1_sub.text = "L2PublishedProduct"
    a1_sub = ET.SubElement(a1, "Notes")
    a1_sub.text = "L2 note"
    a1_sub = ET.SubElement(a1, "Mission")
    a1_sub.text = mission
    a1_sub = ET.SubElement(a1, "File_Class")
    a1_sub.text = "OPER"
    a1_sub = ET.SubElement(a1, "File_Type")
    a1_sub.text = "SSC_L2VALD"
    b1 = ET.SubElement(a1, "Validity_Period")
    b1_sub = ET.SubElement(b1, "Validity_Start")
    # toto.text = "UTC=2006-07-01T18:11:45"
    b1_sub.text = "UTC={}".format(validity_time[0])
    b1_sub = ET.SubElement(b1, "Validity_Stop")
    # toto.text = "UTC=9999-99-99T99:99:99"
    b1_sub.text = "UTC={}".format(validity_time[1])
    b1_sub = ET.SubElement(a1, "File_Version")
    # toto.text = "0001"
    b1_sub.text = version
    b2 = ET.SubElement(a1, "Source")
    b2_sub = ET.SubElement(b2, "System")
    b2_sub.text = source.get("system")
    b2_sub = ET.SubElement(b2, "Creator")
    b2_sub.text = source.get("creator")
    b2_sub = ET.SubElement(b2, "Creator_Version")
    b2_sub.text = source.get("creator_version")
    b2_sub = ET.SubElement(b2, "Creation_Date")
    b2_sub.text = source.get("creation_date")

def get_product_information(root, gipp_files, quality_indexes, mean_sun_angles, solar_angles_zenith,
                            solar_angles_azimuth, mean_viewing_angles, list_of_viewing_angles):
    a1 = ET.SubElement(root, "Product_Information")
    a1_sub = ET.SubElement(a1, "Product_Level")
    a1_sub.text = "L2"
    a1_sub = ET.SubElement(a1, "Acquisition_Date_Time")
    a1_sub.text = ""
    a1_sub = ET.SubElement(a1, "Acquisition_Orbit_Number")
    a1_sub.text = ""
    b1 = ET.SubElement(a1, "Processing_Information")
    b1_sub = ET.SubElement(b1, "Date_Time")
    b1_sub.text = ""
    c1 = ET.SubElement(b1, "List_of_GIPP_Files", count=str(len(gipp_files)))
    for index_gipp, dic_gipp in enumerate(gipp_files):
        c1_sub = ET.SubElement(c1, "GIPP_File", sn=str(index_gipp + 1))
        c1_sub_sub = ET.SubElement(c1_sub, "Nature")
        c1_sub_sub.text = dic_gipp["nature"]
        c1_sub_sub = ET.SubElement(c1_sub, "File_Location")
        c1_sub_sub.text = dic_gipp["file_location"]
        c1_sub_sub = ET.SubElement(c1_sub, "Logical_Name")
        c1_sub_sub.text = dic_gipp["logical_name"]
    b1 = ET.SubElement(a1, "Web_Site_URL")
    b1 = ET.SubElement(a1, "List_of_Quality_Indexes", count=str(len(quality_indexes)))
    for index_qi, dic_qi in enumerate(quality_indexes):
        b1_sub = ET.SubElement(b1, "Quality_Index", sn=str(index_qi + 1))
        b1_sub_sub = ET.SubElement(b1_sub, "Code")
        b1_sub_sub.text = dic_qi["code"]
        b1_sub_sub = ET.SubElement(b1_sub, "Value")
        b1_sub_sub.text = dic_qi["value"]
    b1 = ET.SubElement(a1, "List_of_Band_Central_Wavelength", count=str(len(WAVELENGTH)))
    for key, value in WAVELENGTH.items():
        b1_sub = ET.SubElement(b1, "Band_Central_Wavelength", sk=key, unit="nanometer")
        b1_sub.text = str(value)
    b1 = ET.SubElement(a1, "List_of_Band_Resolution", count=str(len(RESOLUTION)))
    for key, value in RESOLUTION.items():
        b1_sub = ET.SubElement(b1, "Band_Central_Resolution", sk=key, unit="meter")
        b1_sub.text = str(value)
    b1 = ET.SubElement(a1, "Mean_Sun_Angle")
    b1_sub = ET.SubElement(b1, "ZENITH_ANGLE", unit="deg")
    b1_sub.text = str(mean_sun_angles["zenith"])
    b1_sub = ET.SubElement(b1, "AZIMUTH_ANGLE", unit="deg")
    b1_sub.text = str(mean_sun_angles["azimuth"])
    b1 = ET.SubElement(a1, "Solar_Angles")
    b1_sub = ET.SubElement(b1, "Zenith")
    b1_sub_sub = ET.SubElement(b1_sub, "COL_STEP", unit="m")
    b1_sub_sub.text = str(solar_angles_zenith[0])
    b1_sub_sub = ET.SubElement(b1_sub, "ROW_STEP", unit="m")
    b1_sub_sub.text = str(solar_angles_zenith[1])
    b1_sub_sub = ET.SubElement(b1_sub, "Values_List")
    for el in solar_angles_zenith[2]:
        b1_sub_sub_sub = ET.SubElement(b1_sub_sub, "VALUES")
        b1_sub_sub_sub.text = str(el)
    b1_sub = ET.SubElement(b1, "Azimuth")
    b1_sub_sub = ET.SubElement(b1_sub, "COL_STEP", unit="m")
    b1_sub_sub.text = str(solar_angles_azimuth[0])
    b1_sub_sub = ET.SubElement(b1_sub, "ROW_STEP", unit="m")
    b1_sub_sub.text = str(solar_angles_azimuth[1])
    b1_sub_sub = ET.SubElement(b1_sub, "Values_List")
    for el in solar_angles_azimuth[2]:
        b1_sub_sub_sub = ET.SubElement(b1_sub_sub, "VALUES")
        b1_sub_sub_sub.text = str(el)
    b1 = ET.SubElement(a1, "Mean_Viewing_Incidence_Angle_List")
    for key, value in mean_viewing_angles.items():
        b1_sub = ET.SubElement(b1, "Mean_Viewing_Incidence_Angle", bandId=str(key))
        b1_sub_sub = ET.SubElement(b1_sub, "ZENITH_ANGLE", unit="deg")
        b1_sub_sub.text = str(value["zenith"])
        b1_sub_sub = ET.SubElement(b1_sub, "AZIMUTH_ANGLE", unit="deg")
        b1_sub_sub.text = str(value["azimuth"])
    b1 = ET.SubElement(a1, "List_of_Viewing_Angles")
    for key, value in list_of_viewing_angles.items():
        b1_sub = ET.SubElement(b1, "Viewing_Incidence_Angles_Grids", bandId=str(key[0]), detectorId=str(key[1]))
        b1_sub_sub = ET.SubElement(b1_sub, "Zenith")
        zenith_values = value["zenith"]
        b1_sub_sub_sub = ET.SubElement(b1_sub_sub, "COL_STEP", unit="m")
        b1_sub_sub_sub.text = str(zenith_values[0])
        b1_sub_sub_sub = ET.SubElement(b1_sub_sub, "ROW_STEP", unit="m")
        b1_sub_sub_sub.text = str(zenith_values[1])
        b1_sub_sub_sub = ET.SubElement(b1_sub, "Values_List")
        for el in zenith_values[2]:
            b1_sub_sub_sub_sub = ET.SubElement(b1_sub_sub_sub, "VALUES")
            b1_sub_sub_sub_sub.text = str(el)

        b1_sub_sub = ET.SubElement(b1_sub, "Azimuth")
        azimuth_values = value["azimuth"]
        b1_sub_sub_sub = ET.SubElement(b1_sub_sub, "COL_STEP", unit="m")
        b1_sub_sub_sub.text = str(azimuth_values[0])
        b1_sub_sub_sub = ET.SubElement(b1_sub_sub, "ROW_STEP", unit="m")
        b1_sub_sub_sub.text = str(azimuth_values[1])
        b1_sub_sub_sub = ET.SubElement(b1_sub, "Values_List")
        for el in azimuth_values[2]:
            b1_sub_sub_sub_sub = ET.SubElement(b1_sub_sub_sub, "VALUES")
            b1_sub_sub_sub_sub.text = str(el)

    a1_sub = ET.SubElement(a1, "Reference_SiteDefinition_Id")
    a1_sub.text = "UNKNOWN"
    a1_sub = ET.SubElement(a1, "Cloud_Percentage")
    a1_sub.text = "0"
    a1_sub = ET.SubElement(a1, "Snow_Percentage")
    a1_sub.text = "0"
    b1 = ET.SubElement(a1, "Used_DEM")
    b1_sub = ET.SubElement(b1, "DEM_Reference")
    b1_sub.text = ""
    b1_sub = ET.SubElement(b1, "Statistics")
    b1_sub_sub = ET.SubElement(b1_sub, "Min", unit="m")
    b1_sub_sub.text = ""
    b1_sub_sub = ET.SubElement(b1_sub, "Max", unit="m")
    b1_sub_sub.text = ""
    b1_sub_sub = ET.SubElement(b1_sub, "Average", unit="m")
    b1_sub_sub.text = ""
    b1_sub_sub = ET.SubElement(b1_sub, "Standard_Deviation", unit="m")
    b1_sub_sub.text = ""
    a1_sub = ET.SubElement(a1, "Reflectance_Quantification_Value")
    a1_sub.text = "0.0001"
    b1 = ET.SubElement(a1, "Processing_Flags_And_Modes")
    b1_sub = ET.SubElement(b1, "Processing_Mode")
    b1_sub.text = "INIT_MODE"
    b1_sub = ET.SubElement(b1, "Adjacency_Effects_And_Slope_Correction")
    b1_sub.text = "false"
    b1 = ET.SubElement(a1, "List_of_Used_Product_Ids", count="1")
    b1_sub = ET.SubElement(b1, "Used_Product_Id", sn="1")
    b1_sub.text = "MTD_MSIL1C"

def get_image_information(root, res):
    """
                <Number_of_Significant_Bits>16</Number_of_Significant_Bits>
                <Nodata_Value>-10000</Nodata_Value>
                <List_of_Resolutions count="2">
                    <Resolution r="10">
                        <Size>
                            <Lines>10980</Lines>
                            <Columns>10980</Columns>
                            <Bands>4</Bands>
                        </Size>
                        <Geoposition>
                            <ULX>199980</ULX>
                            <ULY>7300000</ULY>
                            <XDIM>10</XDIM>
                            <YDIM>-10</YDIM>
                        </Geoposition>
                        <Product_Sampling>
                            <By_Line unit="m">10</By_Line>
                            <By_Column unit="m">10</By_Column>
                        </Product_Sampling>
                        <List_of_Bands count="4">
                            <Band sn="1">B2</Band>
                            <Band sn="2">B3</Band>
                            <Band sn="3">B4</Band>
                            <Band sn="4">B8</Band>
                        </List_of_Bands>
                    </Resolution>
                    <Resolution r="20">
                        <Size>
                            <Lines>5490</Lines>
                            <Columns>5490</Columns>
                            <Bands>6</Bands>
                        </Size>
                        <Geoposition>
                            <ULX>199980</ULX>
                            <ULY>7300000</ULY>
                            <XDIM>20</XDIM>
                            <YDIM>-20</YDIM>
                        </Geoposition>
                        <Product_Sampling>
                            <By_Line unit="m">20</By_Line>
                            <By_Column unit="m">20</By_Column>
                        </Product_Sampling>
                        <List_of_Bands count="6">
                            <Band sn="1">B5</Band>
                            <Band sn="2">B6</Band>
                            <Band sn="3">B7</Band>
                            <Band sn="4">B8A</Band>
                            <Band sn="5">B11</Band>
                            <Band sn="6">B12</Band>
                        </List_of_Bands>
                    </Resolution>
                </List_of_Resolutions>
                <Image_Compacting_Tool>NO</Image_Compacting_Tool>
            </Image_Information>
    :return:
    """

    a1 = ET.SubElement(root, "Image_Information")
    a1_sub = ET.SubElement(a1, "Format")
    a1_sub.text = "GEOTIFF"
    a1_sub = ET.SubElement(a1, "Binary_Encoding")
    a1_sub.text = "LITTLE_ENDIAN"
    a1_sub = ET.SubElement(a1, "Data_Type")
    a1_sub.text = "SIGNED_SHORT"
    a1_sub = ET.SubElement(a1, "Number_of_Significant_Bits")
    a1_sub.text = "16"
    a1_sub = ET.SubElement(a1, "Nodata_Value")
    a1_sub.text = "-10000"
    a1_sub = ET.SubElement(a1, "List_of_Resolutions", count="2")
    for resolution in res:
        b1 = ET.SubElement(a1_sub, "Resolution", r=str(resolution["resolution"]))
        b1_sub = ET.SubElement(b1, "Size")
        b1_sub_sub = ET.SubElement(b1_sub, "Lines")
        b1_sub_sub.text = str(resolution["info"].size[0])
        b1_sub_sub = ET.SubElement(b1_sub, "Columns")
        b1_sub_sub.text = str(resolution["info"].size[1])
        b1_sub_sub = ET.SubElement(b1_sub, "Bands")
        b1_sub_sub.text = str(resolution["info"].number_of_bands)
        b1_sub = ET.SubElement(b1, "Geoposition")
        b1_sub_sub = ET.SubElement(b1_sub, "ULX")
        b1_sub_sub.text = str(resolution["info"].origin[0])
        b1_sub_sub = ET.SubElement(b1_sub, "ULY")
        b1_sub_sub.text = str(resolution["info"].origin[1])
        b1_sub_sub = ET.SubElement(b1_sub, "XDIM")
        b1_sub_sub.text = str(resolution["info"].pixel_size[0])
        b1_sub_sub = ET.SubElement(b1_sub, "YDIM")
        b1_sub_sub.text = str(resolution["info"].pixel_size[1])
        b1_sub = ET.SubElement(b1, "Product_Sampling")
        b1_sub_sub = ET.SubElement(b1_sub, "By_Line")
        b1_sub_sub.text = str(resolution["info"].pixel_size[0])
        b1_sub_sub = ET.SubElement(b1_sub, "By_Column")
        b1_sub_sub.text = str(resolution["info"].pixel_size[1])
        b1_sub = ET.SubElement(b1, "List_of_Bands", count=str(len(resolution["list_of_bands"])))
        for index_band_name, band_name in enumerate(resolution["list_of_bands"]):
            b1_sub_sub = ET.SubElement(b1_sub, "Band", sn=str(index_band_name + 1))
            b1_sub_sub.text = band_name

    a1_sub = ET.SubElement(a1, "Image_Compacting_Tool")
    a1_sub.text = "NO"

def get_geo_referencing_information(root, info):
    """
    <Geo_Referencing_Information>
        <Product_Coverage>
            <Geographic>
                <Coordinate_Reference_System>
                    EPSG:32736
                    <Short_Description>WGS84 / UTM zone 36S</Short_Description>
                </Coordinate_Reference_System>
            </Geographic>
        </Product_Coverage>
    </Geo_Referencing_Information>
    :return:
    """

    a1 = ET.SubElement(root, "Geo_Referencing_Information")
    a1_sub = ET.SubElement(a1, "Product_Coverage")
    a1_sub_sub = ET.SubElement(a1_sub, "Geographic")
    a1_sub_sub_sub = ET.SubElement(a1_sub_sub, "Coordinate_Reference_System")
    a1_sub = ET.SubElement(a1, "Code")
    a1_sub.text = "EPSG:{}".format(info.espg_code_number)
    a1_sub = ET.SubElement(a1, "Short_Description")
    a1_sub.text = info.projection_name

def get_product_organization(root, files, input_dir):
    """
    :return:
    """
    a1 = ET.SubElement(root, "Product_Organization")
    a1_sub = ET.SubElement(a1, "Image_File")
    image = files.get("image")
    a1_sub_sub = ET.SubElement(a1_sub, "Nature")
    a1_sub_sub.text = image[0]
    a1_sub_sub = ET.SubElement(a1_sub, "File_Location")
    a1_sub_sub.text = os.path.join(".", os.path.basename(os.path.dirname(input_dir)), os.path.basename(image[1]))
    a1_sub_sub = ET.SubElement(a1_sub, "Logical_Name")
    a1_sub_sub.text = os.path.basename(image[1])
    a1_sub = ET.SubElement(a1, "Quicklook_File")
    ql = files.get("quicklook")
    a1_sub_sub = ET.SubElement(a1_sub, "Nature")
    a1_sub_sub.text = ql[0]
    a1_sub_sub = ET.SubElement(a1_sub, "File_Location")
    a1_sub_sub.text = os.path.join(".", os.path.basename(os.path.dirname(input_dir)), os.path.basename(ql[1]))
    a1_sub_sub = ET.SubElement(a1_sub, "Logical_Name")
    a1_sub_sub.text = os.path.basename(ql[1])
    annex_files = files.get("annex_files")
    a1_sub = ET.SubElement(a1, "List_of_Annex_Files", count=str(len(annex_files)))
    for annex, value in annex_files.items():
        a1_sub_sub = ET.SubElement(a1_sub, "Annex_File", sk=annex[:-3])
        a1_sub_sub_sub = ET.SubElement(a1_sub_sub, "Nature")
        a1_sub_sub_sub.text = value[0]
        a1_sub_sub_sub = ET.SubElement(a1_sub_sub, "File_Location")
        a1_sub_sub_sub.text = os.path.join(
            ".", os.path.basename(
                os.path.dirname(input_dir)), os.path.basename(
                value[1]))
        a1_sub_sub_sub = ET.SubElement(a1_sub_sub, "Logical_Name")
        a1_sub_sub_sub.text = os.path.basename(ql[1])
    a1_sub = ET.SubElement(a1, "Private_Data_File")
    private = files.get("private")
    if private is not None:
        a1_sub_sub = ET.SubElement(a1_sub, "Nature")
        a1_sub_sub.text = private[0]
        a1_sub_sub = ET.SubElement(a1_sub, "File_Location")
        a1_sub_sub.text = os.path.join(".", "PRIVATE", os.path.basename(private[1]))
        a1_sub_sub = ET.SubElement(a1_sub, "Logical_Name")
        a1_sub_sub.text = os.path.basename(private[1])

def search_first_file_with_pattern(input_dir, pattern):
    r = search_files_with_pattern(input_dir, pattern)
    if r:
        return os.path.join(input_dir, r[0])
    else:
        LOGGER.error("No match found for %s in %s", pattern, input_dir)

def search_files_with_pattern(input_dir, pattern):
    return [x for x in os.listdir(input_dir) if re.match(pattern, x) is not None]

def search_only_one_file_from_pattern(input_dir, pattern):
    r = search_files_with_pattern(input_dir, pattern)
    # print pattern, r
    # remove aux.xml files matching the pattern
    r = [x for x in r if not x.endswith(".aux.xml")]
    if len(r) == 1:
        return os.path.join(input_dir, r[0])
    elif len(r) == 0:
        LOGGER.error("No match found for %s in %s", pattern, input_dir)
    else:
        LOGGER.error("Error: several files match the given pattern %s", r)

def get_files(input_dir):
    files = {}
    files["image"] = ("SSC_PDTIMG", search_only_one_file_from_pattern(input_dir, "S2.+?_SSC_PDTIMG_.+?SRE_R2.HDR"))
    files["quicklook"] = ("SSC_PDTQLK", search_only_one_file_from_pattern(input_dir, "S2.+?_SSC_PDTQLK_.+?.JPG"))

    files["private"] = ("TEC_L2VALD", search_only_one_file_from_pattern(os.path.join(input_dir, "PRIVATE"),
                                                                        "S2.+?_TEC_L2VALD_.+?.EEF"))

    # remove None values from an incomplete product
    files_to_return = {}
    for key, value in files.items():
        if not value[1] is None:
            files_to_return[key] = value

    annex_files = {}
    annex_files["MSK_r1"] = (
        "SSC_PDTANX", search_only_one_file_from_pattern(
            input_dir, "S2.+?_SSC_PDTANX_.+?_MSK_R1.HDR"))
    annex_files["MSK_r2"] = (
        "SSC_PDTANX", search_only_one_file_from_pattern(
            input_dir, "S2.+?_SSC_PDTANX_.+?_MSK_R2.HDR"))
    annex_files["QLT_r1"] = (
        "SSC_PDTANX", search_only_one_file_from_pattern(
            input_dir, "S2.+?_SSC_PDTANX_.+?_QLT_R1.HDR"))
    annex_files["QLT_r2"] = (
        "SSC_PDTANX", search_only_one_file_from_pattern(
            input_dir, "S2.+?_SSC_PDTANX_.+?_QLT_R2.HDR"))
    annex_files["ATB_r1"] = (
        "SSC_PDTANX", search_only_one_file_from_pattern(
            input_dir, "S2.+?_SSC_PDTANX_.+?_ATB_R1.HDR"))
    annex_files["ATB_r2"] = (
        "SSC_PDTANX", search_only_one_file_from_pattern(
            input_dir, "S2.+?_SSC_PDTANX_.+?_ATB_R2.HDR"))
    annex_files["CLD_r1"] = (
        "SSC_PDTANX", search_only_one_file_from_pattern(
            input_dir, "S2.+?_SSC_PDTANX_.+?_CLD_R1.HDR"))
    annex_files["CLD_r2"] = (
        "SSC_PDTANX", search_only_one_file_from_pattern(
            input_dir, "S2.+?_SSC_PDTANX_.+?_CLD_R2.HDR"))
    # remove None values from an incomplete product
    annex_files_to_return = {}
    for key, value in annex_files.items():
        LOGGER.debug("key, vlue", key, value)
        if not value[1] is None:
            annex_files_to_return[key] = value
    LOGGER.debug("###", annex_files_to_return)
    files_to_return["annex_files"] = annex_files_to_return

    LOGGER.debug("files to return %s", files_to_return)

    return files_to_return

def hdr_creation(input_dir, output_filename, writer):
    LOGGER.debug("global_hdr_nodes, hdr_creation input_dir %s", input_dir)
    LOGGER.debug("global_hdr_nodes, hdr_creation output_filename %s", output_filename)

    if not os.path.isdir(input_dir):
        LOGGER.error("Input directory does not exist ! %s", input_dir)
        return
    if os.listdir(input_dir) == []:
        LOGGER.error("Input directory is empty ! %s", input_dir)
        return

    image_r1 = search_first_file_with_pattern(input_dir, r'^.+?_R1.DBL.TIF$')
    image_r2 = search_first_file_with_pattern(input_dir, r'^.+?_R2.DBL.TIF$')

    id_tile = extract_site_id_from_folder_name(input_dir)
    acquisition_date = extract_acquisition_date_from_folder_name(input_dir)

    if glob.glob(os.path.join(input_dir, "*.TIF")) == []:
        LOGGER.warning("No TIF files found in %s", input_dir)
        return
    a_image = glob.glob(os.path.join(input_dir, "*.TIF"))[0]

    info = GdalDatasetInfo(a_image)
    # basename_out = os.path.basename(os.path.splitext(output_filename)[0])
    # logging.debug(basename_out)
    #
    # xml_file = os.path.join(os.path.dirname(__file__), "xml_template.xml")
    # tree = ET.parse(xml_file)

    # ET.register_namespace("", "http://eop-cfi.esa.int/CFI")
    root = get_root()
    # tree.getroot()

    # root = ET.Element("Earth_Explorer_Header", schema_version = "1.00", xmlns = "http://eop-cfi.esa.int/CFI", xsi = "http://www.w3.org/2001/XMLSchema-instance", type = "REFDE2_Header_Type", schemaLocation = "http://eop-cfi.esa.int/CFI AUX_REFDE2_ReferenceDemDataLevel2.xsd")

    # Double splitext to remove .DBL.DIR
    get_fixed_header(root,
                     basename_out=os.path.basename(os.path.splitext(os.path.splitext(input_dir)[0])[0]),
                     mission="SENTINEL-2A",
                     validity_time=["", ""],
                     version="0003",
                     source={
                         "system": "MAJA",
                         "creator": "MAJA_L2_INIT_CHAIN",
                         "creator_version": "0.0.0",
                         "creation_date": "TBD"
                     })

    a = ET.SubElement(root, "Variable_Header")
    b2 = ET.SubElement(a, "Main_Product_Header")
    ET.SubElement(b2, "List_of_Consumers", count="0")
    ET.SubElement(b2, "List_of_Extensions", count="0")
    b3 = ET.SubElement(a, "Specific_Product_Header")
    b4 = ET.SubElement(b3, "Instance_Id")
    b4_sub = ET.SubElement(b4, "Nick_Name")
    b4_sub.text = id_tile
    b4_sub = ET.SubElement(b4, "Acquisition_Date")
    b4_sub.text = acquisition_date

    gipp_files = [{"nature": "GIP_CKEXTL",
                   "file_location": "NIL=OTHER:EXTERNAL",
                   "logical_name": "S2A_TEST_GIP_CKEXTL_S_35JPK____50001_00000000_99999999"},
                  {"nature": "GIP_CKQLTL",
                   "file_location": "NIL=OTHER:EXTERNAL",
                   "logical_name": "S2A_TEST_GIP_CKQLTL_S_35JPK____50001_00000000_99999999"},
                  {"nature": "GIP_L2ALBD",
                   "file_location": "NIL=OTHER:EXTERNAL",
                   "logical_name": "S2A_TEST_GIP_L2ALBD_L_CONTINEN_50001_00000000_99999999"},
                  {"nature": "GIP_L2COMM",
                   "file_location": "NIL=OTHER:EXTERNAL",
                   "logical_name": "S2A_TEST_GIP_L2COMM_L_ALLSITES_50001_00000000_99999999"},
                  {"nature": "GIP_L2DIFT",
                   "file_location": "NIL=OTHER:EXTERNAL",
                   "logical_name": "S2A_TEST_GIP_L2DIFT_L_CONTINEN_50001_00000000_99999999"},
                  {"nature": "GIP_L2DIRT",
                   "file_location": "NIL=OTHER:EXTERNAL",
                   "logical_name": "S2__TEST_GIP_L2SITE_S_35JPK____50001_00000000_99999999"},
                  {"nature": "GIP_L2SITE",
                   "file_location": "NIL=OTHER:EXTERNAL",
                   "logical_name": "S2__TEST_GIP_L2SITE_S_35JPK____50001_00000000_99999999"},
                  {"nature": "GIP_L2SMAC",
                   "file_location": "NIL=OTHER:EXTERNAL",
                   "logical_name": "S2A_TEST_GIP_L2SMAC_L_ALLSITES_50001_00000000_99999999"},
                  {"nature": "GIP_L2TOCR",
                   "file_location": "NIL=OTHER:EXTERNAL",
                   "logical_name": "S2A_TEST_GIP_L2TOCR_L_CONTINEN_50001_00000000_99999999"},
                  {"nature": "GIP_L2WATV",
                   "file_location": "NIL=OTHER:EXTERNAL",
                   "logical_name": "S2A_TEST_GIP_L2WATV_L_CONTINEN_50001_00000000_99999999"},
                  ]
    qi = [{"code": "RAIN_DETECTED",
           "value": "FALSE"},
          {"code": "HOT_SPOT_DETECTED",
           "value": "FALSE"},
          {"code": "SUN_GLINT_DETECTED",
           "value": "FALSE"},
          {"code": "CIRRUS_DETECTED",
           "value": "FALSE"},
          ]

    mean_sun_angles = {"zenith": -9999,
                       "azimuth": -9999
                       }
    empty_values = [" ".join(["Nan"] * 20)] * 23
    solar_angles_zenith = (5000, 5000, empty_values)
    solar_angles_azimuth = (5000, 5000, empty_values)

    mean_viewing_angles = OrderedDict([("0", {"zenith": -9999,
                                              "azimuth": -9999
                                              }),
                                       ("1", {"zenith": -9999,
                                              "azimuth": -9999
                                              }),
                                       ("2", {"zenith": -9999,
                                              "azimuth": -9999
                                              }),
                                       ("3", {"zenith": -9999,
                                              "azimuth": -9999
                                              }),
                                       ("4", {"zenith": -9999,
                                              "azimuth": -9999
                                              }),
                                       ("5", {"zenith": -9999,
                                              "azimuth": -9999
                                              }),
                                       ("6", {"zenith": -9999,
                                              "azimuth": -9999
                                              }),
                                       ("7", {"zenith": -9999,
                                              "azimuth": -9999
                                              }),
                                       ("8", {"zenith": -9999,
                                              "azimuth": -9999
                                              }),
                                       ("9", {"zenith": -9999,
                                              "azimuth": -9999
                                              }),
                                       ("10", {"zenith": -9999,
                                               "azimuth": -9999
                                               }),
                                       ("11", {"zenith": -9999,
                                               "azimuth": -9999
                                               }),
                                       ("12", {"zenith": -9999,
                                               "azimuth": -9999
                                               }),
                                       ])

    list_of_viewing_angles = OrderedDict([(a, b) for a in range(10) for b in range(3, 13)])

    empty_thing = {"zenith": (5000, 5000, empty_values),
                   "azimuth": (5000, 5000, empty_values)}

    list_of_viewing_angles = OrderedDict([((x, y), empty_thing) for x in BAND_ID for y in DETECTOR_ID])

    get_product_information(b3, gipp_files, qi, mean_sun_angles, solar_angles_zenith, solar_angles_azimuth,
                            mean_viewing_angles, list_of_viewing_angles)

    info_r1 = GdalDatasetInfo(image_r1)
    info_r2 = GdalDatasetInfo(image_r2)

    res = [{"resolution": 10,
            "info": info_r1,
            "list_of_bands": ["B2", "B3", "B4", "B8"]},
           {"resolution": 20,
            "info": info_r2,
            "list_of_bands": ["B5", "B6", "B7", "B8A", "B11", "B12"]}
           ]

    get_image_information(root, res)
    files = get_files(input_dir)
    get_product_organization(root, files, input_dir)

    tree = ET.ElementTree(root)

    f = open(output_filename, "w")
    f.write(ET.tostring(tree, pretty_print=True, xml_declaration=True,
                        encoding="UTF-8"))
    f.close()
    LOGGER.debug("%s Created", output_filename)


# 24. Write a Python program to check whether a specified value is contained in a group of values.
# Test Data :
# 3 -> [1, 5, 8, 3] : True
# -1 -> [1, 5, 8, 3] : False

lst = list(map(int, input("Enter number separated by space : ").split()))
num = int(input("Enter number to find : "))

if num in lst:
    print("Entered number lies within the container.")
else:
    print("Element Not found")


## VCF operation

import sys
import re
def remove_duplicate_snp(vcf,out):
    snps=set()
    bw=open(out,'w')
    count=0
    with open(vcf,'r') as br:
        for line in br:
            if line.startswith('#'):
                bw.write(line)
                continue
            arr=line.strip().split('\t')
            snp='_'.join([arr[x] for x in [0,1,3,4]])
            if snps.__contains__(snp):
                print(f'remove duplicate: {snp}')
                count+=1
                continue
            snps.add(snp)
            bw.write(line)
    bw.close()
    print(f'summary: remove {count} SNPs')

def add_sex_info(ped_prefix,sex,out_prefix):
    id_sex={}
    with open(sex,'r') as br:
        for line in br:
            arr=line.strip().split('\t')
            id_sex[arr[0]]=arr[1]
    bw=open(out_prefix+'.ped','w')
    ic=0
    ac=0
    with open(ped_prefix+'.ped','r') as br:
        for line in br:
            ac+=1
            arr=line.strip().split('\t')
            iid=arr[1]
            if not id_sex.__contains__(iid):
                continue
            bw.write('\t'.join(arr[0:4]+[id_sex[iid]]+arr[5:])+'\n')
            ic+=1
    bw.close()

    ## copy .map file
    bw=open(out_prefix+'.map','w')
    with open(ped_prefix+'.map','r') as br:
        for line in br:
            bw.write(line)
    bw.close()

    print(f'remain {ic} samples, original {ac}')

def remove_ped_duplicate_snp(pef_prefix,out_prefix):
    snps=set()
    bw=open(f'{out_prefix}.map','w')
    count=0
    idx=-1
    idxs=[]
    with open(f'{pef_prefix}.map','r') as br:
        for line in br:
            idx+=1
            arr=line.strip().split('\t')
            snp='_'.join([arr[x] for x in [0,3]])
            if snps.__contains__(snp):
                print(f'remove duplicate: {snp}')
                count+=1
                continue
            snps.add(snp)
            idxs.append(idx)
            bw.write(line)
    bw.close()
    print(f'summary: remove {count} SNPs')
    bw=open(f'{out_prefix}.ped','w')
    with open(f'{pef_prefix}.ped','r') as br:
        for line in br:
            idx+=1
            arr=re.split('\s+',line.strip())
            sep1=' '
            sep2=' '
            bw.write(sep1.join(arr[0:6]+[sep2.join(arr[x*2+6:x*2+8]) for x in idxs])+'\n')
    bw.close()

def get_chr_length(ref_fa,out):
    bw=open(out,'w')
    for line in open(ref_fa,'r'):
        if not line.startswith('>'):
            continue
        arr=re.split('\s+',line.strip())
        try:
            info=arr[0].replace('>','')+'\t'+arr[2].split(':')[-2]
        except:
            info=arr[0].replace('>','')+'\t'+'NA'
        print(info)
        bw.write(info+'\n')
    bw.close()

import os
def rename(dir):
    for chr in os.listdir(dir):
        chr_dir=os.path.join(dir,chr)
        for file in os.listdir(chr_dir):
            if file.__contains__('.gen'):
                continue
            newfile='Mb.gen'.join(file.split('Mb'))
            os.rename(os.path.join(chr_dir,file),os.path.join(chr_dir,newfile))
            cmd=f'rename {os.path.join(chr_dir,file)} {os.path.join(chr_dir,newfile)}'
            print(cmd)
            # os.system(cmd)

if __name__=='__main__':
    # remove_duplicate_snp(sys.argv[1],sys.argv[2])
    # add_sex_info(sys.argv[1],sys.argv[2],sys.argv[3])
    # 'plink --geno 0.1 --hwe 1e-5 --maf 0.01 --mind 0.1'
    # remove_ped_duplicate_snp(sys.argv[1],sys.argv[2])
    # get_chr_length(sys.argv[1],sys.argv[2])
    # print('IMPUTE2_chr1.85-90Mb'.split('Mb'))
    rename(sys.argv[1])


import numpy as np, matplotlib.pyplot as plt, pandas as pd,collections

database = pd.read_csv('database.csv',quotechar='"',skipinitialspace=True, delimiter=',')
data = database.as_matrix()

#Male to female ratio of perpetrators?
maskMale = (data[:,15] == 'Male')
maskFemale = (data[:,15] == 'Female')
Maleperp = data[maskMale].size
Femaleperp = data[maskFemale].size
print('Male perpetrators: ', Maleperp)
print('Female perpetrators: ', Femaleperp)

#Plot Generator
def make_autopct(values):
    def my_autopct(pct):
        total = sum(values)
        val = int(round(pct*total/100.0))
        return '{p:.2f}%  ({v:d})'.format(p=pct,v=val)
    return my_autopct
labels = 'Male', 'Female'
performance = [Maleperp,Femaleperp]
fig1, ax1 = plt.subplots()
ax1.pie(performance, labels=labels, autopct=make_autopct(performance),shadow=True, startangle=90)
ax1.axis('equal')
plt.title("Male to female ratio of perpetrators")
plt.savefig('Question6.png')


import sys
import json
import subprocess

def huffman(content):
  print(content)
  print('Writing frequencies...')
  f=open('tmp.freqs', 'w')
  for x in range(len(content)):
    count=int(content[x]*1000000)
    f.write(str(count))
    f.write("\n")
    print(str(x)+"/"+str(len(content))+' '+str(content[x])+' '+str(count))
  f.close()
  print('Generating code table...')
  subprocess.call(['/Users/brandon/Dust-tools/dist/build/huffman/huffman', 'tmp.freqs', 'tmp.huffman'])

  f=open('tmp.huffman')
  s=f.read()
  f.close()

  l=s.split("\n")
  l=map(parse, l)
  l=filter(lambda x: x!=None, l)

  print(l)

  return l

def parse(item):
  if item=='':
    return None
  a=[]
  for x in item:
    if x=="0":
      a.append(False)
    elif x=="1":
      a.append(True)
  return a

f=open(sys.argv[1])
s=f.read()
f.close()
data=json.loads(s)

data['incomingModel']['huffman']=huffman(data['incomingModel']['content']['params'])
data['outgoingModel']['huffman']=huffman(data['outgoingModel']['content']['params'])

f=open(sys.argv[1], 'w')
f.write(json.dumps(data))
f.close()


import alternate
import onBeat
import fade

def barToCommands(patterns,locations,bpm):
    # Finding the middle of the room to establish the boundary everyone is divided by
    """sumOfLongitudes = 0
    for elem in locations:
        sumOfLongitudes = elem[1] + sumOfLongitudes
    midpoint = sumOfLongitudes/len(locations)"""
    midpoint=[0,0]
    midpoint[0]=sum(locations[0])/float(len(locations[0]))
    midpoint[1]=sum(locations[1])/float(len(locations[1]))

    barTime = 240/bpm # Length of a bar
    beatTime = barTime/4 # Length of a beat

   # Making the list of commands
    commands=[]
    for i, p in enumerate(patterns):
        # Toggles the left and right half of the audience on and off
        if p == "lrAlternate":
            commands += alternate.lrAlternate(midpoint, i,  beatTime, barTime)
        # Same as lrAlternate, except top and bottom
        elif p == "udAlternate":
            commands += alternate.udAlternate(midpoint, i,  beatTime, barTime)
        # All participating devices on for a quarter beat at the start of each beat
        elif p == "flashOB":
            commands += onBeat.flashOB(i, beatTime, barTime)
        # Toggles lights off and on on beat
        elif p == "toggleOB":
            commands += onBeat.toggleOB(i, beatTime, barTime)
        # Identical to toggleOB, except in double time
        elif p == "toggleOB2":
            commands += onBeat.toggleOB2(i,  beatTime, barTime)
        # Test/hype building/space filling instruction. All dark for a bar
        elif p == "dark":
            commands += fade.dark(i, beatTime, barTime)
        elif p == "light":
            commands += fade.light(i, beatTime, barTime)
    #print(commands)
    return commands


from datetime import datetime

from xero import Xero
from xero.auth import PrivateCredentials

from django.conf import settings
from django.utils import timezone
from django.contrib.auth.models import User
from django.core.exceptions import ImproperlyConfigured

from datetime import datetime, time, date, timedelta
from xml.dom.minidom import parse, parseString

from nadine.models.profile import XeroContact

def test_xero_connection():
    api = XeroAPI()
    try:
        api = XeroAPI()
        api.xero.contacts.filter(Name='John Smith')
        return True
    except ImproperlyConfigured as ice:
        raise ice
    except Exception as e:
        pass
    return False

class XeroAPI:

    def __init__(self):
        self.deposit_account = getattr(settings, 'XERO_DEPOSIT_ACCOUNT', None)
        if self.deposit_account is None:
            raise ImproperlyConfigured("Please set your XERO_DEPOSIT_ACCOUNT setting.")

        consumer_key = getattr(settings, 'XERO_CONSUMER_KEY', None)
        if consumer_key is None:
            raise ImproperlyConfigured("Please set your XERO_CONSUMER_KEY setting.")

        private_key = getattr(settings, 'XERO_PRIVATE_KEY', None)
        if private_key is None:
            raise ImproperlyConfigured("Please set your XERO_PRIVATE_KEY setting. Must be a path to your privatekey.pem")

        with open(private_key) as keyfile:
            rsa_key = keyfile.read()

        self.credentials = PrivateCredentials(consumer_key, rsa_key)
        self.xero = Xero(self.credentials)

    def get_all_contacts(self):
        return self.xero.contacts.all()

    def find_contacts(self, user):
        return self.xero.contacts.filter(Name__contains=user.last_name)

    def get_contact(self, user):
        xero_contact = XeroContact.objects.filter(user=user).first()
        if xero_contact:
            search = self.xero.contacts.get(xero_contact.xero_id)
            if search and len(search) == 1:
                return search[0]
        return None

    def save_contact(self, contact_data):
        contact_id = None
        try:
            result = self.xero.contacts.save(contact_data)
            if len(result) == 1:
                contact_id = result[0]['ContactID']
        except Exception as e:
            raise Exception("Xero Contact Save Failed", e)
        return contact_id

    def add_contact(self, contact_data):
        contact_id = None
        try:
            result = self.xero.contacts.put(contact_data)
            if len(result) == 1:
                contact_id = result[0]['ContactID']
        except Exception as e:
            raise Exception("Xero Contact Save Failed", e)
        return contact_id

    def save_or_put_contact(self, contact_data):
        contact_id = None
        try:
            result = self.xero.contacts.save_or_put(contact_data)
            xml = result[3]['xml']
            dom = parseString(xml)
            id_elm = dom.getElementsByTagName('ContactID')
            if id_elm and len(id_elm) > 0:
                contact_id = id_elm[0].firstChild.nodeValue
        except Exception as e:
            raise Exception("Xero Contact Save Failed", e)
        return contact_id

    def sync_user_data(self, user):
        xero_contact = XeroContact.objects.filter(user=user).first()

        contact_data = {}
        contact_data['Name'] = user.get_full_name()
        contact_data['FirstName'] = user.first_name
        contact_data['LastName'] = user.last_name
        contact_data['EmailAddress'] = user.email
        contact_data['AccountNumber'] = user.username
        if xero_contact:
            contact_data['ContactID'] = xero_contact.xero_id
            xero_id = self.save_contact(contact_data)
        else:
            xero_id = self.add_contact(contact_data)
            xero_contact = XeroContact.objects.create(user=user, xero_id=xero_id)

        # Update the sync timestamp
        xero_contact.last_sync = timezone.now()
        xero_contact.save()

    def get_invoices(self, user):
        xero_contact = XeroContact.objects.filter(user=user).first()
        if not xero_contact:
            return None
        return self.xero.invoices.filter(Contact_ContactID=xero_contact.xero_id)

    def get_open_invoices(self, user=None):
        if user:
            xero_contact = XeroContact.objects.filter(user=user).first()
            if not xero_contact:
                return None
            return self.xero.invoices.filter(Contact_ContactID=xero_contact.xero_id, Status="AUTHORISED")
        return self.xero.invoices.filter(Status="AUTHORISED")

    def get_open_invoices_by_user(self):
        ''' One call to Xero to pull all open invoices and group them by user '''
        invoices = {}
        for i in self.get_open_invoices(user=None):
            contact_id = i['Contact']['ContactID']
            contact = XeroContact.objects.filter(xero_id=contact_id).first()
            username = "None"
            if contact:
                username = contact.user.username
            if username in invoices:
                invoices[username].append(i)
            else:
                invoices[username] = [i]
        return invoices

    def get_repeating_invoices(self, user):
        xero_data = None
        xero_contact = XeroContact.objects.filter(user=user).first()
        if xero_contact:
            xero_data = self.xero.repeatinginvoices.filter(Contact_ContactID=xero_contact.xero_id)
        return xero_data

    def create_invoice(self):
        # Clearly just a test -- JLS
        xero = self.xero
        invoice = {
                    'Status': 'DRAFT',
                    'Total': '264.00',
                    'CurrencyRate': '1.000000',
                    'Reference': 'sdfghsfgh',
                    'Type': 'ACCREC',
                    'CurrencyCode': 'AUD',
                    'AmountPaid': '0.00',
                    'TotalTax': '24.00',
                    'Contact': {
                        'Name': 'Test One'
                    },
                    'AmountDue': '264.00',
                    'Date': datetime.date(2014, 7, 24),
                    'LineAmountTypes': 'Exclusive',
                    'LineItems': {
                        'LineItem': {
                            'AccountCode': '200',
                            'TaxAmount': '24.00',
                            'Description': 'fgshfsdh',
                            'UnitAmount': '24.00',
                            'TaxType': 'OUTPUT',
                            'ItemCode': 'sfghfshg',
                            'LineAmount': '240.00',
                            'Quantity': '10.0000'
                        }
                    },
                    'SubTotal': '240.00',
                    'DueDate': datetime.date(2014, 7, 24)
                }
        #xero.invoices.put(invoice)

################################################################################
# OAuth Views (https://github.com/freakboy3742/pyxero)
################################################################################

from django.http import HttpResponseRedirect
from django.core.cache import caches

from xero import Xero
from xero.auth import OAuth2Credentials
from xero.constants import XeroScopes

def start_xero_auth_view(request):
   client_id = getattr(settings, 'XERO2_CLIENT_KEY', None)
   client_secret = getattr(settings, 'XERO2_CLIENT_SECRET', None)
   callback_uri = ""
   credentials = OAuth2Credentials(
       client_id, client_secret, callback_uri=callback_uri,
       scope=[XeroScopes.OFFLINE_ACCESS, XeroScopes.ACCOUNTING_CONTACTS,
              XeroScopes.ACCOUNTING_TRANSACTIONS]
   )
   authorization_url = credentials.generate_url()
   caches['default'].set('xero_creds', credentials.state)
   return HttpResponseRedirect(authorization_url)

def process_callback_view(request):
   cred_state = caches['mycache'].get('xero_creds')
   credentials = OAuth2Credentials(**cred_state)
   auth_secret = request.get_raw_uri()
   credentials.verify(auth_secret)
   credentials.set_default_tenant()
   caches['default'].set('xero_creds', credentials.state)

def some_view_which_calls_xero(request):
   cred_state = caches['mycache'].get('xero_creds')
   credentials = OAuth2Credentials(**cred_state)
   if credentials.expired():
       credentials.refresh()
       caches['default'].set('xero_creds', credentials.state)
   xero = Xero(credentials)

   contacts = xero.contacts.all()


import numpy as np

def predict(x):
    df = x.copy()
    output = []
    for index, row in df.iterrows():
        # Do not change the code before this point.
        # Please describe the process required to make the prediction below.

        feature_1 = row['Feature_1']
        feature_2 = row['Feature_2']

        # Calculate the distance from the origin
        distance = np.sqrt(feature_1**2 + feature_2**2)

        # Normalize the distance to be between 0 and 1
        normalized_distance = distance / (np.sqrt(2))

        # Calculate the probability of target being 1
        y = 1 - normalized_distance

        # Do not change the code after this point.
        output.append(y)
    return np.array(output)


def fact_i(n):
    result = 1
    for i in range(1, n+1):
        result *= i
    return result
####
def fact_r(n):
    if n == 1 or n == 0:
        return 1
    else:
        return n * fact_r(n-1)
####
def fact_r_tail(n, result=1):
    if n == 1 or n == 0:
        return result
    else:
        return fact_r_tail(n-1, n*result)
####

import sys

class TailRecurseException(BaseException):
    def __init__(self, args, kwargs):
        self.args = args
        self.kwargs = kwargs

def tail_call_optimized(g):
    def func(*args, **kwargs):
        f = sys._getframe()
        if (f.f_back and f.f_back.f_back and
             f.f_back.f_back.f_code == f.f_code):
            raise TailRecurseException(args, kwargs)
        else:
            while 1:
                try:
                    return g(*args, **kwargs)
                except TailRecurseException as e:
                    args = e.args
                    kwargs = e.kwargs
    return func

# @tail_call_optimized
# def fact_tco(n, result=1):
    # if n == 1 or n == 0:
        # return result
    # else:
        # return fact_tco(n-1, n*result)
def fact_tco(n, result=1):
    if n == 1 or n == 0:
        return result
    else:
        return fact_tco(n-1, n*result)

fact_tco = tail_call_optimized(fact_tco)

for i in range(2, 50):
    x = fact_i(i)
    y = fact_r(i)
    z = fact_r_tail(i)
    w = fact_tco(i)
    if x == y == z == w:
        pass
    else:
        print('error')

# print(fact_i(980))
sys.setrecursionlimit(2000)
print(fact_r_tail(1000))
sys.setrecursionlimit(100)
print(fact_tco(1000))
for i in range(1000, 1050, 3):
    x = fact_i(i)
    w = fact_tco(i)
    if x == w:
        pass
    else:
        print('error')


from math import ceil, cos, pi, sqrt
import re
from statistics import mean
from typing import List, Set
import numpy as np
import matplotlib.cm as cm
import matplotlib.pyplot as plt
from precession import precess_to_2000
from analyze_bound_20 import ConstellationBoundaryPoint

CONST_REGEX = r"([ \d]\d\.\d{5}) ([\+-]\d{2}\.\d{5}) (\w+)(?: {1,2}(\w+))?"
RA_LENGTH_SCALE = 360 / 24

class ConstellationBoundaryLine:
    def __init__(self, p1: ConstellationBoundaryPoint,
            p2: ConstellationBoundaryPoint):
        self.p1 = p1
        self.p2 = p2

    def __eq__(self, o):
        return isinstance(o, ConstellationBoundaryLine) and (
            (self.p1 == o.p1 and self.p2 == o.p2)
            or (self.p1 == o.p2 and self.p2 == o.p1)
        )

    def __hash__(self):
        return min(hash(self.p1), hash(self.p2))

    def __repr__(self):
        return f"ConstellationBoundaryLine({repr(self.p1)}, {repr(self.p2)})"

    def get_ra_delta(self):

        negative = ((self.p2.ra < self.p1.ra and self.p1.ra - self.p2.ra < 12)
            or (self.p2.ra > self.p1.ra and self.p2.ra - self.p1.ra > 12))

        ra_length = abs(self.p1.ra - self.p2.ra)
        if (ra_length) > 12: ra_length = 24 - ra_length
        return (-1 if negative else 1) * ra_length

    def get_length(self):
        avg_dec = mean([self.p1.dec, self.p2.dec]) / 180 * pi
        # Don't draw too many points near the poles - scale ra_length slightly
        ra_length = abs(self.get_ra_delta()) * (cos(avg_dec) / 2 + 0.5)
        return sqrt((ra_length * RA_LENGTH_SCALE) ** 2
            + (self.p1.dec - self.p2.dec) ** 2)

const_re = re.compile(CONST_REGEX)

points_text = open("data/constbnd.dat.txt", "r").read().splitlines()

points = []
points_dict = {}

repeat_counter = 0
new_counter = 0

for line in points_text:
    data = const_re.search(line).groups()
    points.append(ConstellationBoundaryPoint(*data))

line_segments: Set[ConstellationBoundaryLine] = set()

for i in range(len(points) - 1):
    point1: ConstellationBoundaryPoint = points[i]
    point2: ConstellationBoundaryPoint = points[i + 1]
    if not point2.const2: continue
    segment = ConstellationBoundaryLine(point1, point2)
    if segment in line_segments:
        repeat_counter += 1
    else:
        line_segments.add(segment)
        new_counter += 1

print(f"{repeat_counter} repeats")
print(f"{new_counter} new")

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

POINTS_PER_UNIT_LENGTH = 1

int_count = 0

new_line_segments: List[List[ConstellationBoundaryPoint]] = []
out_lines: List[str] = []

for line in line_segments:
    point_count = ceil(line.get_length() * POINTS_PER_UNIT_LENGTH)
    deltaRa = line.get_ra_delta() / point_count
    deltaDec = (line.p2.dec - line.p1.dec) / point_count

    interpolated_points = [
        ConstellationBoundaryPoint(
            (line.p1.ra + i * deltaRa) % 24,
            line.p1.dec + i * deltaDec,
            line.p2.const1 if i > 0 else None,
            line.p2.const2 if i > 0 else None,
            (i == 0 or i == point_count)
        ) for i in range(point_count + 1)
    ]

    for point in interpolated_points:
        new_ra, new_dec = precess_to_2000(point.ra, point.dec)
        point.ra = new_ra
        point.dec = new_dec

    new_line_segments.append(interpolated_points)

for line_segment_set in new_line_segments:
    first_point = True
    for point in line_segment_set:
        if first_point:
            const1 = ""
            const2 = ""
            first_point = False
        else:
            const1 = point.const1
            const2 = point.const2
        ra = point.ra
        dec = point.dec

        dec_string = f"{dec:+.5f}"
        if abs(dec) < 10:
            dec_string = dec_string[0] + "0" + dec_string[1:]

        out_lines.append(
            f"{f'{ra:.5f}':>8s} {dec_string} {const1:4s} {const2:4s}\n"
        )

open("data/bound_20_gen.txt", "w").writelines(out_lines)


# -*- coding: utf-8 -*-
# @Time    : 2021/5/13 10:33
# @File    : 1269. 停在原地的方案数.py
from leetcode import *

# dp[i][j]代表当前剩余操作数为i，所在位置为j的所有方案数。

class Solution:
    def numWays(self, steps: int, arrLen: int) -> int:
        dp, limit = [[0] * (steps + 1) for _ in range(steps + 1)], min(steps, arrLen)
        dp[steps][0] = 1
        for i in range(steps - 1, -1, -1):
            for j in range(limit):
                dp[i][j] = dp[i + 1][j] + dp[i + 1][j - 1] + dp[i + 1][j + 1]
        return dp[0][0] % 1000000007

if __name__ == '__main__':
    steps = 27
    arrLen = 7
    print(Solution().numWays(steps, arrLen))

1269. 停在原地的方案数.py


##################
#
# TESTS FOR THE FUNCTIONS THAT COMPUTE MOMENTS
# OF THE PROJECTED NORMAL DISTRIBUTION
#
##################

import pytest
import torch
import numpy as np
import qr_library as qr
from test_functions import *

# Parameters of simulation
nX = 5
nDim = 20
nSamples = 500000

####################################
####### ISOTROPIC NOISE CASE #######
#######    EXACT FORMULAS    #######
####################################

# Parameters of distribution
mu = make_mu_sin(nX=nX, nDim=nDim)
sigma = 0.5
covariance = make_covariance(nDim=nDim, sigmaScale=sigma, covType='isotropic')
B = torch.eye(nDim)

# Get theoretical estimates
meanT = qr.projected_normal_mean_iso(mu=mu, sigma=sigma)
smT = qr.projected_normal_sm_iso(mu=mu, sigma=sigma)
covT = qr.secondM_2_cov(secondM=smT, mean=meanT)

# Get empirical estimates
meanE, covE, smE = empirical_moments_projected_gaussian(mu, covariance,
                                                        nSamples=nSamples, B=B)

# Get errors
meanErr = torch.max(torch.abs(meanE - meanT)/(meanE+0.02))
covErr = torch.max(torch.abs(covE - covT)/(covE+0.02))
smErr = torch.max(torch.abs(smE - smT)/(smE+0.02))

# Plot covariances
maxN = 5
cols = np.min([nX, maxN])
for i in range(cols):
    maxVal = np.max([torch.max(covE[i, :, :]), torch.max(covT[i, :, :])])
    minVal = np.min([torch.min(covE[i, :, :]), torch.min(covT[i, :, :])])
    # Set min and max values to the color scale
    plt.subplot(4, cols, i+1)
    plt.imshow(covE[i, :, :], vmin=minVal, vmax=maxVal)
    plt.yticks(ticks=[])
    plt.xticks(ticks=[])
    if i == 0:
        plt.ylabel('Empirical')
    plt.subplot(4, cols, i+1+cols)
    plt.imshow(covT[i, :, :], vmin=minVal, vmax=maxVal)
    plt.yticks(ticks=[])
    plt.xticks(ticks=[])
    if i == 0:
        plt.ylabel('Theoretical')
    plt.subplot(4, cols, i+1+2*cols)
    plt.imshow(covE[i, :, :] - covT[i, :, :], vmin=minVal, vmax=maxVal)
    plt.yticks(ticks=[])
    plt.xticks(ticks=[])
    if i == 0:
        plt.ylabel('Difference')
    plt.subplot(4, cols, i+1+3*cols)
    plt.plot(meanE[i, :], label='Empirical')
    plt.plot(meanT[i, :], label='Theoretical')
    plt.legend()
    plt.yticks(ticks=[])
    plt.xticks(ticks=[])
plt.show()

####################################
####### INDEPENDENT NOISE CASE #####
#######  TAYLOR APPROXIMATION ######
####################################

nX = 1
nDim = 10
nSamples = 1000000

# Parameters of distribution
meanType = 'sin'
covType = 'diagonal'
sigma = 1
muMult = 4
approxMethod = 'taylor'

# Instantiate parameters
if meanType == 'sin':
    mu = make_mu_sin(nX=nX, nDim=nDim) * muMult
    mu = torch.abs(mu)
elif meanType == 'ones':
    mu = torch.ones((nX,nDim)) * muMult
elif meanType == 'sparse':
    mu = torch.rand((nX,nDim)) + 0.1
    # Select random indices
    ind = np.random.randint(0, nDim, size=5)
    # Set values to 2
    mu[:,ind] = 2
    mu = mu * muMult

if covType != 'poisson':
    print('not pois')
    covariance = make_covariance(nDim=nDim, sigmaScale=sigma, covType=covType)
    variances = torch.diag(covariance)
elif covType == 'poisson':
    print('pois')
    variances = mu.clone().squeeze() * sigma**2
    variances = torch.abs(variances)
    covariance = torch.diag(variances)
B = torch.eye(nDim)

# Get empirical moments
meanE, covE, smE = empirical_moments_projected_gaussian(mu, covariance,
                                                        nSamples=nSamples, B=B)

# Get theoretical moments
if approxMethod == 'taylor':
    meanT = qr.projected_normal_mean_taylor(mu=mu, variances=variances, order=2)
elif approxMethod == '0th':
    meanT = qr.projected_normal_mean_taylor(mu=mu, variances=variances, order=0)
elif approxMethod == 'empirical':
    meanT = meanE
smT = qr.projected_normal_sm(mu=mu, covariance=covariance, B=B)
covT = qr.secondM_2_cov(smT, meanT)

# Plot covariances
maxN = 5
cols = np.min([nX, maxN])
for i in range(cols):
    maxVal = np.max([torch.max(covE[i, :, :]), torch.max(covT[i, :, :])])
    minVal = np.min([torch.min(covE[i, :, :]), torch.min(covT[i, :, :])])
    # Set min and max values to the color scale
    plt.subplot(4, cols, i+1)
    plt.imshow(covE[i, :, :], vmin=minVal, vmax=maxVal)
    plt.yticks(ticks=[])
    plt.xticks(ticks=[])
    if i == 0:
        plt.ylabel('Empirical')
    plt.subplot(4, cols, i+1+cols)
    plt.imshow(covT[i, :, :], vmin=minVal, vmax=maxVal)
    plt.yticks(ticks=[])
    plt.xticks(ticks=[])
    if i == 0:
        plt.ylabel('Theoretical')
    plt.subplot(4, cols, i+1+2*cols)
    plt.imshow(covE[i, :, :] - covT[i, :, :], vmin=minVal, vmax=maxVal)
    plt.yticks(ticks=[])
    plt.xticks(ticks=[])
    if i == 0:
        plt.ylabel('Difference')
    plt.subplot(4, cols, i+1+3*cols)
    plt.plot(meanE[i, :], label='Empirical')
    plt.plot(meanT[i, :], label='Theoretical')
    plt.legend()
    plt.yticks(ticks=[])
    plt.xticks(ticks=[])
plt.show()

# Plot second moments
#maxN = 5
#cols = np.min([nX, maxN])
#for i in range(cols):
#    maxVal = np.max([torch.max(smE[i, :, :]), torch.max(smT[i, :, :])])
#    minVal = np.min([torch.min(smE[i, :, :]), torch.min(smT[i, :, :])])
#    # Set min and max values to the color scale
#    plt.subplot(4, cols, i+1)
#    plt.imshow(smE[i, :, :], vmin=minVal, vmax=maxVal)
#    plt.yticks(ticks=[])
#    plt.xticks(ticks=[])
#    if i == 0:
#        plt.ylabel('Empirical')
#    plt.subplot(4, cols, i+1+cols)
#    plt.imshow(smT[i, :, :], vmin=minVal, vmax=maxVal)
#    plt.yticks(ticks=[])
#    plt.xticks(ticks=[])
#    if i == 0:
#        plt.ylabel('Theoretical')
#    plt.subplot(4, cols, i+1+2*cols)
#    plt.imshow(smE[i, :, :] - smT[i, :, :], vmin=minVal, vmax=maxVal)
#    plt.yticks(ticks=[])
#    plt.xticks(ticks=[])
#    if i == 0:
#        plt.ylabel('Difference')
#    plt.subplot(4, cols, i+1+3*cols)
#    plt.plot(meanE[i, :], label='Empirical')
#    plt.plot(meanT[i, :], label='Theoretical')
#    plt.legend()
#    plt.yticks(ticks=[])
#    plt.xticks(ticks=[])
#plt.show()

####################################
#######  TAYLOR APPROXIMATION ######
#######     MATHEMATICS       ######
####################################

## TEST THAT THE METHOD FOR COMPUTING MOMENTS WORKS
meanX2 = qr.quadratic_form_mean(mu=mu, covariance=covariance, M=B)
meanXi2 = mu**2 + variances
meanV = meanX2 - meanXi2
varX2 = qr.quadratic_form_var(mu=mu, covariance=covariance, M=B)
varSubtract = 2 * variances**2 + 4 * mu**2 * variances
varV = varX2 - varSubtract

meanV2 = torch.zeros(nDim)
varV2 = torch.zeros(nDim)
for i in range(nDim):
    muRemainder = torch.cat((mu[0,:i], mu[0,i+1:]))
    muRemainder = muRemainder.unsqueeze(0)
    varRemainder = torch.cat((variances[:i], variances[i+1:]))
    covRemainder = torch.diag(varRemainder)
    B2 = torch.eye(nDim-1)
    meanV2[i] = qr.quadratic_form_mean(mu=muRemainder, covariance=covRemainder, M=B2)
    varV2[i] = qr.quadratic_form_var(mu=muRemainder, covariance=covRemainder, M=B2)

## TEST THAT THE METHOD FOR COMPUTING DERIVATIVES WORKS
def f(x, y):
    " f = x/sqrt(x^2+y) "
    return x/(torch.sqrt(x**2+y))

# Function to compute the second derivative of f with respect to x
# using the autograd package
def d2f_dx2_autograd(x, y):
    # First derivative with respect to x
    df_dx = torch.autograd.grad(f(x, y), x, create_graph=True)[0]
    # Second derivative with respect to x (the gradient of df_dx with respect to x)
    d2f_dx2 = torch.autograd.grad(df_dx, x)[0]
    return d2f_dx2

# Function to compute the second derivative of f with respect to y
# using the autograd package
def d2f_dy2_autograd(x, y):
    # First derivative with respect to y
    df_dy = torch.autograd.grad(f(x, y), y, create_graph=True)[0]
    # Second derivative with respect to y (the gradient of df_dy with respect to y)
    d2f_dy2 = torch.autograd.grad(df_dy, y)[0]
    return d2f_dy2

du2_autograd = torch.zeros(nDim)
dv2_autograd = torch.zeros(nDim)
for i in range(nDim):
    x = mu[0,i].clone().detach().requires_grad_(True)
    y = meanV[0,i].clone().detach().requires_grad_(True)
    # Compute the derivative of f with respect to x
    du2_autograd[i] = d2f_dx2_autograd(x, y)
    # Compute the derivative of f with respect to y
    dv2_autograd[i] = d2f_dy2_autograd(x, y)

# Function to compute the second derivative of f with respect to x
du2_fun = qr.proj_normal_dx2(u=mu, v=meanV)
dv2_fun = qr.proj_normal_dv2(u=mu, v=meanV)

print(f'du2_autograd = {du2_autograd.numpy()}')
print(f'du2_fun = {du2_fun.numpy()}')
print(f'dv2_autograd = {dv2_autograd.numpy()}')
print(f'dv2_fun = {dv2_fun.numpy()}')


__autor__ = "鲁旭"

from lib.funcslib import writexlsx as wx
import re
p = r"C:\Users\BenQ\Desktop\无数据.txt"

fp = open(p, mode="r", encoding="utf-8")
s = fp.read()
res = re.compile(r"test_(.+?)\s*\(test_case\.bi\.(.+?)\.case(.+?)\.Test(.+?)\)").findall(s)
print(len(res))

newres=[]
for i in res:
    i = list(i)
    head = i.pop(0)
    i.append(head)
    i.append("无数据")
    print(len(i))
    newres.append(i)
print(newres)

newres.insert(0, ["页面一级菜单", "页面二级菜单", "测试项", "测试项", "有无数据"])

if __name__ == "__main__":
   wx("无数据统计.xlsx",newres)


"""
from floodsystem.stationdata import build_station_list, update_water_levels
from floodsystem.datafetcher import fetch_measure_levels
import matplotlib.pyplot as plt
import datetime
from floodsystem.flood import stations_highest_rel_level
from plot import plot_water_levels

"""
#imports
from floodsystem.datafetcher import fetch_measure_levels
from floodsystem.stationdata import build_station_list, update_water_levels
from floodsystem.plot import plot_water_levels
from flood import stations_highest_rel_level
import matplotlib.pyplot as plt
import datetime

#Provide a program file Task2E.py that plots the water levels over the past 10 days
#for the 5 stations at which the current relative water level is greatest.
def run():
    #Requirements for Task2E
    n = 6
    dt =10
    stations = build_station_list()
    update_water_levels(stations)
    #build list of tuples of stations
    b_tuples = stations_highest_rel_level(stations, n)

    #Let"s convert the list of tuples into a list of stations!
    b=[]
    for station in stations:        #maybe change the order of these two functions?
        for station_tuple in b_tuples:

            if station.name == station_tuple[0]:
                b.append(station)
                break

    print(b)

    # plot data for each station
    for station in b:
        dates, levels = fetch_measure_levels(
            station.measure_id, dt=datetime.timedelta(days=dt))
        if len(dates) == 0 or len(levels) == 0:
            continue  # Test for the stations with incorrect datafetcher responses
        plot_water_levels(station, dates, levels)
        plt.show()

if __name__ == "__main__":
    print("*** Task 2E: CUED Part IA Flood Warning System *** \n")

    # Run Task2E
    run()


from src.app import app
import requests
from flask_restful import reqparse
from src.model.subscription import Subscription
from src.model.subscription_type import SubscriptionType
from src.model.user import User
from flask_jwt_extended import (
    jwt_required,
    get_jwt_identity
)
from random import randint
from datetime import timedelta, date
import base64
from hashlib import sha1
from flask import request
import json

def add_subscription(userid, subscription_type_id):
    user = User.query.get(userid)
    subscription_type = SubscriptionType.query.get(subscription_type_id)

    if subscription_type and user:
        start = date.today()
        end = start + timedelta(days=subscription_type.duration)

        subscription_entity = Subscription(start=start, end=end,
                                           session_number=subscription_type.session_count
                                           , user_id=userid, subscription_type_id=subscription_type_id)

        user.subscriptions.append(subscription_entity)
        subscription_type.subscriptions.append(subscription_entity)

        subscription_entity.save_to_db()

        return 200
    return 404

@app.route('/subscriptions', methods=['GET'])
@jwt_required()
def get_subscriptions_by_userid():
    current_user = get_jwt_identity()
    user = User.find_by_username(current_user)

    if user:
        return {'subscriptions': [subscription.return_one() for subscription in user.subscriptions]}
    else:
        return {'error': 'user not found'}, 404

@app.route('/subscription/<subId>', methods=['GET'])
@jwt_required()
def get_subscription_by_id(subId: int):
    return Subscription.get_by_id(subId)

@app.route('/subscription/<subId>', methods=['DELETE'])
@jwt_required()
def delete_subscription_by_id(subId: int):
    return Subscription.delete_by_id(subId)

@app.route('/create/payment', methods=['POST'])
@jwt_required()
def payment_create():
    parser = reqparse.RequestParser()
    parser.add_argument('subscription_type_id', type=int, required=True, help='This field cannot be left blank')
    data_parse = parser.parse_args()
    username = get_jwt_identity()
    user = User.find_by_username(username)
    user_id = user.id
    sub_type = SubscriptionType.query.get(data_parse["subscription_type_id"])

    private_key = "sandbox_QSenQtvw4T7PDwTXG8ur9gXFzCD02yZSqCpC1rsH"
    public_key = "sandbox_i45987901491"

    data = {}

    data['version'] = 3
    data['public_key'] = public_key
    data['action'] = "pay"
    data["amount"] = sub_type.price
    data["currency"] = "UAH"
    data["language"] = "uk"
    data["description"] = f"Pay for {sub_type.name} subscription."
    data["order_id"] = randint(0, 10000)
    data['server_url'] = 'https://bbbf-46-211-172-63.eu.ngrok.io/callback/payment'
    data["customer"] = user_id
    data["product_description"] = sub_type.id

    data_encd = base64.b64encode(json.dumps(data).encode("utf-8")).decode("ascii")
    signature = base64.b64encode(sha1((private_key + data_encd + private_key).encode("utf-8")).digest())

    params = {"data": data_encd, "signature": signature}

    res = requests.post(url='https://www.liqpay.ua/api/3/checkout', data=params)

    if res.status_code == 200:
        return {"payment_url": res.url}
    else:
        return {"error": "Payment error"}, 404

@app.route('/callback/payment', methods=['POST'])
def payment_callback():
    private_key = "sandbox_QSenQtvw4T7PDwTXG8ur9gXFzCD02yZSqCpC1rsH"

    data_raw = request.values
    signature = base64.b64encode(sha1((private_key + data_raw["data"] + private_key).encode("utf-8")).digest())

    if signature == data_raw["signature"].encode("utf-8"):
        data = json.loads(base64.b64decode(data_raw["data"]).decode("utf-8"))
        if data["status"] == "success":
            user_id = int(data["customer"])
            subscription_type_id = int(data["product_description"])
            res = add_subscription(user_id, subscription_type_id)
            if res == 200:
                return {'message': 'Payment was successful'}
            else:
                return {"error": "Error create subscription"}, 404
        return {"error": f"Payment status: {data['status']}"}, 403
    return {"error": "Wrong signature"}, 403


## Lists

earnings = [86, 63, 68, 59]
print(earnings[0])
print(earnings[2])
earnings[-1] # the same easnings[len(L) - 1]

len(earnings)

for e in earnings:
    print(e * 1.4)

def is_non_decreasing(L):
    for i in range(len(L)-1):
        if L[i] > L[i+1]:
            return False
    return True


import string
alphabet=string.ascii_uppercase
padding=""
def getTable(plain_text,key):
    row_size=0
    col_size=0
    l=len(plain_text)
    if key:
        col_size=len(key)
        row_size=len(plain_text)/col_size
        key=[(int(x)-1) for x in key]
    else:
        i=0
        while row_size*col_size<l:
            if i%2 is 1:
                row_size=row_size+1
            else:
                col_size=col_size+1
            i=i+1
        key=[x for x in range(col_size)]

    table=[["" for i in range(col_size)]for j in range(row_size)]
    i=0
    global padding
    if "X" not in plain_text:
        padding="X"
    else:
        diff=set(alphabet)-set(plain_text)
        padding=diff.pop()
    return table,row_size,col_size,key

def encrypt(plain_text,key=""):
    plain_text=plain_text.replace(" ","").upper()
    table,row_size,col_size,key=getTable(plain_text,key)
    i=0
    l=len(plain_text)
    for row in range(row_size):
        for col in range(col_size):
            if i<l:
                table[row][col]=plain_text[i]
                i=i+1
            else:
                table[row][col]=padding
    cipher_text=""
    for col in key:
        for row in range(row_size):
            cipher_text+=table[row][col]
    return cipher_text

def decrypt(cipher_text,key=""):
    plain_text=""
    table,row_size,col_size,key=getTable(cipher_text.replace(padding,""),key)
    i=0
    l=len(cipher_text)
    for col in key:
        for row in range(row_size):
            table[row][col]=cipher_text[i]
            i=i+1
    for row in range(row_size):
        for col in range(col_size):
            plain_text+=table[row][col]
    return plain_text.replace(padding,"")

plain_text=raw_input("Enter plain text :")
ch=raw_input("Do you have a key? :")
key=""
if ch is 'y':
    key=raw_input("Enter the key")
cipher_text=encrypt(plain_text,key)
print(cipher_text)
ch=raw_input("Do you want to decrypt?")
if ch is 'y':
     print("Decrypted Text: "+decrypt(cipher_text,key))


# !/usr/bin/python
# -*- coding: utf-8 -*-

# author      : Tao Qitian
# email       : taoqt@mail2.sysu.edu.cn
# datetime    : 2021/4/27 18:55
# filename    : solution.py
# description : LC 543 二叉树的直径

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

class Solution:
    def diameterOfBinaryTree(self, root: TreeNode) -> int:
        self.diameter = 0

        def get_depth(root: TreeNode) -> int:
            """ 计算二叉树深度 """
            if not root:
                return 0

            # 计算左子树深度
            left_depth = get_depth(root.left)
            # 计算右子树深度
            right_depth = get_depth(root.right)
            # 二叉树的直径 = 所有节点的左子树深度与右子树深度之和的最大值
            self.diameter = max(left_depth + right_depth, self.diameter)
            # 加上根节点，深度加一
            return max(left_depth, right_depth) + 1

        get_depth(root)
        return self.diameter


import datetime
import unittest

from habit import Habit

class HabitTestCase(unittest.TestCase):
    def setUp(self):
        self.habit = Habit("test_habit", "", "daily", "test", 1, [],
                           datetime.date(2030, 7, 20).strftime("%Y-%m-%d %H:%M:%S"), "add")

    def test_complete_habit(self):
        self.habit.complete_habit()
        self.assertEqual(self.habit.progress_entries[-1]["timestamp"].date(),
                         datetime.datetime.now().date())

    def test_reset_current_streak(self):
        self.habit.current_streak = 5
        self.habit.reset_current_streak()
        self.assertEqual(self.habit.current_streak, 0)

    def test_update_longest_streak(self):
        self.habit.current_streak = self.habit.longest_streak + 5
        self.habit.update_longest_streak()
        self.assertGreaterEqual(self.habit.longest_streak, self.habit.current_streak)

    def test_is_completed_today(self):
        today_habit = Habit("completed_today", "", "daily", "test", 1, [],
                            datetime.date(2030, 7, 20).strftime("%Y-%m-%d %H:%M:%S"), "add")
        today_habit.complete_habit()
        self.assertTrue(not self.habit.is_completed_today() and today_habit.is_completed_today())

    def test_days_remaining(self):
        delta = datetime.timedelta(days=50)
        default_days = self.habit.days_remaining()
        self.habit.next_deadline = datetime.datetime.now() + delta
        days = self.habit.days_remaining()
        self.assertTrue(default_days == None and days + 1 == delta.days)

    def test_update_next_deadline(self):
        self.habit.update_next_deadline()
        self.assertEqual(datetime.datetime.fromisoformat(self.habit.next_deadline).date(),
                         (datetime.datetime.now() + datetime.timedelta(days=1)).date())

    def test_update_success_status(self):
        successes = 5
        streak = 5

        self.habit.successes = successes
        self.habit.current_streak = streak

        today_habit = Habit("completed_today", "", "daily", "test", 1,
                            [{"comment": "test", "timestamp": datetime.datetime.now()}],
                            datetime.date(2030, 7, 20).strftime("%Y-%m-%d %H:%M:%S"), "add")
        today_habit.successes = successes
        today_habit.current_streak = streak

        self.habit.update_success_status()
        def_successes = self.habit.successes
        def_streak = self.habit.current_streak

        today_habit.update_success_status()
        tod_successes = today_habit.successes
        tod_streak = today_habit.current_streak

        self.assertTrue(def_successes == successes
                        and def_streak == 0
                        and tod_successes == successes + 1
                        and tod_streak == streak + 1)

if __name__ == "__main__":
    unittest.main()


import cv2, sys

"""
    1. O arquivo setup.py faz o download das imagens negativas e cria os diretórios necessários
    2. No arquivo commands.txt estão os comandos utilizados para a fase de treinamento

    Processamento de Imagens. BCC FURB 2018/2
    Djonathan Krause, Rafael Rossi.
"""

# Parametros
DIR_CASCADE = '../data/hand_cascade.xml'
MIN_SIZE = 50           # 50
SCALE_FACTOR = 1.1      # 1.1
MIN_NEIGHBORS = 3       # 5

def track():
    # Carrega o arquivo com o cascade
    cascade = cv2.CascadeClassifier(DIR_CASCADE)

    # Inicia a captura de video
    video_capture = cv2.VideoCapture(0)

    while True:
        # Captura frame por frame do vídeo e converte para cinza
        retval, frame = video_capture.read()
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        # Detecta caracteristicas especificadas no Haar Cascade
        objects = cascade.detectMultiScale(gray, scaleFactor=SCALE_FACTOR, minNeighbors=MIN_NEIGHBORS, minSize=(MIN_SIZE, MIN_SIZE))

        # Desenha retangulo no objeto
        for (x, y, w, h) in objects:
            cv2.rectangle(frame, (x, y), (x+w, y+h), (50, 50, 200), 2)

        # Mostra video
        cv2.imshow('Video', frame)

        # q pra sair
        if cv2.waitKey(1) & 0xFF == ord('q'):
           sys.exit()

track()


#
# @lc app=leetcode id=140 lang=python
#
# [140] Word Break II
#

# @lc code=start
class Solution(object):
   def wordBreak(self, s, wordDict):
        """
        :type s: str
        :type wordDict: List[str]
        :rtype: List[str]
        """
        hashmap = {}
        wordSet = set(wordDict)
        def dfs(s):
            if s in hashmap:
                return hashmap[s]
            path = []
            if s in wordSet:
                path.append(s)
            for i in range(1, len(s)):
                r = s[i:]
                if r in wordSet:
                    path += [l +" "+ r for l in dfs(s[:i])]
            hashmap[s] = path
            return hashmap[s]
        return dfs(s)

# @lc code=end


from sklearn import ensemble
import features
import numpy as np
import retrieval

if __name__ == '__main__':

    films = retrieval.read_film_csv('films.csv')
    train_films = films[np.logical_and(films['year'] >= 2007, films['year'] <= 2011)]
    test_films = films[films['year'] == 2012]

    data = features.train_and_test_data(train_films, test_films, 'revisions', verbose=True)
    (base_train_features, train_response, base_test_features, test_response) = data

    subseq = features.subsequence_scores(films, features.people_by_genres_jaccard, verbose=True)
    train_features = features.attach_similar_revenue(films, base_train_features, subseq)
    test_features = features.attach_similar_revenue(films, base_test_features, subseq)
    train_features_nowiki = train_features.copy()
    test_features_nowiki = test_features.copy()

    del train_features_nowiki['avg_size']
    del train_features_nowiki['edit_runs_0_7']
    del train_features_nowiki['edit_runs_7_28']
    del train_features_nowiki['word_extfile']
    del train_features_nowiki['word_headings']
    del train_features_nowiki['word_imax']
    del test_features_nowiki['avg_size']
    del test_features_nowiki['edit_runs_0_7']
    del test_features_nowiki['edit_runs_7_28']
    del test_features_nowiki['word_extfile']
    del test_features_nowiki['word_headings']
    del test_features_nowiki['word_imax']

    model = ensemble.GradientBoostingRegressor(n_estimators=100, max_depth=2)
    model = model.fit(train_features, train_response)
    result = features.prediction_result(test_films, model, test_features, test_response)

    model_nowiki = ensemble.GradientBoostingRegressor(n_estimators=100, max_depth=2)
    model_nowiki = model_nowiki.fit(train_features_nowiki, train_response)
    result_nowiki = features.prediction_result(test_films, model_nowiki, test_features_nowiki, test_response)

    print('With Wikipedia:')
    print(result)

    print('Without Wikipedia:')
    print(result_nowiki)


import csv
from typing import IO, Optional, Sequence, Type, Union

def create_csv_dict_reader(
    text_stream: IO[str],
    csv_dialect: Type[csv.Dialect],
    row_dict_extra_fields_key: Union[str, None] = None,
    expected_fields_strict: bool = True,
    expected_field_names: Optional[Sequence[str]] = None,
) -> csv.DictReader:
    """
    Create a CSV dict reader with custom options.

    :param text_stream:
    :param row_dict_extra_fields_key:
        CSV row dict key under which the extra data in the row will be saved
    :param csv_dialect:
    :param expected_fields_strict:
    :param expected_field_names:
        (required if ``expected_field_names`` is True)
    :return: a CSV DictReader

    """
    csv_reader = csv.DictReader(
        text_stream,
        fieldnames=None,  # the values of the first row will be used as the fieldnames
        restkey=row_dict_extra_fields_key,
        dialect=csv_dialect,
    )

    if expected_fields_strict:
        if expected_field_names:
            if csv_reader.fieldnames is None:
                raise Exception(
                    "Programming error: when a 'csv.DictReader' instance is created with"
                    "'fieldnames=None', the attribute will be set to the values of the first row."
                )
            if tuple(csv_reader.fieldnames) != expected_field_names:
                raise ValueError(
                    "CSV file field names do not match those expected, or their order.",
                    csv_reader.fieldnames,
                )
        else:
            raise ValueError(
                "Param 'expected_field_names' is required if 'expected_fields_strict' is True."
            )

    return csv_reader


import logging

# A nosec comment is appended to the following line in order to disable the B404 check.
# In this file the input of the module subprocess is trusted.
import subprocess  # nosec B404
from datetime import datetime
from typing import List, Union

from common.schedulers.slurm_commands import DEFAULT_SCONTROL_COMMAND_TIMEOUT, SCONTROL
from common.utils import (
    SlurmCommandError,
    SlurmCommandErrorHandler,
    check_command_output,
    run_command,
    validate_subprocess_argument,
)
from retrying import retry
from slurm_plugin.slurm_resources import SlurmReservation

logger = logging.getLogger(__name__)

SCONTROL_SHOW_RESERVATION_OUTPUT_AWK_PARSER = (
    'awk \'BEGIN{{RS="\\n\\n" ; ORS="######\\n";}} {{print}}\' | '
    + "grep -oP '^(ReservationName=\\S+)|(?<!Next)(State=\\S+)|(Users=\\S+)|(Nodes=\\S+)|(######)'"
)

def _create_or_update_reservation(
    base_command: str,
    name: str,
    nodes: str = None,
    partition: str = None,
    user: str = None,
    start_time: Union[datetime, str] = None,  # 'now' is accepted as a value
    duration: Union[int, str] = None,  # 'infinite' is accepted as a value
    number_of_nodes: int = None,
    flags: str = None,
    command_timeout=DEFAULT_SCONTROL_COMMAND_TIMEOUT,
    raise_on_error=True,
):
    """
    Create or update slurm reservation, adding all the parameters.

    Official documentation is https://slurm.schedmd.com/reservations.html
    """
    cmd = _add_param(base_command, "ReservationName", name)
    cmd = _add_param(cmd, "nodes", nodes)
    cmd = _add_param(cmd, "partition", partition)
    cmd = _add_param(cmd, "user", user)
    if isinstance(start_time, datetime):
        # Convert start time to format accepted by slurm command
        cmd = _add_param(cmd, "starttime", start_time.strftime("%Y-%m-%dT%H:%M:%S"))
    elif start_time:
        cmd = _add_param(cmd, "starttime", start_time)
    cmd = _add_param(cmd, "duration", duration)
    cmd = _add_param(cmd, "nodecnt", number_of_nodes)
    cmd = _add_param(cmd, "flags", flags)

    run_command(cmd, raise_on_error=raise_on_error, timeout=command_timeout, shell=True)  # nosec B604

@retry(
    stop_max_attempt_number=2,
    wait_fixed=1000,
    retry_on_exception=lambda exception: isinstance(exception, SlurmCommandError),
)
@SlurmCommandErrorHandler.handle_slurm_command_error
def create_slurm_reservation(
    name: str,
    nodes: str = "ALL",
    partition: str = None,
    user: str = "slurm",
    start_time: Union[datetime, str] = None,  # 'now' is accepted as a value
    duration: Union[int, str] = None,  # 'infinite' is accepted as a value
    number_of_nodes: int = None,
    flags: str = "maint",
    command_timeout: int = DEFAULT_SCONTROL_COMMAND_TIMEOUT,
    raise_on_error: bool = True,
):
    """
    Create slurm reservation with scontrol call.

    The command to create a reservation is something like the following:
    scontrol create reservation starttime=2009-02-06T16:00:00 duration=120 user=slurm flags=maint nodes=ALL
    scontrol create reservation user=root partition=queue1 starttime=noon duration=60 nodecnt=10

    We're using slurm as default user because it is the default Slurm administrator user in ParallelCluster,
    this is the user running slurmctld daemon.
    "maint" flag permits to overlap existing reservations.
    Official documentation is https://slurm.schedmd.com/reservations.html
    """
    cmd = f"{SCONTROL} create reservation"

    logger.debug("Creating Slurm reservation with command: %s", cmd)
    _create_or_update_reservation(
        cmd, name, nodes, partition, user, start_time, duration, number_of_nodes, flags, command_timeout, raise_on_error
    )

@retry(
    stop_max_attempt_number=2,
    wait_fixed=1000,
    retry_on_exception=lambda exception: isinstance(exception, SlurmCommandError),
)
@SlurmCommandErrorHandler.handle_slurm_command_error
def update_slurm_reservation(
    name: str,
    nodes: str = None,
    partition: str = None,
    user: str = None,
    start_time: Union[datetime, str] = None,  # 'now' is accepted as a value
    duration: Union[int, str] = None,  # 'infinite' is accepted as a value
    number_of_nodes: int = None,
    flags: str = None,
    command_timeout: int = DEFAULT_SCONTROL_COMMAND_TIMEOUT,
    raise_on_error: bool = True,
):
    """
    Update slurm reservation with scontrol call.

    The command to update a reservation is something like the following:
    scontrol update ReservationName=root_3 duration=150 users=admin

    Official documentation is https://slurm.schedmd.com/reservations.html
    """
    cmd = f"{SCONTROL} update"

    logger.debug("Updating Slurm reservation with command: %s", cmd)
    _create_or_update_reservation(
        cmd, name, nodes, partition, user, start_time, duration, number_of_nodes, flags, command_timeout, raise_on_error
    )

@retry(
    stop_max_attempt_number=2,
    wait_fixed=1000,
    retry_on_exception=lambda exception: isinstance(exception, SlurmCommandError),
)
@SlurmCommandErrorHandler.handle_slurm_command_error
def delete_slurm_reservation(
    name: str,
    command_timeout: int = DEFAULT_SCONTROL_COMMAND_TIMEOUT,
    raise_on_error: bool = True,
):
    """
    Delete slurm reservation with scontrol call.

    The command to delete a reservation is something like the following:
    scontrol delete ReservationName=root_6

    Official documentation is https://slurm.schedmd.com/reservations.html
    """
    cmd = f"{SCONTROL} delete"
    cmd = _add_param(cmd, "ReservationName", name)

    logger.debug("Deleting Slurm reservation with command: %s", cmd)
    run_command(cmd, raise_on_error=raise_on_error, timeout=command_timeout, shell=True)  # nosec B604

def _add_param(cmd, param_name, value):
    """If the given value is not None, validate it and concatenate ' param_name=value' to cmd."""
    if value:
        validate_subprocess_argument(value)
        cmd += f" {param_name}={value}"
    return cmd

@retry(
    stop_max_attempt_number=2,
    wait_fixed=1000,
    retry_on_exception=lambda exception: isinstance(exception, SlurmCommandError),
)
@SlurmCommandErrorHandler.handle_slurm_command_error
def is_slurm_reservation(
    name: str,
    command_timeout: int = DEFAULT_SCONTROL_COMMAND_TIMEOUT,
    raise_on_error: bool = True,
):
    """
    Check if slurm reservation exists, by retrieving information with scontrol call.

    Return True if reservation exists, False otherwise.
    Raise a CalledProcessError if the command fails for other reasons.

    $ scontrol show ReservationName=root_5
    Reservation root_5 not found
    $ echo $?
    1

    $ scontrol show ReservationName=root_6
    ReservationName=root_6 StartTime=2023-10-13T15:57:03 EndTime=2024-10-12T15:57:03 Duration=365-00:00:00
    Nodes=q1-st-cr2-1,q2-dy-cr4-[1-5] NodeCnt=6 CoreCnt=481 Features=(null) PartitionName=(null) Flags=MAINT,SPEC_NODES
    TRES=cpu=481
    Users=root Groups=(null) Accounts=(null) Licenses=(null) State=ACTIVE BurstBuffer=(null) Watts=n/a
    MaxStartDelay=(null)
    $ echo $?
    0

    Official documentation is https://slurm.schedmd.com/reservations.html
    """
    cmd = f"{SCONTROL} show"
    cmd = _add_param(cmd, "ReservationName", name)

    try:
        logger.debug("Retrieving Slurm reservation with command: %s", cmd)
        output = check_command_output(
            cmd, raise_on_error=raise_on_error, timeout=command_timeout, shell=True, log_error=False
        )  # nosec B604
        reservation_exists = f"ReservationName={name}" in output

    except subprocess.CalledProcessError as e:
        expected_output = f"Reservation {name} not found"
        error = f" Error is: {e.stderr.rstrip()}." if e.stderr else ""
        output = f" Output is: {e.stdout.rstrip()}." if e.stdout else ""
        if expected_output in error or expected_output in output:
            logger.debug(f"Slurm reservation {name} not found.")
            reservation_exists = False
        else:
            msg = f"Failed when retrieving Slurm reservation info with command {cmd}.{error}{output} {e}"
            logger.error(msg)
            raise SlurmCommandError(msg)

    return reservation_exists

@retry(
    stop_max_attempt_number=2,
    wait_fixed=1000,
    retry_on_exception=lambda exception: isinstance(exception, SlurmCommandError),
)
@SlurmCommandErrorHandler.handle_slurm_command_error
def get_slurm_reservations_info(
    command_timeout=DEFAULT_SCONTROL_COMMAND_TIMEOUT, raise_on_error: bool = True
) -> List[SlurmReservation]:
    """
    List existing slurm reservations with scontrol call.

    The output of the command is something like the following:
    $ scontrol show reservations
    ReservationName=root_7 StartTime=2023-10-25T09:46:49 EndTime=2024-10-24T09:46:49 Duration=365-00:00:00
    Nodes=queuep4d-dy-crp4d-[1-5] NodeCnt=5 CoreCnt=480 Features=(null) PartitionName=(null) Flags=MAINT,SPEC_NODES
    TRES=cpu=480
    Users=root Groups=(null) Accounts=(null) Licenses=(null) State=ACTIVE BurstBuffer=(null) Watts=n/a
    MaxStartDelay=(null)

    Official documentation is https://slurm.schedmd.com/reservations.html
    """
    # awk is used to replace the \n\n record separator with '######\n'
    show_reservations_command = f"{SCONTROL} show reservations | {SCONTROL_SHOW_RESERVATION_OUTPUT_AWK_PARSER}"
    slurm_reservations_info = check_command_output(
        show_reservations_command, raise_on_error=raise_on_error, timeout=command_timeout, shell=True
    )  # nosec B604

    return _parse_reservations_info(slurm_reservations_info)

def _parse_reservations_info(slurm_reservations_info: str) -> List[SlurmReservation]:
    """Parse slurm reservations info into SlurmReservation objects."""
    # $ /opt/slurm/bin/scontrol show reservations awk 'BEGIN{{RS="\n\n" ; ORS="######\n";}} {{print}}' |
    # grep -oP '^(ReservationName=\S+)|(?<!Next)(State=\S+)|(Users=\S+)|(Nodes=\S+)|(######)'
    # ReservationName=root_8
    # Nodes=queuep4d-dy-crp4d-[1-5]
    # Users=root
    # State=ACTIVE
    # ######
    # ReservationName=root_9
    # Nodes=queue1-st-crt2micro-1
    # Users=root
    # State=ACTIVE
    # ######
    map_slurm_key_to_arg = {"ReservationName": "name", "Nodes": "nodes", "Users": "users", "State": "state"}

    reservation_info = slurm_reservations_info.split("######\n")
    slurm_reservations = []
    for reservation in reservation_info:
        lines = reservation.splitlines()
        kwargs = {}
        for line in lines:
            key, value = line.split("=")
            kwargs[map_slurm_key_to_arg[key]] = value
        if lines:
            reservation = SlurmReservation(**kwargs)
            slurm_reservations.append(reservation)

    return slurm_reservations


import numpy as np

BOARD_SIZE = 8

class Game(object):
    def __init__(self):
        self.board_size = BOARD_SIZE
        self.black_chess = set()
        self.white_chess = set()
        self.board = [[0 for j in range(self.board_size)] for i in range(self.board_size)]

        self.black_chess.add((BOARD_SIZE // 2 - 1, BOARD_SIZE // 2))
        self.black_chess.add((BOARD_SIZE // 2, BOARD_SIZE // 2 - 1))
        self.white_chess.add((BOARD_SIZE // 2 - 1, BOARD_SIZE // 2 - 1))
        self.white_chess.add((BOARD_SIZE // 2, BOARD_SIZE // 2))

        # 1表示黑棋，-1表示白棋
        for item in self.black_chess:
            self.board[item[0]][item[1]] = 1
        for item in self.white_chess:
            self.board[item[0]][item[1]] = -1

    def Gameover(self):
        """判断游戏是否结束，即整个棋盘下满了棋

        Returns:
            int -- 没结束返回0；黑棋赢返回1；白棋赢返回-1
        """
        if len(self.black_chess) + len(self.white_chess) == pow(self.board_size, 2) \
                or len(self.black_chess) * len(self.white_chess) == 0:
            return 1 if len(self.black_chess) > len(self.white_chess) else -1
        else:
            return 0

    def Get_Valid_Pos(self, my_chess, oppo_chess):
        """找出所有合法的落子点，即该位置落子后必须存在对方的棋需要翻转

        Arguments:
            my_chess {set} -- 己方当前的所有棋
            oppo_chess {set} -- 对方当前的所有棋

        Returns:
            valid_pos {set} -- 合法位置的集合,位置表示为元组(x,y)
        """
        valid_pos = set()
        for (x, y) in my_chess:
            temp = (x, y)
            while (x - 1, y) in oppo_chess:
                x -= 1
            if (x, y) != temp and x - 1 >= 0 and (x - 1, y) not in my_chess:
                valid_pos.add((x - 1, y))

            (x, y) = temp
            while (x + 1, y) in oppo_chess:
                x += 1
            if (x, y) != temp and x + 1 < self.board_size and (x + 1, y) not in my_chess:
                valid_pos.add((x + 1, y))

            (x, y) = temp
            while (x, y - 1) in oppo_chess:
                y -= 1
            if (x, y) != temp and y - 1 >= 0 and (x, y - 1) not in my_chess:
                valid_pos.add((x, y - 1))

            (x, y) = temp
            while (x, y + 1) in oppo_chess:
                y += 1
            if (x, y) != temp and y + 1 < self.board_size and (x, y + 1) not in my_chess:
                valid_pos.add((x, y + 1))

            (x, y) = temp
            while (x - 1, y - 1) in oppo_chess:
                x -= 1
                y -= 1
            if (x, y) != temp and x - 1 >= 0 and y - 1 >= 0 and (x - 1, y - 1) not in my_chess:
                valid_pos.add((x - 1, y - 1))

            (x, y) = temp
            while (x + 1, y + 1) in oppo_chess:
                x += 1
                y += 1
            if (x, y) != temp and x + 1 < self.board_size and y + 1 < self.board_size and (
            x + 1, y + 1) not in my_chess:
                valid_pos.add((x + 1, y + 1))

            (x, y) = temp
            while (x + 1, y - 1) in oppo_chess:
                x += 1
                y -= 1
            if (x, y) != temp and x + 1 < self.board_size and y - 1 >= 0 and (x + 1, y - 1) not in my_chess:
                valid_pos.add((x + 1, y - 1))

            (x, y) = temp
            while (x - 1, y + 1) in oppo_chess:
                x -= 1
                y += 1
            if (x, y) != temp and x - 1 >= 0 and y + 1 < self.board_size and (x - 1, y + 1) not in my_chess:
                valid_pos.add((x - 1, y + 1))
        return valid_pos

    def Reverse(self, last_pos, my_chess, oppo_chess, my_color):
        """每一次有一步新的落子后，把新的落子一方夹着的棋翻转；
            即把对方一部分棋归入己方
        Arguments:
            last_pos {tuple} -- 我方刚刚落子的位置
            my_chess {set} -- 当前我方的棋面，包含刚落子的位置
            oppo_chess {set} -- 当前对方的棋面
            my_color {int} -- 1表示黑色，-1表示白色
        """
        # print(last_pos)
        (x_, y_) = last_pos
        for (x, y) in my_chess:
            if (x, y) != (x_, y_):
                temp = []
                if x == x_:
                    temp = [(x, yy) for yy in range(min(y, y_) + 1, max(y, y_))]
                elif y == y_:
                    temp = [(xx, y) for xx in range(min(x, x_) + 1, max(x, x_))]
                elif x + y == x_ + y_:
                    const = x + y
                    temp = [(xx, const - xx) for xx in range(min(x, x_) + 1, max(x, x_))]
                elif x - y == x_ - y_:
                    const = x - y
                    temp = [(xx, xx - const) for xx in range(min(x, x_) + 1, max(x, x_))]

                if all(map(lambda para: para in oppo_chess, temp)):
                    temp = set(temp)
                    my_chess = my_chess.union(temp)
                    oppo_chess = oppo_chess.difference(temp)
        if my_color == 1:
            self.black_chess = my_chess
            self.white_chess = oppo_chess
        else:
            self.black_chess = oppo_chess
            self.white_chess = my_chess
        # 更新board！！！！！
        for (x, y) in self.black_chess:
            self.board[x][y] = 1
        for (x, y) in self.white_chess:
            self.board[x][y] = -1

    def Get_State(self):
        """返回当前棋盘的状态

        Returns:
            64维向量
        """
        return np.array(self.board, dtype=np.int).flatten()

    def Add(self, my_color, pos):
        """加入一个新的棋子

        Arguments:
            my_color {int} -- 1表示黑棋，-1表示白棋
            pos {int} -- 位置
        """
        if pos != 64:
            (x, y) = (pos // self.board_size, pos % self.board_size)
            self.board[x][y] = my_color
            if my_color == 1:
                self.black_chess.add((x, y))
                self.board[x][y] = 1
            elif my_color == -1:
                self.white_chess.add((x, y))
                self.board[x][y] = -1

            if my_color == 1:
                self.Reverse((x, y), self.black_chess, self.white_chess, my_color)
            elif my_color == -1:
                self.Reverse((x, y), self.white_chess, self.black_chess, my_color)

    def Display(self):
        for n in range(self.board_size):
            print('----', end='')
        print('')
        for m in range(self.board_size):
            for n in range(self.board_size):
                if self.board[m][n] == 1:
                    print("| x ", end='')
                elif self.board[m][n] == -1:
                    print("| o ", end='')
                else:
                    print("|   ", end='')
            print('|', m)
            for n in range(self.board_size):
                print('----', end='')
            print('')
        for n in range(self.board_size):
            print('  {} '.format(n), end='')
        print('\n\n')


# Сравнение объектов класса

from dataclasses import dataclass

@dataclass(order = True)
class Person:
    age: int
    fName: str
    sName: str

p1 = Person(18, 'Rafael', 'Raf')
print(p1)
p2 = Person(17, 'Leanardo', 'Leo')
print(p2)

if p1 > p2:
  print('p1 старше p2' )
else:
  print('p2 старше p1')

2 курс/Программирование/4 семестр/ЛР4_Нововведения_Python/comparison.py


s="Python is widely used by a number of big companies"
word="aeiou"
print("모음 : ",end="")
count = 0
n=0
while n < len(s):
    if s[n] in word :
        count=count+1
        print(s[n],end=" ")
    n = n+1
print()
print("모음 개수 : %s" %count)


def good_vs_evil(good, evil):

    good_worth = [1, 2, 3, 3, 4, 10]
    evil_worth = [1, 2, 2, 2, 3, 5, 10]

    good_sum = sum(g_worth * int(g_num) for g_worth, g_num in zip(good_worth, good.split()))
    evil_sum = sum(e_worth * int(e_num) for e_worth, e_num in zip(evil_worth, evil.split()))

    if good_sum > evil_sum:
        return "Battle Result: Good triumphs over Evil"
    elif good_sum < evil_sum:
        return "Battle Result: Evil eradicates all trace of Good"
    else:
        return "Battle Result: No victor on this battle field"