import sys
import os
from multiprocessing import Pool
import numpy as np
from pylinac.core import image as pylinac_image
import matplotlib.style
import matplotlib
matplotlib.use('Agg')
from matplotlib.figure import Figure

# To revert back to matplotlib 1.0 style
matplotlib.style.use('classic')

parent_module = sys.modules['.'.join(__name__.split('.')[:-1]) or '__main__']
if __name__ == '__main__' or parent_module.__name__ == '__main__':
    #sys.path.append(os.path.abspath(os.path.realpath("python_packages")))
    import config
    from python_packages.bottlepy.bottle import Bottle, request, TEMPLATE_PATH, template, redirect, response
    from python_packages import mpld3
    import general_functions
    import RestToolbox_modified as RestToolbox
    import field_rotation as field_rotation
else:
    from . import config
    from .python_packages.bottlepy.bottle import Bottle, request, TEMPLATE_PATH, template, redirect, response
    from .python_packages import mpld3
    from . import general_functions
    from . import RestToolbox_modified as RestToolbox
    from . import field_rotation as field_rotation

CUR_DIR = os.path.realpath(os.path.dirname(__file__))

# Path to Bottle templates
TEMPLATE_PATH.insert(0, os.path.join(CUR_DIR, 'views'))

# Url to some mpld3 library
D3_URL = config.D3_URL
MPLD3_URL = config.MPLD3_URL

PI = np.pi

# Here starts the bottle server
fieldrot_app = Bottle()

@fieldrot_app.route('/fieldrot', method="POST")
def fieldrot():
    colormaps = ["Greys", "brg", "gray", "prism"]
    displayname = request.forms.hidden_displayname
    username = request.get_cookie("account", secret=config.SECRET_KEY)
    if not username:
        redirect("/login")
    try:
        variables = general_functions.Read_from_dcm_database()
        variables["colormaps"] = colormaps
        variables["displayname"] = displayname
        response.set_cookie("account", username, secret=config.SECRET_KEY, samesite="lax")
    except ConnectionError:
        return template("error_template", {"error_message": "Orthanc is refusing connection."})
    return template("fieldrot", variables)

def fieldrot_helperf_catch_error(args):
    try:
        return fieldrot_helperf(args)
    except Exception as e:
        return template("error_template", {"error_message": str(e)})

def fieldrot_helperf(args):

    test_type = args["test_type"]
    direction = args["direction"]
    direction2 = args["direction2"]
    number_samples = args["number_samples"]
    margin = args["margin"]
    clipbox = args["clipbox"]
    invert = args["invert"]
    w1 = args["w1"]
    w2 = args["w2"]
    colormap = args["colormap"]
    med_filter = args["med_filter"]
    general_functions.set_configuration(args["config"])
    imgdescription = args["imgdescription"]
    station = args["station"]
    displayname = args["displayname"]
    acquisition_datetime = args["acquisition_datetime"]
    high_contrast = args["high_contrast"]

    # Collect data for "save results"
    dicomenergy = general_functions.get_energy_from_imgdescription(imgdescription)
    user_machine, user_energy = general_functions.get_user_machine_and_energy(station, dicomenergy)
    machines_and_energies = general_functions.get_machines_and_energies(general_functions.get_treatmentunits_fieldrotation())
    tolerances = general_functions.get_tolerance_user_machine_fieldrotation(user_machine)  # If user_machne has specific tolerance

    if not tolerances:
        tt = general_functions.get_settings_fieldrotation()
    else:
        tt = tolerances[0]

    (tolerance_collabs, tolerance_collrel, tolerance_couchrel) = tt

    tolerance_collabs = float(tolerance_collabs)
    tolerance_collrel = float(tolerance_collrel)
    tolerance_couchrel = float(tolerance_couchrel)

    save_results = {
                    "user_machine": user_machine,
                    "user_energy": user_energy,
                    "machines_and_energies": machines_and_energies,
                    "displayname": displayname,
                    "nominal_angle": np.linspace(360, -360, 49).tolist()
                    }

    try:
        temp_folder1, file_path1 = RestToolbox.GetSingleDcm(config.ORTHANC_URL, w1)
        temp_folder2, file_path2 = RestToolbox.GetSingleDcm(config.ORTHANC_URL, w2)
    except:
        return template("error_template", {"error_message": "Cannot read images."})

    # Load first image
    try:
        img1 = pylinac_image.DicomImage(file_path1)
        # Here we force pixels to background outside of box:
        if clipbox != 0:
            try:
                img1.check_inversion_by_histogram(percentiles=[4, 50, 96]) # Check inversion otherwise this might not work
                general_functions.clip_around_image(img1, clipbox)
            except Exception as e:
                return template("error_template", {"error_message": "Unable to apply clipbox. "+str(e)})
        else:
            img1.remove_edges(pixels=2)
        if invert:
            img1.invert()
        else:
            img1.check_inversion()
        img1.flipud()
    except:
        return template("error_template", {"error_message": "Cannot read image."})
    try:
        img2 = pylinac_image.DicomImage(file_path2)
        if clipbox != 0:
            try:
                img2.check_inversion_by_histogram(percentiles=[4, 50, 96]) # Check inversion otherwise this might not work
                general_functions.clip_around_image(img2, clipbox)
            except Exception as e:
                return template("error_template", {"error_message": "Unable to apply clipbox. "+str(e)})
        else:
            img2.remove_edges(pixels=2)
        if invert:
            img2.invert()
        else:
            img2.check_inversion()
        img2.flipud()
    except:
        return template("error_template", {"error_message": "Cannot read image."})

    # Apply some filtering
    if med_filter > 0:
        img1.filter(med_filter)
        img2.filter(med_filter)

    # Get radiation field box:
    try:
        center_cax1, rad_field_bounding_box1, field_corners1 = field_rotation._find_field_centroid(img1)
        center_cax2, rad_field_bounding_box2, field_corners2 = field_rotation._find_field_centroid(img2)
    except Exception as e:
        return template("error_template", {"error_message": str(e)})

    field_corners1 = field_corners1.astype(int)
    field_corners2 = field_corners2.astype(int)

    # Set colormap
    cmap = matplotlib.cm.get_cmap(colormap)

    if test_type == "Collimator absolute":
        # Get BBs
        try:
            if high_contrast:
                bbs1 = field_rotation._find_bb2(img1, rad_field_bounding_box1)
                bbs2 = field_rotation._find_bb2(img2, rad_field_bounding_box2)
            else:
                bbs1 = field_rotation._find_bb(img1, rad_field_bounding_box1)
                bbs2 = field_rotation._find_bb(img2, rad_field_bounding_box2)
        except Exception as e:
            return template("error_template", {"error_message": str(e)})

        bb_coord1_1, bw_bb_im1_1 = bbs1[0]
        bb_coord1_2, bw_bb_im1_2 = bbs1[1]
        bb_coord2_1, bw_bb_im2_1 = bbs2[0]
        bb_coord2_2, bw_bb_im2_2 = bbs2[1]

        center1_1 = (bb_coord1_1[0], bb_coord1_1[1])
        center1_2 = (bb_coord1_2[0], bb_coord1_2[1])
        center2_1 = (bb_coord2_1[0], bb_coord2_1[1])
        center2_2 = (bb_coord2_2[0], bb_coord2_2[1])

        # Line between BBs:
        bb_angle1 = np.arctan(
            np.inf if bb_coord1_1[0]-bb_coord1_2[0] == 0 else
            (bb_coord1_1[1]-bb_coord1_2[1]) / (bb_coord1_1[0]-bb_coord1_2[0])
            )*180/np.pi
        bb_angle2 = np.arctan(
            np.inf if bb_coord2_1[0]-bb_coord2_2[0] == 0 else
            (bb_coord2_1[1]-bb_coord2_2[1]) / (bb_coord2_1[0]-bb_coord2_2[0])
            )*180/np.pi

        img1_filled = np.copy(img1.array)
        img2_filled = np.copy(img2.array)

        # Fill BBs area with neighbouring values
        field_rotation.fill_BB_hole(bb_coord1_1, bw_bb_im1_1, img1_filled)
        field_rotation.fill_BB_hole(bb_coord1_2, bw_bb_im1_2, img1_filled)
        field_rotation.fill_BB_hole(bb_coord2_1, bw_bb_im2_1, img2_filled)
        field_rotation.fill_BB_hole(bb_coord2_2, bw_bb_im2_2, img2_filled)

        # Get penumbra points
        try:
            samples_left1, samples_right1, p_left1, p_right1 = field_rotation.find_penumbra_points(direction, number_samples, field_corners1, margin, img1_filled)
            samples_left2, samples_right2, p_left2, p_right2 = field_rotation.find_penumbra_points(direction2, number_samples, field_corners2, margin, img2_filled)
        except Exception as e:
            return template("error_template", {"error_message": str(e)})

        # Calculate field edge slopes
        pmin = 0
        pmax = np.max(img1.shape)  # Maksimum point for drawing regression lines

        if direction=="X":
            left_slope1, left_P1, left_err1 = field_rotation.calculate_regression(p_left1, samples_left1, pmin, pmax)
            right_slope1, right_P1, right_err1 = field_rotation.calculate_regression(p_right1, samples_right1, pmin, pmax)
        else:
            left_slope1, left_P1, left_err1 = field_rotation.calculate_regression(samples_left1, p_left1, pmin, pmax)
            right_slope1, right_P1, right_err1 = field_rotation.calculate_regression(samples_right1, p_right1, pmin, pmax)

        if direction2=="X":
            left_slope2, left_P2, left_err2 = field_rotation.calculate_regression(p_left2, samples_left2, pmin, pmax)
            right_slope2, right_P2, right_err2 = field_rotation.calculate_regression(p_right2, samples_right2, pmin, pmax)
        else:

            left_slope2, left_P2, left_err2 = field_rotation.calculate_regression(samples_left2, p_left2, pmin, pmax)
            right_slope2, right_P2, right_err2 = field_rotation.calculate_regression(samples_right2, p_right2, pmin, pmax)

        left_edge_angle1 = np.arctan(left_slope1)*180/np.pi
        left_edge_angle2 = np.arctan(left_slope2)*180/np.pi
        right_edge_angle1 = np.arctan(right_slope1)*180/np.pi
        right_edge_angle2 = np.arctan(right_slope2)*180/np.pi

        # First plot: field and penumbra points
        fig1 = Figure(figsize=(10.5, 5.5), tight_layout={"w_pad":3,  "pad": 3})
        ax1 = fig1.add_subplot(1,2,1)
        ax2 = fig1.add_subplot(1,2,2)
        # Plot error bars and goodness of fit
        fig2 = Figure(figsize=(10, 4), tight_layout={"w_pad":0,  "pad": 1})
        ax3 = fig2.add_subplot(1,2,1)
        ax4 = fig2.add_subplot(1,2,2)
        # Plot angled lines
        fig3 = Figure(figsize=(10, 4), tight_layout={"w_pad":0,  "pad": 1})
        ax5 = fig3.add_subplot(1,2,1)
        ax6 = fig3.add_subplot(1,2,2)

        ax1.imshow(img1.array, cmap=cmap, interpolation="none", aspect="equal", origin='lower')
        ax1.set_title('Image 1')
        ax1.axis('off')
        ax2.imshow(img2.array, cmap=cmap, interpolation="none", aspect="equal", origin='lower')
        ax2.set_title('Image 2')
        ax2.axis('off')

        #Plot field corners
        ax1.plot(field_corners1[:, 1], field_corners1[:, 0], "mo",  markersize=5, markeredgewidth=0)
        ax2.plot(field_corners2[:, 1], field_corners2[:, 0], "mo",  markersize=5, markeredgewidth=0)

        # Plot penumbra points
        if direction=="X":
            ax1.plot(p_left1, samples_left1, "bx", markersize=5, markeredgewidth=2)
            ax1.plot(p_right1, samples_right1, "yx", markersize=5, markeredgewidth=2)
        else:
            ax1.plot(samples_left1, p_left1, "bx", markersize=5, markeredgewidth=2)
            ax1.plot(samples_right1, p_right1,  "yx", markersize=5, markeredgewidth=2)

        ax1.plot(left_P1[0], left_P1[1],  "b--")
        ax1.plot(right_P1[0], right_P1[1], "y--")

        if direction2=="X":
            ax2.plot(p_left2, samples_left2, "bx", markersize=5, markeredgewidth=2)
            ax2.plot(p_right2, samples_right2, "yx", markersize=5, markeredgewidth=2)
        else:
            ax2.plot(samples_left2, p_left2, "bx", markersize=5, markeredgewidth=2)
            ax2.plot(samples_right2, p_right2,  "yx", markersize=5, markeredgewidth=2)

        ax2.plot(left_P2[0], left_P2[1],  "b--")
        ax2.plot(right_P2[0], right_P2[1], "y--")

        # Plot errors:
        ax3.plot(samples_left1, left_err1, "bx", markeredgewidth = 2)
        ax3.plot(samples_right1, right_err1, "yx", markeredgewidth = 2)
        ax4.plot(samples_left2, left_err2, "bx", markeredgewidth = 2)
        ax4.plot(samples_right2, right_err2, "yx", markeredgewidth = 2)

        limits_max = np.amax([np.amax(left_err1), np.amax(right_err1), np.amax(left_err2), np.amax(right_err2)])*1.05
        limits_min = np.amin([np.amin(left_err1), np.amin(right_err1), np.amin(left_err2), np.amin(right_err2)])*0.95
        limits = np.amax([abs(limits_max), abs(limits_min)])
        limits = limits if limits > 1 else 1

        ax3.set_ylim([-limits, limits])
        ax4.set_ylim([-limits, limits])
        ax3.set_ylabel("Deviation from fit [px]")
        ax4.set_ylabel("Deviation from fit [px]")
        ax3.set_xlabel("Field edge [px]")
        ax4.set_xlabel("Field edge [px]")
        ax3.set_title('Image 1 - Regression error')
        ax4.set_title('Image 2 - Regression error')

        # Plot angled lines:
        # If angles are negative, convert to [pi, 2pi]
        if abs(bb_angle1) > 80 and abs(bb_angle1) <= 90:
            B1 = left_edge_angle1 if left_edge_angle1 >= 0 else 180 + left_edge_angle1
            Y1 = right_edge_angle1 if right_edge_angle1 >= 0 else 180 + right_edge_angle1
            BB1 = bb_angle1 if bb_angle1 >= 0 else 180 + bb_angle1
            ref_angle_plot = PI/2  # Reference angle for drawing (either 0 or 90)
        else:
            B1 = left_edge_angle1
            Y1 = right_edge_angle1
            BB1 = bb_angle1
            ref_angle_plot = 0

        if abs(bb_angle2) > 80 and abs(bb_angle2) <= 90:
            B2 = left_edge_angle2 if left_edge_angle2 >= 0 else 180 + left_edge_angle2
            Y2 = right_edge_angle2 if right_edge_angle2 >= 0 else 180 + right_edge_angle2
            BB2 = bb_angle2 if bb_angle2 >= 0 else 180 + bb_angle2
        else:
            B2 = left_edge_angle2
            Y2 = right_edge_angle2
            BB2 = bb_angle2

        a = 2
        x_bb1 = [-a*np.cos(BB1*PI/180), a*np.cos(BB1*PI/180)]
        y_bb1 = [-a*np.sin(BB1*PI/180), a*np.sin(BB1*PI/180)]

        x_b1 = [-a*np.cos((B1)*PI/180), a*np.cos((B1)*PI/180)]
        y_b1 = [-a*np.sin((B1)*PI/180), a*np.sin((B1)*PI/180)]

        x_b2 = [-a*np.cos((BB1-(B2-BB2))*PI/180), a*np.cos((BB1-(B2-BB2))*PI/180)]
        y_b2 = [-a*np.sin((BB1-(B2-BB2))*PI/180), a*np.sin((BB1-(B2-BB2))*PI/180)]

        x_y1 = [-a*np.cos((Y1)*PI/180), a*np.cos((Y1)*PI/180)]
        y_y1 = [-a*np.sin((Y1)*PI/180), a*np.sin((Y1)*PI/180)]

        x_y2 = [-a*np.cos((BB1-(Y2-BB2))*PI/180), a*np.cos((BB1-(Y2-BB2))*PI/180)]
        y_y2 = [-a*np.sin((BB1-(Y2-BB2))*PI/180), a*np.sin((BB1-(Y2-BB2))*PI/180)]

        ax5.plot(x_bb1, y_bb1, "g-", label="BB")
        ax5.plot(x_b1, y_b1, "b-", label="Gantry 0")
        ax5.plot(x_b2, y_b2, "b--", label="Gantry 180")

        ax6.plot(x_bb1, y_bb1, "g-", label="BB")
        ax6.plot(x_y1, y_y1, "y-", label="Gantry 0")
        ax6.plot(x_y2, y_y2, "y--", label="Gantry 180")

        if ref_angle_plot == PI/2:
            max_xb = np.amax([np.abs(x_b1), np.abs(x_b2)])
            max_xy = np.amax([np.abs(x_y1), np.abs(x_y2)])
            ax5.set_xlim([-2*max_xb, 2*max_xb])
            ax5.set_ylim([-1, 1])
            ax6.set_xlim([-2*max_xy, 2*max_xy])
            ax6.set_ylim([-1, 1])
        else:
            max_y = np.amax([np.abs(y_b1), np.abs(y_b2)])
            max_yy = np.amax([np.abs(y_y1), np.abs(y_y2)])
            ax5.set_ylim([-2*max_y, 2*max_y])
            ax5.set_xlim([-1, 1])
            ax6.set_ylim([-2*max_yy, 2*max_yy])
            ax6.set_xlim([-1, 1])

        ax5.legend(loc='upper right', fontsize=10, edgecolor="none")
        ax5.set_title("Blue edge")
        ax5.set_xlabel("LAT [px]")
        ax5.set_ylabel("LONG [px]")
        ax6.legend(loc='upper right', fontsize=10, edgecolor="none")
        ax6.set_title("Yellow edge")
        ax6.set_xlabel("LAT [px]")
        ax6.set_ylabel("LONG [px]")

        # Plot BB line and crosses
        ax1.plot([bb_coord1_1[0], bb_coord1_2[0]], [bb_coord1_1[1], bb_coord1_2[1]], "g-")
        ax2.plot([bb_coord2_1[0], bb_coord2_2[0]], [bb_coord2_1[1], bb_coord2_2[1]], "g-")
        ax1.plot(center1_1[0], center1_1[1],  'r+', markersize=10, markeredgewidth=2)
        ax1.plot(center1_2[0], center1_2[1],  'r+', markersize=10, markeredgewidth=2)
        ax2.plot(center2_1[0], center2_1[1],  'r+', markersize=10, markeredgewidth=2)
        ax2.plot(center2_2[0], center2_2[1],  'r+', markersize=10, markeredgewidth=2)

        ax1.set_xlim([0, img1.shape[1]])
        ax1.set_ylim([0, img1.shape[0]])
        ax2.set_xlim([0, img2.shape[1]])
        ax2.set_ylim([0, img2.shape[0]])

        script1 = mpld3.fig_to_html(fig1, d3_url=D3_URL, mpld3_url=MPLD3_URL)
        script2 = mpld3.fig_to_html(fig2, d3_url=D3_URL, mpld3_url=MPLD3_URL)
        script3 = mpld3.fig_to_html(fig3, d3_url=D3_URL, mpld3_url=MPLD3_URL)

        variables = {"script1": script1,
                     "script2": script2,
                     "script3": script3,
                     "left_edge_angle1": left_edge_angle1,
                     "left_edge_angle2": left_edge_angle2,
                     "right_edge_angle1": right_edge_angle1,
                     "right_edge_angle2": right_edge_angle2,
                     "bb_angle1": bb_angle1,
                     "bb_angle2": bb_angle2,
                     "test_type":test_type,
                     "tolerance": tolerance_collabs
                     }

    elif test_type == "Collimator relative":

        # Get penumbra points
        try:
            samples_left1, samples_right1, p_left1, p_right1 = field_rotation.find_penumbra_points(direction, number_samples, field_corners1, margin, img1.array)
            samples_left2, samples_right2, p_left2, p_right2 = field_rotation.find_penumbra_points(direction2, number_samples, field_corners2, margin, img2.array)
        except Exception as e:
            return template("error_template", {"error_message": str(e)})

        # Calculate field edge slopes
        pmin = 0
        pmax = np.max(img1.shape)  # Maksimum point for drawing regression lines

        if direction=="X":
            left_slope1, left_P1, left_err1 = field_rotation.calculate_regression(p_left1, samples_left1, pmin, pmax)
            right_slope1, right_P1, right_err1 = field_rotation.calculate_regression(p_right1, samples_right1, pmin, pmax)
        else:
            left_slope1, left_P1, left_err1 = field_rotation.calculate_regression(samples_left1, p_left1, pmin, pmax)
            right_slope1, right_P1, right_err1 = field_rotation.calculate_regression(samples_right1, p_right1, pmin, pmax)

        if direction2=="X":
            left_slope2, left_P2, left_err2 = field_rotation.calculate_regression(p_left2, samples_left2, pmin, pmax)
            right_slope2, right_P2, right_err2 = field_rotation.calculate_regression(p_right2, samples_right2, pmin, pmax)
        else:
            left_slope2, left_P2, left_err2 = field_rotation.calculate_regression(samples_left2, p_left2, pmin, pmax)
            right_slope2, right_P2, right_err2 = field_rotation.calculate_regression(samples_right2, p_right2, pmin, pmax)

        left_edge_angle1 = np.arctan(left_slope1)*180/np.pi
        left_edge_angle2 = np.arctan(left_slope2)*180/np.pi
        right_edge_angle1 = np.arctan(right_slope1)*180/np.pi
        right_edge_angle2 = np.arctan(right_slope2)*180/np.pi

        # First plot: field and penumbra points
        fig1 = Figure(figsize=(10.5, 5.5), tight_layout={"w_pad":3,  "pad": 3})
        ax1 = fig1.add_subplot(1,2,1)
        ax2 = fig1.add_subplot(1,2,2)
        # Plot error bars and goodness of fit
        fig2 = Figure(figsize=(10, 4), tight_layout={"w_pad":0,  "pad": 1})
        ax3 = fig2.add_subplot(1,2,1)
        ax4 = fig2.add_subplot(1,2,2)

        ax1.imshow(img1.array, cmap=cmap, interpolation="none", aspect="equal", origin='lower')
        ax1.set_title('Image 1')
        ax1.axis('off')
        ax2.imshow(img2.array, cmap=cmap, interpolation="none", aspect="equal", origin='lower')
        ax2.set_title('Image 2')
        ax2.axis('off')

        #Plot field corners
        ax1.plot(field_corners1[:, 1], field_corners1[:, 0], "mo",  markersize=5, markeredgewidth=0)
        ax2.plot(field_corners2[:, 1], field_corners2[:, 0], "mo",  markersize=5, markeredgewidth=0)

        # Plot penumbra points
        if direction=="X":
            ax1.plot(p_left1, samples_left1, "bx", markersize=5, markeredgewidth=2)
            ax1.plot(p_right1, samples_right1, "yx", markersize=5, markeredgewidth=2)

        else:
            ax1.plot(samples_left1, p_left1, "bx", markersize=5, markeredgewidth=2)
            ax1.plot(samples_right1, p_right1,  "yx", markersize=5, markeredgewidth=2)

        ax1.plot(left_P1[0], left_P1[1],  "b--")
        ax1.plot(right_P1[0], right_P1[1], "y--")

        if direction2=="X":
            ax2.plot(p_left2, samples_left2, "bx", markersize=5, markeredgewidth=2)
            ax2.plot(p_right2, samples_right2, "yx", markersize=5, markeredgewidth=2)

        else:
            ax2.plot(samples_left2, p_left2, "bx", markersize=5, markeredgewidth=2)
            ax2.plot(samples_right2, p_right2,  "yx", markersize=5, markeredgewidth=2)

        ax2.plot(left_P2[0], left_P2[1],  "b--")
        ax2.plot(right_P2[0], right_P2[1], "y--")

        ax1.set_xlim([0, img1.shape[1]])
        ax1.set_ylim([0, img1.shape[0]])
        ax2.set_xlim([0, img2.shape[1]])
        ax2.set_ylim([0, img2.shape[0]])

        # Plot errors:
        ax3.plot(samples_left1, left_err1, "bx", markeredgewidth = 2)
        ax3.plot(samples_right1, right_err1, "yx", markeredgewidth = 2)
        ax4.plot(samples_left2, left_err2, "bx", markeredgewidth = 2)
        ax4.plot(samples_right2, right_err2, "yx", markeredgewidth = 2)

        limits_max = np.amax([np.amax(left_err1), np.amax(right_err1), np.amax(left_err2), np.amax(right_err2)])*1.05
        limits_min = np.amin([np.amin(left_err1), np.amin(right_err1), np.amin(left_err2), np.amin(right_err2)])*0.95
        limits = np.amax([abs(limits_max), abs(limits_min)])
        limits = limits if limits > 1 else 1

        ax3.set_ylim([-limits, limits])
        ax4.set_ylim([-limits, limits])
        ax3.set_ylabel("Deviation from fit [px]")
        ax4.set_ylabel("Deviation from fit [px]")
        ax3.set_xlabel("Field edge [px]")
        ax4.set_xlabel("Field edge [px]")
        ax3.set_title('Image 1 - Regression error')
        ax4.set_title('Image 2 - Regression error')

        script1 = mpld3.fig_to_html(fig1, d3_url=D3_URL, mpld3_url=MPLD3_URL)
        script2 = mpld3.fig_to_html(fig2, d3_url=D3_URL, mpld3_url=MPLD3_URL)

        variables = {"script1": script1,
                     "script2": script2,
                     "script3": "",
                     "left_edge_angle1": left_edge_angle1,
                     "left_edge_angle2": left_edge_angle2,
                     "right_edge_angle1": right_edge_angle1,
                     "right_edge_angle2": right_edge_angle2,
                     "test_type": test_type,
                     "tolerance": tolerance_collrel
                     }

    else:  # Couch rotation
        # Get BBs
        try:
            if high_contrast:
                bbs1 = field_rotation._find_bb2(img1, rad_field_bounding_box1)
                bbs2 = field_rotation._find_bb2(img2, rad_field_bounding_box2)
            else:
                bbs1 = field_rotation._find_bb(img1, rad_field_bounding_box1)
                bbs2 = field_rotation._find_bb(img2, rad_field_bounding_box2)
        except Exception as e:
            return template("error_template", {"error_message": str(e)})

        bb_coord1_1, bw_bb_im1_1 = bbs1[0]
        bb_coord1_2, bw_bb_im1_2 = bbs1[1]
        bb_coord2_1, bw_bb_im2_1 = bbs2[0]
        bb_coord2_2, bw_bb_im2_2 = bbs2[1]

        center1_1 = [bb_coord1_1[0], bb_coord1_1[1]]
        center1_2 = [bb_coord1_2[0], bb_coord1_2[1]]
        center2_1 = [bb_coord2_1[0], bb_coord2_1[1]]
        center2_2 = [bb_coord2_2[0], bb_coord2_2[1]]

        bb_line_center1 = [np.average([center1_1[0], center1_2[0]]), np.average([center1_1[1], center1_2[1]])]
        bb_line_center2 = [np.average([center2_1[0], center2_2[0]]), np.average([center2_1[1], center2_2[1]])]

        # Line between BBs:
        bb_angle1 = np.arctan(
            np.inf if bb_coord1_1[0]-bb_coord1_2[0] == 0 else
            (bb_coord1_1[1]-bb_coord1_2[1]) / (bb_coord1_1[0]-bb_coord1_2[0])
            )*180/np.pi
        bb_angle2 = np.arctan(
            np.inf if bb_coord2_1[0]-bb_coord2_2[0] == 0 else
            (bb_coord2_1[1]-bb_coord2_2[1]) / (bb_coord2_1[0]-bb_coord2_2[0])
            )*180/np.pi

        fig1 = Figure(figsize=(10.5, 5.5), tight_layout={"w_pad":3,  "pad": 3})
        ax1 = fig1.add_subplot(1,2,1)
        ax2 = fig1.add_subplot(1,2,2)

        ax1.imshow(img1.array, cmap=cmap, interpolation="none", aspect="equal", origin='lower')
        ax1.set_title('Image 1')
        ax1.axis('off')
        ax2.imshow(img2.array, cmap=cmap, interpolation="none", aspect="equal", origin='lower')
        ax2.set_title('Image 2')
        ax2.axis('off')

        # Plot BB line and crosses
        ax1.plot([bb_coord1_1[0], bb_coord1_2[0]], [bb_coord1_1[1], bb_coord1_2[1]], "g-")
        ax2.plot([bb_coord2_1[0], bb_coord2_2[0]], [bb_coord2_1[1], bb_coord2_2[1]], "g-")
        ax1.plot(center1_1[0], center1_1[1],  'r+', markersize=10, markeredgewidth=2)
        ax1.plot(center1_2[0], center1_2[1],  'r+', markersize=10, markeredgewidth=2)
        ax2.plot(center2_1[0], center2_1[1],  'r+', markersize=10, markeredgewidth=2)
        ax2.plot(center2_2[0], center2_2[1],  'r+', markersize=10, markeredgewidth=2)

        ax1.set_xlim([0, img1.shape[1]])
        ax1.set_ylim([0, img1.shape[0]])
        ax2.set_xlim([0, img2.shape[1]])
        ax2.set_ylim([0, img2.shape[0]])

        script1 = mpld3.fig_to_html(fig1, d3_url=D3_URL, mpld3_url=MPLD3_URL)

        variables = {"script1": script1,
                     "script2": "",
                     "script3": "",
                     "bb_angle1": bb_angle1,
                     "bb_angle2": bb_angle2,
                     "bb_line_center1": bb_line_center1,
                     "bb_line_center2": bb_line_center2,
                     "test_type":test_type,
                     "tolerance": tolerance_couchrel
                     }
    variables["acquisition_datetime"] = acquisition_datetime
    variables["save_results"] = save_results
    general_functions.delete_files_in_subfolders([temp_folder1, temp_folder2]) # Delete image
    return template("fieldrot_results", variables)

@fieldrot_app.route('/fieldrot/<w1>/<w2>', method="POST")
def fieldrot_calculate(w1, w2):
    colormap = request.forms.hidden_colormap
    test_type = request.forms.hidden_type
    direction = request.forms.hidden_direction
    direction2 = request.forms.hidden_direction2
    number_samples = int(request.forms.hidden_points)
    margin = int(request.forms.hidden_margin)
    med_filter = int(request.forms.hidden_filter)
    imgdescription = request.forms.hidden_imgdescription
    station = request.forms.hidden_station
    displayname = request.forms.hidden_displayname
    acquisition_datetime = request.forms.hidden_datetime

    clipbox = float(request.forms.hidden_clipbox)*10.0
    invert = True if request.forms.hidden_invert=="true" else False
    high_contrast = True if request.forms.hidden_high_contrast=="true" else False

    args = {"test_type": test_type, "direction": direction, "direction2": direction2,
            "number_samples":number_samples, "margin":margin, "clipbox": clipbox,
            "invert":invert, "w1": w1, "w2": w2, "colormap": colormap, "med_filter": med_filter,
            "imgdescription": imgdescription, "station": station, "displayname": displayname,
            "acquisition_datetime": acquisition_datetime, "high_contrast": high_contrast,
            "config": general_functions.get_configuration()}
    p = Pool(1)
    data = p.map(fieldrot_helperf_catch_error, [args])
    p.close()
    p.join()
    return data


'''
Created on 2017年12月7日

@author: admin
'''
from model import models,user
class Role(models.Model):
    def __init__(self):
        models.Model.__init__(self,self.__class__.__name__)
    def getRolebyid(self,roleid):
        if roleid=="":
            role = {}
            role["msg"] = "no"
            cols = self.param
            for col in cols:
                role[col] = ""
            return role
        else:
            wh="where role_id='"+roleid+"'"
            res = self.query_data(where=wh)
            roles = []
            if len(res)<=0:
                role = {}
                role["msg"] = "no"
                cols = self.param
                for col in cols:
                    role[col] = ""
                return role
            else:
                cols = self.param
                for r in res:
                    role = {}
                    n = 0;
                    for col in cols:
                        role[col] = r[n]
                        n+=1
                    role["msg"] = "yes"
                    roles.append(role)
            return roles[0]
    def remove_role(self,roleid):
        wh = "role_id='"+roleid+"'"
        return self.delete_data(wh)
    def add_role(self,T):
        V = ""
        for i in T:
            V+=",%s"
        V = V[1:len(V)]
        return self.insert_data(V,T)
    def add_role_kv(self,T):
        K = "(Id,role_name,role_id,role_val,role_mark)"
        V = ""
        for it in T:
          V = V+",'"+str(it)+"'"
        V = "("+V[1:]+")"
        return self.insert_data_KV(K,V)
    def edit_role(self,T,roleid):
        V = self.param[:]
        V.remove("Id")
        V.remove("role_id")
        length = len(V)
        w = "";
        for i in range(0,length):
            w = w+","+V[i]+"='"+str(T[i])+"'"
        w = w[1:len(w)]
        wh = "role_id='"+roleid+"'"
        return self.update_data(w,wh)
    def get_role(self,usr=""):
        ur = user.User.getuser_by_acount(usr)
        ro = self.getRolebyid(ur['role_id'])
        ro['isadmin'] = ur['isadmin']
        ro['user_id'] = ur['user_id']
        return ro
    def change_per_vals(self,ro,pers):
        p = ro['role_val']+","+pers
        T = (pers)
        w = "role_val";
        wh = "role_id='"+ro['role_id']+"'"
        return self.update_data(w,wh)
Role = Role()
# print(Role.param)


# -*- encoding: utf-8 -*-
'''
@Func    :   get statistics of different datasets
@Time    :   2021/12/08 21:37:48
@Author  :   Yixiao Ma
@Contact :   mayx20@mails.tsinghua.edu.cn
'''

import os
import json
import numpy as np
from tqdm import tqdm
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer
import jieba

def cos(x,y):
    assert len(x) == len(y)
    xy=0.0
    x2=0.0
    y2=0.0
    for i in range(len(x)):
        xy += x[i]*y[i]
        x2 += x[i]**2
        y2 += y[i]**2
    return xy/((x2*y2)**0.5)

def add_doc_len(data, stats_={}):
    # # lecard
    stats = stats_
    if data == 'LeCaRD':
        gt = json.load(open('/work/mayixiao/similar_case/LeCaRD/LeCaRD_github/data/label/label_top30_dict.json','r'))
        dir_path = '/work/mayixiao/similar_case/candidates'
    elif data == 'CAIL2021':
        gt = json.load(open('/work/mayixiao/similar_case/202006/data/label/label_top30_dict_2.json','r'))
        dir_path = '/work/mayixiao/similar_case/202006/data/candidates_2'
    elif data == 'COLIEE2020':
        gt = json.load(open('/work/mayixiao/cutoff/preresults/COLIEE2020/labels.json','r'))
        dir_path = '/work/mayixiao/coliee_2020/data/task1/task1_2020'

    keys = list(gt.keys())

    for key1 in tqdm(keys):
        stats[key1] = {}
        if data == 'COLIEE2020':
            files = os.listdir(os.path.join(dir_path, key1, 'candidates'))
        else:
            files = os.listdir(os.path.join(dir_path, key1))
        key2s = list(gt[key1].keys())
        if data == 'COLIEE2020':
            for key2 in key2s:
                doc = open(os.path.join(dir_path, key1, 'candidates', key2 + '.txt'),'r').read()
                stats[key1][key2] = {'doclen': len(doc.split(' '))}
        else:
            for key2 in key2s: #list(gt[key1].keys())[:30]:
                stats[key1][key2] = {'doclen': len(json.load(open(os.path.join(dir_path, key1, key2 + '.json'),'r'))['qw'])}

    return stats

def split_word(line, stopwords):
    raw_a = jieba.cut(line, cut_all=False)
    a = [i for i in raw_a if not i in stopwords]
    return  " ".join(a)

def add_neighbor_tfidf(data, stats_={}):
    stats = stats_
    vectorizer = CountVectorizer()  # 实例化
    transformer = TfidfTransformer()
    if data == 'LeCaRD':
        gt = json.load(open('/work/mayixiao/similar_case/LeCaRD/LeCaRD_github/data/label/label_top30_dict.json','r'))
        dir_path = '/work/mayixiao/similar_case/candidates'
    elif data == 'CAIL2021':
        gt = json.load(open('/work/mayixiao/similar_case/202006/data/label/label_top30_dict_2.json','r'))
        dir_path = '/work/mayixiao/similar_case/202006/data/candidates_2'
    elif data == 'COLIEE2020':
        gt = json.load(open('/work/mayixiao/cutoff/preresults/COLIEE2020/labels.json','r'))
        dir_path = '/work/mayixiao/coliee_2020/data/task1/task1_2020'

    keys = list(gt.keys())

    for key1 in tqdm(keys):
        corpus = []

        if data == 'COLIEE2020':
            files = os.listdir(os.path.join(dir_path, key1, 'candidates'))
            key2s = list(gt[key1].keys())
            for key2 in key2s:
                doc = open(os.path.join(dir_path, key1, 'candidates', key2 + '.txt'),'r').read()[:4096]
                corpus.append(doc)
        else:
            files = os.listdir(os.path.join(dir_path, key1))
            key2s = [file_.split('.')[0] for file_ in files]
            for key2 in key2s:
                corpus.append(split_word(json.load(open(os.path.join(dir_path, key1, key2 + '.json'),'r'))['ajjbqk'], stopwords))
        tfidf_list = transformer.fit_transform(vectorizer.fit_transform(corpus)).toarray().tolist()

        num_file = len(key2s)
        for i in range(num_file):
            stats[key1][key2s[i]]['neighbor_tfidf'] = {}
            for j in range(num_file):
                stats[key1][key2s[i]]['neighbor_tfidf'][key2s[j]] = cos(tfidf_list[i], tfidf_list[j])

    return stats

if __name__ == '__main__':
    with open('/work/mayixiao/similar_case/LeCaRD/LeCaRD_github/data/others/stopword.txt', 'r') as g:
        words = g.readlines()
    stopwords = [i.strip() for i in words]
    stopwords.extend(['.','（','）','-'])

    DATA = 'COLIEE2020'
    dic = {}
    dic = add_doc_len(DATA, dic)
    dic = add_neighbor_tfidf(DATA, dic)
    WPATH = '/work/mayixiao/cutoff/preresults/%s/stats.json'%(DATA)
    json.dump(dic, open(WPATH, 'w'), ensure_ascii=False)


from glob import glob
import tempfile

from lib import Markers

def test_insert_markers():
    for filename in glob('files/*.avb'):
        print(filename)
        data = Markers(filename)

        for _, component in data.enumerate_components().items():
            marker = data.create_marker(0, 'xxx', 'red', 'me')
            data.add_marker(component, marker)

        filename = tempfile.mkstemp(suffix='.avb')[1]

        data.write(filename)


import logging
import os

def log_init(path):
    format = logging.Formatter('%(asctime)s - %(levelname)s: %(message)s')
    root = logging.getLogger()
    add_handlers = []
    for handle in root.handlers:
        if isinstance(handle, logging.StreamHandler) or isinstance(handle, logging.FileHandler):
            pass
        else:
            add_handlers.append(handle)
    root.handlers.clear()
    root.handlers.extend(add_handlers)
    root.setLevel(logging.DEBUG)

    stream = logging.StreamHandler()
    stream.setFormatter(format)
    root.addHandler(stream)

    plc_logger = logging.FileHandler(os.path.join(path, "抄控器.txt"), encoding="utf-8")
    plc_logger.setFormatter(format)
    root.addHandler(plc_logger)

    root.propagate = False

    test_machine = logging.getLogger("测试工装")
    test_machine.handlers.clear()
    machine_log = logging.FileHandler(os.path.join(path, "测试工装.txt"), encoding="utf-8")
    machine_log.setFormatter(format)
    test_machine.addHandler(machine_log)
    test_machine.propagate = False

    device_under_test = logging.getLogger("被测设备")
    device_under_test.handlers.clear()
    device_log = logging.FileHandler(os.path.join(path, "被测设备.txt"), encoding="utf-8")
    device_log.setFormatter(format)
    device_under_test.addHandler(device_log)
    device_under_test.propagate = False

    device_raw = logging.getLogger("被测设备.raw")
    device_raw.handlers.clear()
    device_raw_logger = logging.FileHandler(os.path.join(path, "被测设备_raw.txt"), encoding="utf-8")
    device_raw_logger.setFormatter(format)
    device_raw.addHandler(device_raw_logger)
    device_raw.propagate = False

    ignore_logger = logging.getLogger("ignore")
    ignore_logger.handlers.clear()
    ignore_file = logging.FileHandler(os.path.join(path, "ignore.txt"), encoding="utf-8")
    ignore_file.setFormatter(format)
    ignore_logger.addHandler(ignore_file)
    ignore_logger.propagate = False


# ----- ----- ----- MSc Data Science - Ahmet Cem Saydam - 13173584 - 2019/2020  ----- ----- ----- #
# ----- ----- ----- MSc Data Science - Ahmet Cem Saydam - 13173584 - 2019/2020  ----- ----- ----- #
# ----- ----- ----- MSc Data Science - Ahmet Cem Saydam - 13173584 - 2019/2020  ----- ----- ----- #

import tkinter
from tkinter import *
from tkinter import messagebox
import numpy as np
import math
import random
from random import choice
from math import sqrt
import copy

def read_cities(file_name):
    file_name1 = open(file_name, "r")
    list1,list2,list3=[],[],[]
    for line1 in file_name1:
        list2 = line1.rstrip().split("\t")
        list1.append(list2)
    for i in range(len(list1)):
        list3.append([list1[i][0], list1[i][1], (((list1[i][2]))), ((list1[i][3]))])
    return list3

def print_cities(road_map):
    list4=[]
    for i in range(0,len(road_map)):
        list4.append([road_map[i][0],road_map[i][1],(round((float(road_map[i][2])),2)),
                      (round(float(road_map[i][3]),2))])
    print(*list4,sep="\n")

def compute_total_distance(road_map):
    total_dist1 = 0.0
    for i in range(0,len(road_map)):
        city_x1 = float(road_map[i][2])
        city_y1 = float(road_map[i][3])
        city_x2 = float(road_map[(i + 1) % len(road_map)][2])
        city_y2 = float(road_map[(i + 1) % len(road_map)][3])
        total_dist1 += sqrt( ( (city_x2-city_x1) ** 2)   + ( ( city_y2-city_y1 )  ** 2) )
    return (total_dist1)

def swap_cities(road_map,index1,index2):
    new_road_map = copy.deepcopy(road_map)
    if (index1!= index2):
        new_value_1 = new_road_map[index1]
        new_value_2 = new_road_map[index2]
        new_road_map[index1] = new_value_2
        new_road_map[index2] = new_value_1
        new_total_distance = compute_total_distance(new_road_map)
    else:
        index1 = int(len(new_road_map) * random.random())
        index2 = int(len(new_road_map) * random.random())
        new_road_map,new_total_distance = (swap_cities(new_road_map, index1, index2)[0]),\
                                          (swap_cities(new_road_map, index1, index2)[1])
    return (new_road_map,new_total_distance)

def shift_cities(road_map):
    new_shifted_road_map=[road_map[-1]] + road_map[:-1]
    return new_shifted_road_map

def find_best_cycle(road_map):
    min_dist = compute_total_distance(road_map)
    new_best_map = road_map
    count=0
    while (count <= 10000):
        index1 = int(len(new_best_map)* random.random())
        index2 = int(len(new_best_map)* random.random())
        new_route1 = (swap_cities(shift_cities(new_best_map), index1, index2)[0])
        new_dist = (swap_cities(shift_cities(new_best_map), index1, index2)[1])
        if new_dist < min_dist:
            min_dist = new_dist
            new_best_map = new_route1
        count += 1
    return new_best_map

def print_map(road_map):
    road_map_last = road_map
    total_dist =0
    list5 = []
    for i in range(0,len(road_map_last)):
        new_city_x3 = float(road_map_last[i][2])
        new_city_y3 = float(road_map_last[i][3])
        new_city_x4 = float(road_map_last[(i + 1) % len(road_map_last)][2])
        new_city_y4 = float(road_map_last[(i + 1) % len(road_map_last)][3])
        new_dist1 = ((compute_total_distance([[str(),str(),new_city_x3,new_city_y3],
                                              [str(),str(),new_city_x4,new_city_y4]]))/2)
        total_dist += new_dist1
        new_line1 = " From City : " + road_map_last[i][1] + " ( " + " State : " +  road_map_last[i][0] \
                    + " ) to" +" City : "+ road_map_last[(i + 1) % len(road_map_last)][1] + " ( "  \
                    + " State : " + road_map_last[(i + 1) % len(road_map_last)][0]  + " ) " \
                    + " Distance : " + str(round(new_dist1, 2))
        list5.append(new_line1)
        list5.append("Total distance : ---> " + str(round(total_dist, 2)))
    print(*list5,sep="\n")

def Visualizer(road_map):
    root = tkinter.Tk()
    canvas_x_axis = 1250
    canvas_y_axis = 625
    grid_distance = 25
    visualize_1= tkinter.Canvas(root, width=canvas_x_axis, height=canvas_y_axis, bg='white')
    root.title(" The Traveling Salesman ")
    visualize_1.pack(side=LEFT)

    exe_1 = Frame(root)
    exe_1.pack()

    best_route_2 = road_map
    minDistance = compute_total_distance(best_route_2)

    def dialog ():
        messagebox.showinfo(" Best Ciycle ",information_2 )
    information_2 = str(("Best Route : " + " From City : " + str(best_route_2[0][1]) + " ( State : " \
                         + str(best_route_2[0][0]) + " ) to City : " + str(best_route_2[-1][1]) + " ( State : " \
                         + str(best_route_2[-1][0]) + " ) " + " Minimum Distance : " + str(round(minDistance, 2))))
    button1 = Button(exe_1, text=" ---> Best Cycle <--- ", fg="white", bg="lightblue", command=dialog)
    button1.pack()

    for x in range(grid_distance, canvas_x_axis + grid_distance, grid_distance):
        visualize_1.create_line(x, grid_distance, x, canvas_y_axis, fill="blue", dash=())
    for y in range(grid_distance, canvas_y_axis + grid_distance, grid_distance):
        visualize_1.create_line(grid_distance, y, canvas_x_axis, y, fill="red", dash=())

    maximum_Longtt = np.max([float(i[3]) for i in best_route_2])
    minumum_Longtt  = np.min([float(i[3]) for i in best_route_2])
    maximum_Latt = np.max([float(i[2]) for i in best_route_2])
    minumum_Latt = np.min([float(i[2]) for i in best_route_2])
    Longtt_Range = np.append([0], np.linspace(math.floor(minumum_Longtt),
                                              math.ceil(maximum_Longtt), int(canvas_x_axis / grid_distance) - 2))
    Latt_Range = np.append([0], np.flip(np.linspace(math.floor(minumum_Latt),
                                                    math.ceil(maximum_Latt), int(canvas_y_axis / grid_distance) - 2)))

    for x in range(grid_distance, canvas_x_axis - grid_distance, grid_distance):
        visualize_1.create_text(x + grid_distance, grid_distance, text=round((Longtt_Range[int(x / grid_distance)]), 2),
                      angle=90, font=("Lucida Console", 9), fill='black')
    for y in range(grid_distance, canvas_y_axis - grid_distance, grid_distance):
        visualize_1.create_text(grid_distance, y + grid_distance, text=round((Latt_Range[int(y / grid_distance)]), 2),
                      font=("Lucida Console", 9), fill='black')

    count = 0
    for i in best_route_2:
        count += 1
        differeance_Longtt = grid_distance / abs(Longtt_Range[-1] - Longtt_Range[-2])
        inter_Longtt = differeance_Longtt * ((float(i[3])) - math.floor(minumum_Longtt))
        differeance_Latt = grid_distance / abs(Latt_Range[-1] - Latt_Range[-2])
        inter_Latt = differeance_Latt * (math.ceil(maximum_Latt) - float(i[2]))
        my_color = "#" + "".join((choice(['0', '1', '2', '3', '4', '5', '6', '7', '8']) for _ in range(0, 9)))
        visualize_1.create_oval(inter_Longtt + 30, inter_Latt + 30, inter_Longtt + 50,
                                inter_Latt + 50, fill=my_color, outline=my_color)
        visualize_1.create_text(inter_Longtt + 40, inter_Latt + 40, text=str(count),
                                font=("Lucida Console", 9), fill='white')
        information_1=Label(text=(str(count),str(i[1]),str(i[0])),font=("Lucida Console", 9))
        information_1.pack(side=TOP)

    tkinter.mainloop()

def main():
    file_name = input("Please type a file name that contains the data (for example type :city-data) :")
    road_map= read_cities(("%s.txt" % (file_name)))
    print_cities(road_map)
    compute_total_distance(road_map)
    index1 = int(len(road_map) * random.random())
    index2 = int(len(road_map) * random.random())
    swap_cities(road_map, index1, index2)
    shift_cities(road_map)
    print_map(road_map)
    best_route_1 = find_best_cycle(road_map)
    Visualizer(best_route_1)

if __name__ == "__main__":
    main()

# ----- ----- ----- MSc Data Science - Ahmet Cem Saydam - 13173584 - 2019/2020  ----- ----- ----- #
# ----- ----- ----- MSc Data Science - Ahmet Cem Saydam - 13173584 - 2019/2020  ----- ----- ----- #
# ----- ----- ----- MSc Data Science - Ahmet Cem Saydam - 13173584 - 2019/2020  ----- ----- ----- #


from math import sqrt
from statistics import mean, median, stdev
import sys # for import from parent directory
import os # for import from parent directory
current = os.path.dirname(os.path.realpath(__file__))
parent = os.path.dirname(current)
sys.path.append(parent)
import asyncio
import pickle
import time

from src.minimum_heap.min_heap import MinHeap
from src.graphs.search_item import SearchItem
from src.search_engine.search_engine import SearchEngine
from example_program.calculate_weight import calc_edge_weight
from data_collection_tools.utils.status_report import print_progress_bar

def build_database():
    """Builds Vertices and WordTrie"""
    print('Building AnimeSearch and WordTrie.')
    se = SearchEngine()
    data: dict
    mal:dict
    for data in get_anime_info():
        title = data['title']
        tags = data.get('tags', set())
        mal = data['mal_stats']
        mal['mean'] = mal.get('mean', 0.0)
        # build SearchItem
        item = SearchItem(name=title, tags=tags, info=data)
        # build SearchGraph
        se.add_item(item, calc_edge_weight)

    searchengine_path = os.path.join(os.getcwd(), 'dataset/searchengine.pkl')
    with open(searchengine_path, 'wb') as f:
        pickle.dump(se, f)

def get_anime_info():
    """Generator for anime info."""
    # load in database
    file_path = os.path.join(os.getcwd(), 'dataset/anime_search_database.pkl')
    with open(file_path, 'rb') as f:
        anime_database = pickle.load(f)
    total_len = len(anime_database)

    for cnt, data in enumerate(anime_database.values()):
        print_progress_bar(cnt, total_len)
        # convert lists to sets
        for key, value in data.items():
            if type(value) is not list:
                continue
            data[key] = set(value)
        # convert VAs to sets
        try:
            for lang, vas in data.get('voice_actors').items():
                if type(vas) is not list:
                    continue
                data['voice_actors'][lang] = set(vas)
        except:
            data['voice_actors'] = {'japanese': set()}
        # convert studios
        studios = set()
        for studio in data['mal_stats'].get('studios', []):
            studios.add(studio['name'])
        data['mal_stats']['studios'] = studios
        # yield
        yield data

def test():
    se = SearchEngine()
    for i in range(18000):
        print_progress_bar(i, 18000)
        item = SearchItem(name=str(i))
        # build SearchGraph
        def calc(s1, s2):
            pass
        se.add_item(item, calc)

async def animesearch_test():
    print('Building SearchEngine.')
    # testing parameters
    samples = 17000
    weight_thres = 32
    trials = 10
    #
    cwd = os.getcwd()
    # filepath = os.path.join(cwd, 'dataset/searchengine.pkl')
    # with open(filepath, 'rb') as f:
    #     se = pickle.load(f)

    se = SearchEngine()
    data: dict
    mal: dict
    for i, data in enumerate(get_anime_info()):
        if i > samples:
            break
        title = data['title']
        tags = data.get('tags', set())
        mal = data['mal_stats']
        mal['mean'] = mal.get('mean', 0.0)
        # build SearchItem
        item = SearchItem(name=title, tags=tags, info=data)
        print(item)
        # build SearchGraph
        se.add_item(item, calc_edge_weight, weight_thres)
    print('Finished building SearchEngine.')
    # runtime benchmark
    se: SearchEngine
    nums = []
    # for row in se.graph:
    #     nums.extend(row)

    # matrix = se.graph
    # size = len(se.graph)
    # for i in range(size):
    #     for j in range(size):
    #         weight = matrix[i][j]
    #         if weight < 69:
    #             nums.append(weight)

    # filepath = os.path.join(cwd, 'dataset/nums.pkl')
    # with open(filepath, 'wb') as f:
    #     pickle.dump(nums, f)

    # filepath = os.path.join(cwd, 'dataset/nums.pkl')
    # with open(filepath, 'rb') as f:
    #     nums = pickle.load(f)

    # new_nums = [num for num in nums if num < 32]

    # print(f'Num edge weights: {len(new_nums)}')
    # print(f'Num vertices: {sqrt(len(new_nums))}')
    # print(f'Mean: {mean(new_nums)}')
    # print(f'Median: {median(new_nums)}')
    # print(f'Std deviation: {stdev(new_nums)}')

    t0 = time.time()
    for _ in range(trials):
        results = await se.search('a', limit=5)
    print(f'Average runtime for {samples} samples in {trials} trials: '
          f'{(time.time()-t0)/trials} s.')

if __name__ == '__main__':
    # build_database()
    asyncio.run(animesearch_test())


import turtle

my_turtle = turtle.Turtle()
my_turtle.shape('turtle')
my_turtle.shapesize(5, 5, 12)
my_turtle.color('red', 'green')

# Getting the turtle to move forward by 100 paces
my_turtle.forward(100)

my_screen = turtle.Screen()
my_screen.exitonclick()

# You can learn about this package if needed, from the official documentation


# le um arquivo txt ou csv em um dataframe

def read_txt(arquivo, sep='\t'):
    file = open(arquivo) if type(arquivo)==str else arquivo
    lines = file.readlines()
    if type(lines[0])==bytes: lines=[str(i)[2:] for i in lines]
    file.close()
    values = [i.replace('\n','').split(sep) for i in lines]
    df = pd.DataFrame(values[1:], columns=values[0])
    return df


import os
import socket
import sys
from pynet.lib.ip import IP
from pynet.lib.icmp import ICMP

class Scanner:
    def __init__(self, host):
        self.host = host
        if os.name == 'nt':
            socket_protocol = socket.IPPROTO_IP
        else:
            socket_protocol = socket.IPPROTO_ICMP

        self.socket = socket.socket(socket.AF_INET,
                                socket.SOCK_RAW, socket_protocol)
        self.socket.bind((host, 0))
        self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)

        # If on Windows, turn on promiscuous mode:
        if os.name == 'nt':
            self.socket.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

    def sniff(self):
        try:
            while True:
                # read a packet
                raw_buffer = self.socket.recvfrom(65535)[0]
                # create an IP header from the first 20 bytes
                ip_header = IP(raw_buffer[0:20])

                # print the detected protocol and hosts
                print('Protocol: %s %s -> %s' % (ip_header.protocol,
                                                 ip_header.src_address,
                                                 ip_header.dst_address))
                print(f'Version: {ip_header.ver}')
                print(f'Header Length: {ip_header.ihl} TTL: {ip_header.ttl}')

                if ip_header.protocol == "ICMP":
                    offset = ip_header.ihl * 4
                    buf = raw_buffer[offset:offset + 8]
                    icmp_header = ICMP(buf)
                    print('ICMP -> Type: %s Code %s\n' %
                        (icmp_header.type, icmp_header.code))

        except KeyboardInterrupt:
            # If on Windows, turn off promiscuous mode:
            if os.name == 'nt':
                self.socket.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
            sys.exit()


import os
import openai
from dotenv import load_dotenv

load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")

response = openai.Completion.create(
  model="text-davinci-003",
  prompt="How many weeks in a year?",
)

print(response)


from django.core.management.base import BaseCommand, CommandError

import olympia.core.logger
from olympia.activity.models import ActivityLogToken

log = olympia.core.logger.getLogger('z.amo.activity')

class Command(BaseCommand):
    help = 'Force expire a list of Activity Email tokens.'

    def add_arguments(self, parser):
        """Handle command arguments."""
        parser.add_argument('token_uuid', nargs='*')
        parser.add_argument(
            '--version_id',
            action='store',
            type=int,
            dest='version_id',
            help='Expire all tokens on this version.',
        )

    def handle(self, *args, **options):
        version_pk = options.get('version_id')
        token_uuids = options.get('token_uuid')
        if token_uuids:
            done = [
                t.expire()
                for t in ActivityLogToken.objects.filter(uuid__in=token_uuids)
            ]
            log.info('{} tokens ({}) expired'.format(len(done), ','.join(token_uuids)))
            if version_pk:
                print('Warning: --version_id ignored as tokens provided too')
        elif version_pk:
            done = [
                t.expire()
                for t in ActivityLogToken.objects.filter(version__pk=version_pk)
            ]
            log.info(f'{len(done)} tokens for version {version_pk} expired')
        else:
            raise CommandError(
                'Please provide either at least one token, or a version id.'
            )


# Реализуйте RLE алгоритм: реализуйте модуль сжатия и восстановления данных.
# Входные и выходные данные хранятся в отдельных текстовых файлах.

def rle_encode(raw_str):
    encoded = ''
    prev_char = ''
    count = 1
    # если строка пустая возвращаем пусто
    if not raw_str:
        return ''
    for char in raw_str:
        # если текущий символ не совпадает с предыдущим
        if char != prev_char:
            # тогда добаляем количество и символ
            if prev_char:
                encoded += str(count) + prev_char
            count = 1
            prev_char = char
        else:
            # иначе добавляем количество
            count += 1
    else:
        # закончили сжатие
        encoded += str(count) + prev_char
    return encoded

def rle_decode(encodedstring):
    decode = ''
    count = ''
    for char in encodedstring:
        # если символ - цифра
        if char.isdigit():
            # добавляем к количеству
            count += char
        else:
            # иначе символ, значит записываем символ count раз
            decode += char * int(count)
            count = ''
    return decode

print()

compressed_text = rle_encode(input('Введите кодируюмую строку -> ')) #
print()
print(f'Сжатие по алгоритму: {compressed_text}')
# результат записываем в файл
with open("coded_rle.txt", "w", encoding="utf-8") as my_f:
    my_f.write(compressed_text)

print()
# считываем из файла (, ранее закодированные данные) и раскодируем их
with open("coded_rle.txt") as my_f:
    compressed_text2 = my_f.readline()
print(f'Результат чтения из файла и раскодирования по алгоритму: {rle_decode(compressed_text2)}')
print()


"""Programa desenvolvido na UFRJ para disciplina Algortmos e Programação"""

def naocomuns(a,b):
    #retorna os elementos não comuns entre duas listas 'a' e 'b'
    naocomuns = []

    for i in range (0,len(a)):

        if not (a[i] in b):
            naocomuns = naocomuns + [a[i]]

    for i in range (0,len(b)):

        if not (b[i] in a):
            naocomuns = naocomuns + [b[i]]

    return naocomuns


'''
문제를 잘못 인지하고 전전긍긍했던 문제
인지하지 못했던 문제 단어 "X의 각 자리가 등차수열"
문제 출제자의 의도는 101의 수는 1, 0, 1 이지만 인지하기 전에는 1~101 수 안의 등차수열 개수로 잘못 인지
'''
num = int(input())
cnt = 0
for i in range(1, num + 1):
	if 100 > i:
		cnt += 1
	elif 1000 > i:
		f_n = i // 100
		s_n = i // 10 % 10
		t_n = i % 10
		if s_n - f_n == t_n - s_n:
			cnt += 1
print(cnt)


#!/usr/bin/env python
from geometry_msgs.msg import Pose, Point
from pilz_robot_programming import *
import math
import rospy
# from utils import *

__REQUIRED_API_VERSION__ = "1"  # API version
__ROBOT_VELOCITY__ = 0.5        # velocity of the robot

# main program
def start_program():
    # print the current position of thr robot in the terminal
    rospy.loginfo("Current pose: %s", r.get_current_pose(target_link="Tip", base="base_link"))

    # move to starting position
    # rospy.loginfo("Move to starting position 1 ")
    # r.move(Ptp(goal=[0.0 , 1.65 , 0.4 , 0 , 1 , 3.65],
    #     planning_group="denso_arm_torch", reference_frame="base_link",
    #     vel_scale=0.4, acc_scale=0.4))
    # rospy.loginfo("\tNew pose: %s", r.get_current_pose(target_link="Tip", base="base_link"))

    rospy.loginfo("Move to starting point 1")
    r.move(Ptp(goal=Pose(position=Point(-0.5028, 0.0000, 0.5386), orientation=Quaternion(0.0135, 0.9238, 0.0056, -0.3827)),
           relative=False, reference_frame="base_link", planning_group="denso_arm_torch", target_link="Tip",
           vel_scale=0.5, acc_scale=0.5))
    rospy.loginfo("\tNew pose: %s", r.get_current_pose(target_link="Tip", base="base_link"))

    rospy.loginfo("Move to starting point 2")
    r.move(Lin(goal=Pose(position=Point(-0.5325, 0.0019, 0.0340), orientation=Quaternion(0.0134, 0.9238, 0.0055, -0.3827)),
           relative=False, reference_frame="base_link", planning_group="denso_arm_torch", target_link="Tip",
           vel_scale=0.1, acc_scale=0.1))
    rospy.loginfo("\tNew pose: %s", r.get_current_pose(target_link="Tip", base="base_link"))

    # Welding trajectory 1:
    #   1. Move left & change orientation
    #   2. Move Forward

    rospy.loginfo("Move left and change orientation")
    r.move(Lin(goal=Pose(position=Point(-0.5298, 0.0946, 0.0340), orientation=Quaternion(-0.4009, 0.8119, -0.1325, -0.4031)),
           relative=False, reference_frame="base_link", planning_group="denso_arm_torch", target_link="Tip",
           vel_scale=0.05, acc_scale=0.05))
    rospy.loginfo("\tNew pose: %s", r.get_current_pose(target_link="Tip", base="base_link"))

#     rospy.loginfo("Move forward")
#     r.move(Lin(goal=Pose(position=Point(0.012, 0.0, 0)),
#            relative=True, reference_frame="BASE", planning_group="denso_arm_torch", target_link="Tip",
#            vel_scale=0.1, acc_scale=0.1))
#     rospy.loginfo("\tNew pose: %s", r.get_current_pose(target_link="Tip", base="base_link"))

    # Welding trajectory 2:
    #   1. Move left
    #   2. Circular motion

    # rospy.loginfo("Move left and change orientation")
    # r.move(Lin(goal=Pose(position=Point(0, -0.2, 0), orientation=from_rpy(0,0,0)),
    #        relative=True, reference_frame="BASE", planning_group="denso_arm_torch", target_link="Tip",
    #        vel_scale=0.1, acc_scale=0.1))
    # rospy.loginfo("\tNew pose: %s", r.get_current_pose(target_link="Tip", base="base_link"))

    # rospy.loginfo("Move circular")
    # r.move(Circ(goal=Pose(position=Point(-0.632, -0.107, 0.132)), center=Point(-0.632, -0.095, 0.132),
    #         reference_frame="base_link", planning_group="denso_arm_torch", target_link="Tip",
    #         vel_scale=0.1, acc_scale=0.1))
    # rospy.loginfo("\tNew pose: %s", r.get_current_pose(target_link="Tip", base="base_link"))

    # Welding trajectory 3:
    #   1. Move left & change orientation
    #   2. Blend
    #   3. Move Forward

    # Welding trajectory 4:
    #   1. Move left
    #   2. Blend
    #   3. Circular motion

if __name__ == "__main__":
    # init a rosnode
    rospy.init_node('robot_program_node')

    # initialisation
    r = Robot(__REQUIRED_API_VERSION__)  # instance of the robot

    # start the main program
    start_program()


import sys
from Graph import Graph
from Vertex import Vertex
comps = 0

def findAdjecentVertexes(g: Graph, v: Vertex) -> list:
    global comps
    if not v:
        comps += 1
        return
    res = []
    for edge in g.edges:
        comps += 2
        if edge.vertex1 == v:
            res.append(edge.vertex2)
        elif edge.vertex2 == v:
            res.append(edge.vertex1)
    return res

def findNonAdjecentVertexes(g: Graph, vertexs: list) -> list:
    global comps

    res = []

    for in_vertex in vertexs:
        adjacent_vertexs = findAdjecentVertexes(g, in_vertex)
        if adjacent_vertexs == None:
            comps += 1
            continue
        for vertex in g.vertexs:
            if vertex in res:
                if vertex in adjacent_vertexs:
                    res.remove(vertex)
                    comps += 2

            else:
                if vertex not in adjacent_vertexs:
                    if vertex not in vertexs:
                        res.append(vertex)
                        comps += 3
    return res

def getMinEdgesVertex(graph: Graph, vertexs: list) -> Vertex:
    global comps
    if vertexs == []:
        comps += 1
        return None
    min_edges_count = len(graph.vertexs)
    min_edges_vertex = None
    for vertex in vertexs:
        current_vertext_edges_count = 0
        for edge in graph.edges:
            if edge.containsVertex(vertex):
                comps += 2
                current_vertext_edges_count += 1
        if current_vertext_edges_count < min_edges_count:
            comps += 1
            min_edges_count = current_vertext_edges_count
            min_edges_vertex = vertex
    return min_edges_vertex

def calculateMaxIndependetSet(graph: Graph) -> set:
    global comps

    current_vertex = getMinEdgesVertex(graph, graph.vertexs)
    res = []
    vertexs_to_explore = (findNonAdjecentVertexes(graph, [current_vertex]))
    res.append(current_vertex)
    while True:
        if not vertexs_to_explore:
            comps += 1
            break
        current_vertex = getMinEdgesVertex(graph, vertexs_to_explore)
        res.append(current_vertex)
        vertexs_to_explore = findNonAdjecentVertexes(graph, res)
    return res

if __name__ == '__main__':
    if len(sys.argv) == 1:
        print('Usage:\npython3 greedy_alg.py graph_vertex_count')
    elif len(sys.argv) == 2:
        total_vertexs = int(sys.argv[1])
        graph = Graph.loadGraph(total_vertexs)
        print(calculateMaxIndependetSet(graph))
        print(comps)


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

class ConvBlock(nn.Module):
    def __init__(self, in_channels, out_channels):
        super(ConvBlock, self).__init__()
        self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1)
        self.bn1 = nn.BatchNorm2d(out_channels)
        self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1)
        self.bn2 = nn.BatchNorm2d(out_channels)

    def forward(self, x):
        x = F.relu(self.bn1(self.conv1(x)))
        x = F.relu(self.bn2(self.conv2(x)))
        return x

class AttentionBlock(nn.Module):
    def __init__(self, in_channels, out_channels):
        super(AttentionBlock, self).__init__()
        self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=1)
        self.bn = nn.BatchNorm2d(out_channels)

        self.theta = nn.Conv2d(out_channels, out_channels, kernel_size=1)
        self.phi = nn.Conv2d(out_channels, out_channels, kernel_size=1)
        self.g = nn.Conv2d(out_channels, out_channels, kernel_size=1)

        self.attn_conv = nn.Conv2d(out_channels, out_channels, kernel_size=1)
        self.attn_bn = nn.BatchNorm2d(out_channels)

    def forward(self, x):
        residual = x

        x = self.conv(x)
        x = self.bn(x)

        theta = self.theta(x)
        phi = self.phi(x)
        g = self.g(x)

        theta = theta.view(theta.shape[0], theta.shape[1], -1)
        phi = phi.view(phi.shape[0], phi.shape[1], -1)
        g = g.view(g.shape[0], g.shape[1], -1)

        attn = F.softmax(torch.bmm(theta.permute(0, 2, 1), phi), dim=2)
        attn = torch.bmm(g, attn.permute(0, 2, 1))
        attn = attn.view(x.shape)

        attn = self.attn_conv(attn)
        attn = self.attn_bn(attn)

        x = x + attn
        x = F.relu(x)

        return x + residual

class UpBlock(nn.Module):
    def __init__(self, in_channels, out_channels):
        super(UpBlock, self).__init__()
        self.up = nn.ConvTranspose2d(in_channels, in_channels // 2, kernel_size=2, stride=2)
        self.conv = ConvBlock(in_channels, out_channels)

    def forward(self, x, skip_x):
        x = self.up(x)
        x = torch.cat([x, skip_x], axis=1)
        x = self.conv(x)
        return x

class AttU_Net(nn.Module):
    def __init__(self, in_channels=3, out_channels=1, init_features=32):
        super(AttU_Net, self).__init__()

        features = init_features
        self.encoder1 = ConvBlock(in_channels, features)
        self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)
        self.encoder2 = ConvBlock(features, features * 2)
        self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)
        self.encoder3 = ConvBlock(features * 2, features * 4)
        self.pool3 = nn

        MaxPool2d(kernel_size=2, stride=2)
        self.encoder4 = ConvBlock(features * 4, features * 8)
        self.pool4 = nn.MaxPool2d(kernel_size=2, stride=2)

        self.center = ConvBlock(features * 8, features * 16)

        self.decoder4 = UpBlock(features * 16, features * 8)
        self.attention4 = AttentionBlock(features * 16, features * 8)
        self.decoder3 = UpBlock(features * 8, features * 4)
        self.attention3 = AttentionBlock(features * 8, features * 4)
        self.decoder2 = UpBlock(features * 4, features * 2)
        self.attention2 = AttentionBlock(features * 4, features * 2)
        self.decoder1 = UpBlock(features * 2, features)
        self.attention1 = AttentionBlock(features * 2, features)

        self.output = nn.Conv2d(features, out_channels, kernel_size=1)

    def forward(self, x):
        skip1 = self.encoder1(x)
        x = self.pool1(skip1)

        skip2 = self.encoder2(x)
        x = self.pool2(skip2)

        skip3 = self.encoder3(x)
        x = self.pool3(skip3)

        skip4 = self.encoder4(x)
        x = self.pool4(skip4)

        x = self.center(x)

        x = self.decoder4(x, skip4)
        x = self.attention4(x)

        x = self.decoder3(x, skip3)
        x = self.attention3(x)

        x = self.decoder2(x, skip2)
        x = self.attention2(x)

        x = self.decoder1(x, skip1)
        x = self.attention1(x)

        x = self.output(x)

        return x


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('project', '0001_initial'),
        ('inventory', '0004_auto_20150924_1743'),
    ]

    operations = [
        migrations.RemoveField(
            model_name='inventoryaccount',
            name='opening_balance',
        ),
        migrations.AddField(
            model_name='inventoryaccount',
            name='site',
            field=models.ForeignKey(default=1, related_name='inventory_account', to='project.Project'),
            preserve_default=False,
        ),
    ]


from PIL import Image
from numpy import *
from pylab import *
import os

def ProcessImage(ImgName,ResultName,Params="--edge-thresh 10 --peak-thresh 5"):
    if ImgName[-3:]!='pgm':
        Img=Image.open(ImgName).convert('L');
        ImgName=ImgName[:-3]+'pgm';
        Img.save(ImgName);
    cmmd=str("sift "+ImgName+" --output="+ResultName+" "+Params);
    os.system(cmmd);
    print("Processed",ImgName,"To",ResultName);

def ReadFeaturesFromFile(FileName):
    f=loadtxt(FileName);
    return f[:,:4],f[:,4:];

def WriteFeaturesToFile(FileName,Locs,Desc):
    savetxt(FileName,hstack((Locs,Desc)));

def PlotFeatures(Img,Locs,Circle=False):
    def DrawCircle(c,r):
        t=arange(0,1.01,0.01)*2*pi;
        x=r*cos(t)+c[0];
        y=r*sin(t)+c[1];
        plot(x,y,'b',linewidth=2);

    imshow(Img);
    if Circle:
        for p in Locs:
            DrawCircle(p[:2],p[2]);
    else:
        plot(Locs[:,0],locs[:,1],'ob');
    axis('off');

def Match(Desc1,Desc2):
    Desc1=array([d/linalg.norm(d) for d in Desc1]);
    Desc2=array([d/linalg.norm(d) for d in Desc2]);

    DistRatio=0.6;
    DescSize=Desc1.shape;

    MatchScores=zeros((DescSize[0],1),'int');
    Desc2T=Desc2.T;
    for i in range(DescSize[0]):
        DotProds=0.9999*dot(Desc1[i,:],Desc2T);
        Index=argsort(arccos(DotProds));

        if arccos(DotProds)[Index[0]]<DistRatio*arccos(DotProds)[Index[1]]:
            MatchScores[i]=int(Index[0]);

    return MatchScores;

def MatchTwoSided(Desc1,Desc2):
    Matches12=Match(Desc1,Desc2);
    Matches21=Match(Desc2,Desc1);

    Index12=Matches12.nonzero()[0];

    for i in Index12:
        if Matches21[int(Matches12[i])]!=i:
            Matches12[i]=0;

    return Matches12;

def AppendImages(Img1,Img2):
    Rows1=Img1.shape[0];
    Rows2=Img2.shape[0];

    if Rows1<Rows2:
        Img1=concatenate((Img1,zeros((Rows2-Rows1,Img1.shape[1]))),axis=0);
    elif Rows1>Rows2:
        Img2=concatenate((Img2,zeros((Rows1-Rows2,Img2.shape[1]))),axis=0);

    return concatenate((Img1,Img2),axis=1);

def PlotMatches(Img1,Img2,Locs1,Locs2,MatchScores,ShowBelow=True):
    Img3=AppendImages(Img1,Img2);
    if ShowBelow:
        Img3=vstack((Img3,Img3));

    imshow(Img3);

    cols1=Img1.shape[1];
    for i,m in enumerate(MatchScores):
        if m[0]>0:
            plot([Locs1[i][0],Locs2[m[0]][0]+cols1],[Locs1[i][1],Locs2[m[0]][1]],'c');
    axis('off');


"""
  Author: Kuznetsov Igor, P3355
"""

from name_data import months_names, month_date_names, times_minute_names, \
    times_hours_names, years_ending_names, hundreds_names, hundreds_names_standalone

class DateToTextTransformer(object):
    def __init__(self):
        pass

    def transform(self, date):
        """
        Transforms date in numerical format into russian next.

        Args:
            date (str): for example 25.09.2019 08:17:59

        Returns (str): russian text
        """
        date_str, time_str = date.split(" ")
        dd, MM, yy = list(map(int, date_str.split(".")))
        hh, mm, ss = list(map(int, time_str.split(":")))

        s = f"{month_date_names[dd]} {months_names[MM]} {self._year2text(yy)} года" \
            f" {times_hours_names[hh]} час{self._hour_postfix(hh)} " \
            f"{times_minute_names[mm]} минут{self._second_minute_postfix(mm)} " \
            f"{times_minute_names[ss]} секунд{self._second_minute_postfix(ss)}"

        return s.strip()

    def _hour_postfix(self, hh):
        if hh % 10 in [2, 3, 4]:
            return "а"
        if hh % 10 in [0, 5, 6, 7, 8, 9]:
            return "ов"
        return ""

    def _second_minute_postfix(self, mm):
        if mm % 10 == 1 and mm != 11:
            return "а"
        if mm % 10 in [2, 3, 4] and mm//10 != 1:
            return "ы"
        return ""

    def _year2text(self, yy):
        s = ""

        # Edge case
        if yy == 2000:
            return "двухтысячного"

        if yy // 1000 == 1:
            s += "одна тысяча "
            if yy % 100 == 0:
                print(yy%1000//100)
                s += hundreds_names_standalone[yy%1000//100]
            else:
                s += hundreds_names[yy%1000//100] + " "
        else:
            s += "две тысячи "

        if yy%100 != 0:
            s += years_ending_names[yy%100]
        return s

if __name__ == "__main__":
    transormer = DateToTextTransformer()

    s = "25.09.2019 08:17:59"
    text = transormer.transform(s)
    print(text)


from WdA.Lista03 import Lista03zad01

class Node:
    """Class representing a single Node"""
    def __init__(self, data=None, left=None, right=None, parent=None):
        self.data = data
        self.left = left
        self.right = right
        self.parent = parent

    def __str__(self):
        return str(self.data)

class LinkedList(Lista03zad01.Queue):
    """Class representing a single Linked List structure"""
    def __init__(self, head=None):
        super(LinkedList, self).__init__(head)
        self.head = head

    def print_list(self):
        """Prints out all the nodes in a linked list to the console. Written in debugging purposes"""
        node = self.head
        while node:
            print(node.data)
            node = node.next

    def pop(self):
        """Removes and returns the first item (index 0) from a Linked List"""
        if self.head:
            head = self.head
            self.head = self.head.next
            return head.data
        else:
            return None

    def is_empty(self):
        """Checks if there are no values in the Linked List"""
        if self.head:
            return False
        else:
            return True

def breadth_first_search(tree):
    """Visits every node of a binary tree using the Breadth First Search algorithm"""
    visited = []
    queue = LinkedList()
    queue.append(tree)
    while not queue.is_empty():
        node = queue.pop()
        visited.append(node.data)
        if node.left:
            queue.append(node.left)
        if node.right:
            queue.append(node.right)
    print(visited)

def depth_first_search(tree):
    """Visits every node of a binary tree using the Depth First Search algorithm"""
    visited = []
    stack = LinkedList()
    stack.prepend(tree)
    while not stack.is_empty():
        node = stack.pop()
        visited.append(node.data)
        if node.right:
            stack.prepend(node.right)
        if node.left:
            stack.prepend(node.left)
    print(visited)

def btree_print_indented(top, level=0):
    """Prints the binary tree to the console horizontally"""
    if top is None:
        return
    btree_print_indented(top.right, level + 1)
    print("{}* {}".format('   ' * level, top))
    btree_print_indented(top.left, level + 1)

root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
root.right.left = Node(6)
root.right.right = Node(7)
root.left.left.left = Node(8)

if __name__ == '__main__':
    print("\n" + 70 * "-")

    print("\nList of visited nodes in chronological order using the BFS algorithm:")
    breadth_first_search(root)

    print("\nList of visited nodes in chronological order using the DFS algorithm:")
    depth_first_search(root)

    print("\n" + 70 * "-")

    btree_print_indented(root)


#! /usr/bin/python3
import iota.harness.api as api
import iota.protos.pygen.topo_svc_pb2 as topo_svc_pb2
from iota.test.iris.testcases.aging.aging_utils import *
import pdb

GRACE_TIME=5

def Setup(tc):
    if tc.args.type == 'local_only':
        tc.workload_pairs = api.GetLocalWorkloadPairs()
    else:
        tc.workload_pairs = api.GetRemoteWorkloadPairs()
    w1, w2 = tc.workload_pairs[0]
    tc.naples = w1 if w1.IsNaples() else w2
    return api.types.status.SUCCESS

def Trigger(tc):
    req = api.Trigger_CreateExecuteCommandsRequest(serial = True)
    tc.cmd_cookies = []

    #Step 0: Update the timeouti & connection-tracking in the config object
    if not tc.args.skip_security_prof:
        update_timeout("icmp-timeout", tc.iterators.timeout)

    w1, w2 = tc.workload_pairs[0]
    cmd_cookie = "%s(%s) --> %s(%s)" %\
                  (w1.workload_name, w1.ip_address, w2.workload_name, w2.ip_address)
    api.Logger.info("Starting Ping test from %s" % (cmd_cookie))

    cmd_cookie = "halctl clear session"
    api.Trigger_AddNaplesCommand(req, tc.naples.node_name, "/nic/bin/halctl clear session")
    tc.cmd_cookies.append(cmd_cookie)

    if not tc.args.skip_security_prof:
        timeout = timetoseconds(tc.iterators.timeout) + GRACE_TIME
    else:
        timeout = str(DEFAULT_ICMP_TIMEOUT + GRACE_TIME)

    cmd_cookie = "ping"
    api.Trigger_AddCommand(req, w1.node_name, w1.workload_name,
                           "ping -c 3 %s" % w2.ip_address)
    tc.cmd_cookies.append(cmd_cookie)

    cmd_cookie = "Before aging show session ICMP"
    api.Trigger_AddNaplesCommand(req, tc.naples.node_name, "/nic/bin/halctl show session | grep ICMP")
    tc.cmd_cookies.append(cmd_cookie)

    #Get it from the config
    cmd_cookie = "sleep"
    api.Trigger_AddNaplesCommand(req, tc.naples.node_name, "sleep %s"%(timeout), timeout=300)
    tc.cmd_cookies.append(cmd_cookie)

    cmd_cookie = "After aging show session"
    api.Trigger_AddNaplesCommand(req, tc.naples.node_name, "/nic/bin/halctl show session | grep ICMP")
    tc.cmd_cookies.append(cmd_cookie)

    tc.resp = api.Trigger(req)
    return api.types.status.SUCCESS

def Verify(tc):
    if tc.resp is None:
        return api.types.status.FAILURE

    #if tc.config_update_fail == 1:
    #    return api.types.status.FAILURE

    result = api.types.status.FAILURE
    cookie_idx = 0

    for cmd in tc.resp.commands:
        api.Logger.info("Results for %s" % (tc.cmd_cookies[cookie_idx]))
        api.PrintCommandResults(cmd)
        if cmd.exit_code != 0:
            #This is expected so dont set failure for this case
            if tc.cmd_cookies[cookie_idx].find("After aging") != -1 or \
               tc.cmd_cookies[cookie_idx].find("ping") != -1:
                result = api.types.status.SUCCESS
        if tc.cmd_cookies[cookie_idx].find("clear session") != -1:
           if cmd.stdout == '':
              result = api.types.status.SUCCESS
        elif tc.cmd_cookies[cookie_idx].find("Before aging") != -1:
           #Session were not established ?
           if cmd.stdout.find("ICMP") == -1:
               result = api.types.status.FAILURE
        elif tc.cmd_cookies[cookie_idx].find("After aging") != -1:
           #Check if sessions were aged
           if cmd.stdout.find("ICMP") != -1:
              result = api.types.status.FAILURE
        cookie_idx += 1
    return result

def Teardown(tc):
    return api.types.status.SUCCESS


#!/usr/bin/env python3
import psycopg, os, os.path, jinja2, json

config = json.load(open("/etc/juniorgopher/config.json"))
db = psycopg.connect(config['db'])

c = db.cursor()
c.execute("SELECT id, url FROM cameras")
camera_ids = [camera_id for camera_id, camera_url in c.fetchall()]

template = jinja2.Template(open('index.html.jinga').read())

print(template.render(camera_ids=camera_ids))


import PyQt5.QtWidgets
from PyQt5.QtWidgets import QFileDialog
import math
from TabelModel import Model
import form2
from itertools import groupby
import mainwindow
import sys
import re

class Form(PyQt5.QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        self.ui = form2.Ui_Form()
        self.ui.setupUi(self)
        self.ui.groupBox.hide()

    def closeEvent(self, event):
        main_window.show()
        event.accept()

class MainWindow(PyQt5.QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.ui = mainwindow.Ui_MainWindow()
        self.ui.setupUi(self)
        self.text1 = ""
        self.text2 = ""

# FOR TABLE -> columns, rows = 3, 5

columns, rows = 3, 5
app = PyQt5.QtWidgets.QApplication(sys.argv)
main_window = MainWindow()

def show_second_form():
    if len(main_window.text1) == 0 or len(main_window.text2) == 0 or len(main_window.ui.textEdit.toPlainText()) == 0:
        return False
    form = Form()
    form.show()
    main_window.hide()
    text1 = main_window.text1
    text2 = main_window.text2
    word_search = main_window.ui.textEdit.toPlainText()

    def cook_text(input_text, search):
        text_words = re.compile('\w+').findall(input_text)
        text_words_count = len(text_words)
        duplicates_in_text = [0] * (math.ceil(text_words_count / 1000))

        for idx, val in enumerate(text_words):
            if search.lower() == val.lower():
                duplicates_in_text[int(idx / 1000)] += 1
        # duplicates_in_text = list(filter((0).__ne__, duplicates_in_text))
        return sorted(duplicates_in_text), text_words_count

    def cook_matrix(elms, text_words_count):
        c1 = sorted(list(set(elms)))
        c2 = [len(list(group)) for key, group in groupby(elms)]
        c3 = list(map(lambda x, y: x * y, c1, c2))
        matrix = [["" for x in range(6)] for y in c1]
        sum_c2 = sum(c2)
        sum_c3 = sum(c3)
        sum_c5 = 0
        ser = sum_c3 / sum_c2
        for idx in range(len(c1)):
            matrix[idx][0] = c1[idx]
            matrix[idx][1] = c2[idx]
            matrix[idx][2] = c3[idx]
            matrix[idx][3] = c1[idx] - ser
            matrix[idx][4] = (c1[idx] - ser) ** 2
            matrix[idx][5] = ((c1[idx] - ser) ** 2) * c2[idx]
            sum_c5 += matrix[idx][5]
        vid = math.sqrt(sum_c5 / sum_c2)
        mira = vid / math.sqrt(sum_c2)
        var = vid / ser
        stab = 1 - (var / (math.sqrt(sum_c2 - 1)))
        es = sum_c5 / (sum_c2 * (sum_c2 - 1))
        vidn = sum_c3 / text_words_count
        return matrix, ser, vid, mira, var, stab, es, sum_c2, vidn, sum_c3

    cooked_text1, text_words_count1 = cook_text(text1, word_search)
    cooked_text2, text_words_count2 = cook_text(text2, word_search)

    matrix1, ser1, vid1, mira1, var1, stab1, es1, sumc21, vidn1, sumc31 = cook_matrix(cooked_text1, text_words_count1)
    matrix2, ser2, vid2, mira2, var2, stab2, es2, sumc22, vidn2, sumc32 = cook_matrix(cooked_text2, text_words_count2)

    form.ui.tableView.setModel(Model(form, matrix=matrix1))
    form.ui.tableView_2.setModel(Model(form, matrix=matrix2))

    form.ui.label_7.setText(format(ser1, '.4f'))
    form.ui.label_12.setText(format(ser2, '.4f'))
    form.ui.label_8.setText(format(vid1, '.4f'))
    form.ui.label_13.setText(format(vid2, '.4f'))
    form.ui.label_9.setText(format(mira1, '.4f'))
    form.ui.label_14.setText(format(mira2, '.4f'))
    form.ui.label_10.setText(format(var1, '.4f'))
    form.ui.label_17.setText(format(var2, '.4f'))
    form.ui.label_11.setText(format(stab1, '.4f'))
    form.ui.label_21.setText(format(stab2, '.4f'))
    form.ui.label_5.setText(format(vidn1, '.4f'))
    form.ui.label_24.setText(format(vidn2, '.4f'))

    def compare():
        smuga1 = ser1 + (mira1 * 2)
        smuga2 = ser1 - (mira2 * 2)
        smuga3 = ser2 + (mira2 * 2)
        smuga4 = ser2 - (mira2 * 2)

        st1 = 'від {0:.2f} до {1:.2f}'.format(smuga2, smuga1)
        st2 = 'від {0:.2f} до {1:.2f}'.format(smuga4, smuga3)

        p = ((vidn1*100*sumc31) + (vidn2*100*sumc32))/(sumc31+sumc32)

        stud = (ser1 - ser2) / (math.sqrt(es1 + es2))
        stud_pro = ((vidn1*100) - (vidn2*100)) / math.sqrt(p * (100-p) * (1/sumc31+1/sumc32))

        svoboda1 = (11 - 1)*(2 - 1)
        svoboda2 = sumc21 + sumc22 - 2
        svoboda3 = sumc31 + sumc32 - 2

        t_text1 = cooked_text1
        t_text2 = cooked_text2
        f_sk = list((map(lambda x, y: x + y, t_text1, t_text2)))
        f_N = sum(t_text1) + sum(t_text2)
        f_sm = [sum(t_text1), sum(t_text2), f_N]
        s_m_1 = sum(map(lambda x, y: (x ** 2) / (y * f_sm[0]) if (y != 0) else 0, t_text1, f_sk))
        s_m_2 = sum(map(lambda x, y: (x ** 2) / (y * f_sm[1]) if (y != 0) else 0, t_text2, f_sk))
        f_result = f_N * ((s_m_1 + s_m_2) - 1)

        form.ui.groupBox.show()
        form.ui.pushButton.hide()
        form.ui.label_34.setText(format(stud, '.4f'))
        form.ui.label_39.setText(format(stud_pro, '.4f'))
        form.ui.label_31.setText(format(svoboda1, '.4f'))
        form.ui.label_35.setText(format(svoboda2, '.4f'))
        form.ui.label_37.setText(format(svoboda3, '.4f'))
        form.ui.label_26.setText(st1)
        form.ui.label_27.setText(st2)
        form.ui.label_29.setText(format(f_result, '.4f'))

    form.ui.pushButton.clicked.connect(compare)

    # form.ui.pushButton.clicked.connect(form.hide)

def OpenDialog():
    dlg = QFileDialog()
    dlg.setFileMode(QFileDialog.AnyFile)
    dlg.setNameFilters(["Text files (*.txt)"])
    return dlg

def OpenFirstFile(self):
    dlg = OpenDialog()
    if dlg.exec_():
        with open(dlg.selectedFiles()[0], 'r') as f:
            data = f.read()
            main_window.ui.textBrowser.setText(data)
            main_window.text1 = data

def OpenSecondFile(self):
    dlg = OpenDialog()
    if dlg.exec_():
        with open(dlg.selectedFiles()[0], 'r') as f:
            data = f.read()
            main_window.ui.textBrowser_2.setText(data)
            main_window.text2 = data

main_window.ui.pushButton.clicked.connect(show_second_form)
main_window.ui.pushButton_2.clicked.connect(OpenFirstFile)
main_window.ui.pushButton_3.clicked.connect(OpenSecondFile)
main_window.show()

sys.exit(app.exec_())


import os
import subprocess
import discord

def init(client: "Client"):

    @client.command(["kill"])
    async def kill(message: discord.Message):
        """
        This command is for stop the CLIENT,

        If someone wants to use this command,
        his discord user's id need to be in the hard-coded id list
        :param message: discord.Message
        """
        list_admin = [290227829558345728]
        if message.author.id in list_admin:
            await message.reply("SIR, YES SIR !")

            for voice_client in client.voice_clients:
                await voice_client.disconnect()

            # This is a command to kill the current process.
            # Because discord.py API don't make it after disconnected,
            # I need to kill the current process to stop the program.
            # I know that's not a good solution. Contact tamikata#2214 if you have another solution.
            subprocess.run(f'kill -9 {os.getpid()}', shell=True)


"""ECMWF UK data pipeline."""

from nwp_consumer.internal import FetcherInterface
from nwp_consumer.internal.inputs.ecmwf import mars

from local_archives.nwp._generic_definitions_factory import (
    MakeDefinitionsOptions,
    MakeDefinitionsOutputs,
    make_definitions,
)
from local_archives.partitions import InitTimePartitionsDefinition

fetcher: FetcherInterface = mars.Client(
    area="uk",
)

partitions: InitTimePartitionsDefinition = InitTimePartitionsDefinition(
    start="2017-01-01",
    init_times=["00:00", "12:00"],
)

defs: MakeDefinitionsOutputs = make_definitions(
    opts=MakeDefinitionsOptions(
        area="uk",
        source="ecmwf",
        partitions=partitions,
        fetcher=fetcher,
    ),
)

ecmwf_uk_source_archive = defs.source_asset
ecmwf_uk_raw_archive = defs.raw_asset
ecmwf_uk_zarr_archive = defs.zarr_asset


"""
Write an algorithm that takes an array and moves all of the zeros to the end, preserving the order of the other elements.

move_zeros([1, 0, 1, 2, 0, 1, 3]) # returns [1, 1, 2, 1, 3, 0, 0]
"""
def move_zeros(lst):
    num_of_zeros = lst.count(0)
    # print(num_of_zeros)

    lst = list(filter(None, lst))
    # print(lst)

    for i in range(num_of_zeros):
        lst.append(0)

    # print(lst)
    return lst

# ALTERNATIVE USING LIST COMPREHENSION
# l = [i for i in arr if i != 0]
# return l + [0] * (len(arr) - len(l))


import pandas as pd

f = open("D:\Latest  programs &  data  that work -in IDLE-/1st 495 symbols.csv", "r")

'''
df_old = pd.read_csv("A.csv")
print(df_old.head())
df_old.drop(["volume", "timestamp", "open", "high", "low"], axis = 1, inplace = True)
print(df_old.head())

'''
for symbol in f.readlines():

    symbol = symbol.strip()

    url_part1 = symbol
    url_part2 = ".csv"
    url = url_part1 + url_part2

    df_old = pd.read_csv(url)
    print(df_old.head())
    df_old.drop(["volume", "timestamp", "open", "high", "low"], axis = 1, inplace = True)
    print(df_old.head())

    df_old.set_index('close')
    #df_old.rename(columns={'close':(symbol)}, inplace=True)
    print(df_old.head())

    #df_old.to_csv(r'D:\Latest  programs &  data  that work -in IDLE-\revised colum csvs\(url)')


'''
Predicting on the ~10 enantiomer pairs selected in chemdraw w/ JUST RF and KNN.
'''

import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import classification_report, accuracy_score
from rdkit import Chem
from rdkit.Chem import AllChem
import argparse

rf = RandomForestClassifier()
kn = KNeighborsClassifier()

def make_fingerprint(smiles):
    mol = Chem.MolFromSmiles(smiles)
    fps = AllChem.GetMorganFingerprintAsBitVect(mol, 2, 2048)
    return np.array(fps)

def make_inputs(df):
    inputs = np.array([])
    for smiles in df['canonical_smiles']:
        fps_i = make_fingerprint(smiles)
        chiral_tag_i = make_chiral_tag(smiles)
        fps_i = np.concatenate((fps_i, chiral_tag_i))
        inputs = np.concatenate((inputs, fps_i))
    return inputs.reshape([len(df), -1])

def extract_fragrance_class(df_row):
    keys = list(df_row.keys())
    one_hot_fragrance = df_row[keys[5:-1]]
    return np.array(one_hot_fragrance)

def make_labels(df):
    labels = np.array([])
    for i in range(len(df)):
        label_i = extract_fragrance_class(df.iloc[i])
        labels = np.concatenate((labels, label_i))
    labels = labels.reshape([len(df), -1])
    labels = labels.astype('int')
    return labels

def init_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--path_to_data', type=str, help='path to fragrance pickle data.',
                        default='data/pyrfume_enatiomer_pairs_removed.pickle')
    parser.add_argument('--path_to_enantiomers', type=str, help='The path to the enantiomer pickle file.',
                        default='data/one_hot_aicrowd_enantiomers_columns_fixed.pickle')
    return parser.parse_args()

def make_true_label(vocab, df_row):
    '''
    From a single row, make the corresponding text label.
    '''
    label = []
    # For every '1' in the df_row, add it to the label
    for name in vocab:
        if df_row[name] == 1:
            label.append(name)
    return label

def make_true_labels(df):
    all_labels = []
    vocab = list(df.keys())[5:-1]
    for i in range(len(df)):
        all_labels.append(make_true_label(vocab, df.iloc[i]))
    return all_labels

def make_top_N_single_pred_label(vocab, pred, true):
    '''
    Find the top N a single predicted label, where N = number of classes in true label.
    '''
    pred_label = []
    N = 5
    # Find top N, including duplicates, then remove the duplicates for the for loop, then sort again to keep order.
    top_Ns = np.sort(np.unique(np.sort(pred)[::-1][0:N]))[::-1]

    # Finding the top N entries.
    top_N_idxs = []
    for top_pred in top_Ns:
        top_pred_idx = np.where(pred == top_pred)[0]
        # Appending the idxs to
        for idx in top_pred_idx:
            top_N_idxs.append(idx)

    # Finding the corresponding vocab.
    for idx in top_N_idxs:
        pred_label.append(vocab[idx])
    return pred_label

def make_top_N_pred_labels(test_df, all_preds):
    vocab = list(test_df.keys())[5:-1]
    all_pred_labels = []
    for i, pred in enumerate(all_preds):
        true_label = make_true_label(vocab, test_df.iloc[i])
        all_pred_labels.append(make_top_N_single_pred_label(vocab, pred, true_label))
    return all_pred_labels

def make_chiral_tag(smiles):
    mol = Chem.MolFromSmiles(smiles)
    chiral_atoms = [str(x.GetChiralTag()) for x in mol.GetAtoms()]
    if 'CHI_TETRAHEDRAL_CW' in chiral_atoms:
        chiral_tag = np.array([1, 0, 0])
    elif 'CHI_TETRAHEDRAL_CCW' in chiral_atoms:
        chiral_tag = np.array([0, 1, 0])
    else:
        chiral_tag = np.array([0, 0, 1])
    return chiral_tag

def main():
    # args = init_args()
    # path_to_data = args.path_to_data
    # path_to_enantiomers = args.path_to_enantiomers
    path_to_data = 'data/pyrfume_enatiomer_pairs_removed.pickle'
    path_to_enantiomers = 'data/one_hot_aicrowd_enantiomers_columns_fixed.pickle'

    print('Loading in data...')
    print()
    df = pd.read_pickle(path_to_data)
    enantiomers = pd.read_pickle(path_to_enantiomers)

    test_idxs = [6, 61, 8, 86, 10, 51, 20, 38, 48, 16, 9, 34, 12, 74, 13, 27, 17, 85, 39, 42, 46, 68]

    # Split the dataframe.
    test_df = enantiomers.loc[test_idxs].reset_index(drop=True)
    enantiomers = enantiomers.drop(test_idxs)
    train_df = pd.concat((df, enantiomers)).reset_index(drop=True)
    preds = test_df.copy()

    print('Embedding the molecules...')
    print()
    # Make the inputs and labels
    train_inputs = make_inputs(train_df)
    test_inputs = make_inputs(test_df)

    print('Inputs Made.')
    print()

    print('Forming labels...')
    print()
    train_labels = make_labels(train_df)
    test_labels = make_labels(test_df)

    print('Labels Made.')
    print()

    rf.fit(train_inputs, train_labels)
    rf_preds = rf.predict(test_inputs)
    f1 = classification_report(test_labels, rf_preds, output_dict=True, zero_division=0.0)
    f1_macro = f1['macro avg']['f1-score']
    f1_weighted = f1['weighted avg']['f1-score']
    accuracy = accuracy_score(test_labels, rf_preds)

    # Making the labels.
    true_labels = make_true_labels(preds)
    rf_pred_labels = make_top_N_pred_labels(preds, rf_preds)

    preds['true_labels'] = true_labels
    preds['rf_pred_labels'] = rf_pred_labels

    print('---------------- Random Forest ----------------')
    print(f"F1 (Macro): {f1_macro}, F1 (Weighted): {f1_weighted}, Accuracy: {accuracy}")
    print()

    kn.fit(train_inputs, train_labels)
    kn_preds = kn.predict(test_inputs)
    f1 = classification_report(test_labels, kn_preds, output_dict=True, zero_division=0.0)
    f1_macro = f1['macro avg']['f1-score']
    f1_weighted = f1['weighted avg']['f1-score']
    accuracy = accuracy_score(test_labels, kn_preds)

    kn_pred_labels = make_top_N_pred_labels(preds, kn_preds)
    preds['knn_pred_labels'] = kn_pred_labels

    print('---------------- K-Neighbors ----------------')
    print(f"F1 (Macro): {f1_macro}, F1 (Weighted): {f1_weighted}, Accuracy: {accuracy}")
    print()

    print(preds['rf_pred_labels'])
    print(preds['knn_pred_labels'])
    # preds.to_pickle('enantiomer_baseline_predictions.pickle')
if __name__ == '__main__':
    main()


import pygit2
from collections import defaultdict
from taf.log import taf_logger as logger
from taf.exceptions import GitError
import os.path

class PyGitRepository:
    def __init__(
        self,
        encapsulating_repo,
        *args,
        **kwargs,
    ):
        self.encapsulating_repo = encapsulating_repo
        self.path = encapsulating_repo.path
        self.repo = pygit2.Repository(str(self.path))

    _files_cache = defaultdict(dict)

    def _get_child(self, parent, path_part):
        """
        Return the child object of a parent object.
        Used for walking a git tree.
        """
        try:
            out = parent[path_part]
        except KeyError:
            return None
        else:
            return self.repo[out.id]

    def _get_object_at_path(self, obj, path):
        """
        for the given commit object,
        get the object at the given path
        """
        working = obj.tree
        if path.endswith("/"):
            path = path[:-1]
        path = path.split("/")
        for part in path:
            working = self._get_child(working, part)
            if working is None:
                return None
        return working

    def _get_blob_at_path(self, obj, path):
        """
        for the given commit object,
        get the blob at the given path
        """
        logger.debug("Get blob at path %s", path)
        working = self._get_object_at_path(obj, path)
        if working and isinstance(working, pygit2.Blob):
            logger.debug("Found blob at path %s", "/".join(path))
            return working
        logger.debug("Blob not found at path %s", "/".join(path))
        return None

    def cleanup(self):
        """
        Must call this function in order to release pygit2 file handles.
        """
        self.repo.free()

    def get_file(self, commit, path, raw=False):
        """
        for the given commit string,
        return the string contents of the blob at the
        given path, if it exists, otherwise raise GitError
        """
        obj = self.repo.get(commit)
        blob = self._get_blob_at_path(obj, path)
        if blob is None:
            raise GitError(
                self.encapsulating_repo,
                message=f"fatal: Path '{path}' does not exist in '{commit}'",
            )
        else:
            git_id = blob.hex
            type = "raw" if raw else "decoded"
            if git_id not in self._files_cache or type not in self._files_cache[git_id]:
                content = blob.read_raw() if raw else blob.read_raw().decode()
                self._files_cache[git_id] |= {type: content}
            return git_id, self._files_cache[git_id][type]

    def _list_files_at_revision(self, tree, path="", results=None):
        """
        recurse through tree and return paths relative to that tree for
        all blobs in that tree.
        """
        if results is None:
            results = []

        for entry in tree:
            new_path = os.path.join(path, entry.name)
            if entry.type_str == "blob":
                results.append(new_path)
            elif entry.type_str == "tree":
                obj = self._get_child(tree, entry.name)
                self._list_files_at_revision(obj, new_path, results)
            else:
                raise NotImplementedError(
                    f"object at '{new_path}' of type '{entry.name}' not supported"
                )
        return results

    def list_files_at_revision(self, commit, path):
        """
        for the given commit string,
        return a list of all file paths that are
        descendents of the path string.
        """
        obj = self.repo.get(commit)
        root = self._get_object_at_path(obj, path)
        if root is None:
            raise GitError(
                self.encapsulating_repo,
                message=f"fatal: Path '{path}' does not exist in '{commit}'",
            )
        return self._list_files_at_revision(root)