import matplotlib.pyplot as plt
import matplotlib.patches as patches
from PIL import Image

def create_diagram(rectangles, security, room_size, filename):

    fig,ax = plt.subplots(1, figsize=(10,10))
    room = plt.Rectangle((0, 0), room_size[0], room_size[1], linewidth=1, edgecolor='g', facecolor='none')
    ax.add_patch(room)

    for box in rectangles:
        width = box.width
        height = box.height
        x = box.x
        y = box.y
        x_table = x + security/2
        w_table = width - security
        y_table = y + security/2
        h_table = height - security

        if x == 0:
            x += security/2
            width -= security/2
        elif x==room_size[0]-width+security:
            width -= security/2
        if y == 0:
            y += security/2
            height -= security/2
        elif y==room_size[1]-height+security:
            height -= security/2

        x -= security/2
        y -= security/2
        x_table -= security/2
        y_table -= security/2

        sec = plt.Rectangle((x, y), width, height, linewidth=1, edgecolor='r', facecolor='none', alpha=0.2)
        ax.add_patch(sec)

        table = plt.Rectangle((x_table, y_table), w_table, h_table,
            linewidth=2, edgecolor='b', facecolor='none')
        ax.add_patch(table)
        w = round(box.width-security, 2)
        h = round(box.height-security, 2)
        plt.text(x + width/3, y + height/2, f'{w}, {h}')

    ax.scatter([1], [1],color="w")
    plt.savefig(str(filename)+'.png')


import itertools as iter

def solution(num_buns, num_required):
    """
    total keys = num_buns choose num_required-1

    no num_required-1 # of bunnies can have the ability
    to unlock the doors.
    this can lead us to how many times each key is held.
    looking at the examples, (5, 3) each key is held 3 times
    (3, 1) each key is held 3 times
    (2, 2) each key is held once
    (3, 2) each key is held twice
    (4, 4) each key is held once
    is it num_buns - num_required + 1?

    so each key in range(total_keys) needs to be held
    num_buns - num_required + 1 times.
    So we need to assign each key to num_required bunnies.

    this means each bunny holds (total_keys*dupe_keys)/num_buns keys

    for each of range(total_keys)
    choose dupe_keys num_bunnies to possess that key.
    are there always total_keys ways to select groups of dupe_keys bunnies?
    n = num_buns
    k = num_require
    j = n - k + 1 = dupe_keys
    n!/(k-1)!(n-(k-1))! = total_keys = C(n, k - 1)
    C(n, n-(k-1) = C(n, n - k + 1) = C(n, k - 1)

    yes, since we know C(n, k) = C(n, n-k)
    so it follows C(n, k - 1) = C(n, n - (k - 1)) = C(n, n - k + 1) = C(n, j)
    """

    dupe_keys = num_buns - num_required + 1
    sol = [[] for _ in range(num_buns)]

    # solve easy cases
    if num_buns == num_required:
        for i in range(num_required):
            sol[i] = [i]
        return sol
    if num_required == 1:
        for i in range(num_buns):
            sol[i] = [0]
        return sol
    if num_required == 0:
        return sol

    i = 0
    for l in iter.combinations(range(num_buns), dupe_keys):
        for j in l:
            sol[j].append(i)
        i += 1
    return sol

solution(5, 0)
solution(4, 1)
solution(4, 4)
solution(5, 3)


import numpy as np
import math, sys
import cv2
from PIL import Image

def test_ransac():
    im1 = cv2.imread('part2-images/book1.jpg', cv2.IMREAD_COLOR)
    im1 = cv2.cvtColor(im1, cv2.COLOR_BGR2RGB)
    im2 = cv2.imread('part2-images/book2.jpg', cv2.IMREAD_COLOR)
    im2 = cv2.cvtColor(im2, cv2.COLOR_BGR2RGB)

    image1_coords = np.array([[318, 256], [534, 372], [316,670], [73,473]])
    image2_coords = np.array([[141, 131], [480, 159], [493,630], [64,601]])

    post, transform_mat = projective(im2, image1_coords, image2_coords)

    h, w, c = im1.shape

    sample_x = np.random.choice(w, size=10, replace=False).astype(np.float16)
    sample_y = np.random.choice(h, size=10, replace=False).astype(np.float16)

    sigma = 1
    sample_y += np.random.normal(loc=0, scale=sigma, size=sample_y.shape)

    image1_coords = np.array([[x, y] for x, y in zip(sample_x, sample_y)])
    a = np.vstack((image1_coords.transpose(), np.ones(image1_coords.shape[0])))
    b = np.dot(transform_mat, a)
    image2_coords = remove_homogeneous(b).transpose()

    best_transform = ransac(image1_coords, image2_coords, 10, 9e-13)

    post = inv_transform(im2, best_transform)
    blended = blend_images(post, im1)
    blended_img = Image.fromarray(blended)
    # blended_img.show()
    print(f'Comparing the real and estimated transformation matrices')
    print(f'Sum Squared Error: {np.mean((best_transform - transform_mat)**2)}')
    print(f'SSE / sum_all_vals: {np.mean((best_transform - transform_mat)**2) / np.mean(best_transform + transform_mat)}')

def ransac(image1_coords, image2_coords, n, threshhold):
    if image1_coords.shape[0] == 4:
        return transform_mat(image1_coords, image2_coords)
    elif image1_coords.shape[0] < 4:
        print('Not enough points to compute transform')
        return
    max_inliers = 0
    best_transform = np.identity(3)
    for _ in range(n):
        # Takes sample to calculate transformation hypothesis
        row_idx = np.random.choice(image1_coords.shape[0], size=4, replace=False)
        sample1 = image1_coords[row_idx,:]
        sample2 = image2_coords[row_idx,:]

        # Rows not in samples to count inliers
        sample1_c = np.array([row for row in image1_coords if row not in sample1])
        sample2_c = np.array([row for row in image2_coords if row not in sample2])

        try:
            mat = transform_mat(sample1, sample2)
        except np.linalg.LinAlgError:
            continue

        # Apply transformation
        a = np.vstack((sample1_c.transpose(), np.ones(sample1_c.shape[0])))
        b = np.dot(mat, a)
        points = remove_homogeneous(b).transpose()

        # Count inliers
        inliers = 0
        for p1, p2 in zip(sample2_c, points):
            if cv2.norm(p1, p2, cv2.NORM_L2) < threshhold:
                inliers += 1

        if inliers > max_inliers:
            max_inliers = inliers
            best_transform = mat

    return best_transform

def blend_images(img1_arr, img2_arr):
    h1, w1, _ = img1_arr.shape
    h2, w2, _ = img2_arr.shape

    h, w = max(h1, h2), max(w1, w2)
    if h > 5000 or w > 5000:
        sys.exit(f'Image dims ({h, w, 3}) too large, exiting')
    res = np.zeros((h, w, 3))
    res.fill(127)

    for i, row in enumerate(img1_arr):
        for j, row in enumerate(row):
            res[i,j] = img1_arr[i,j]

    for i, row in enumerate(img2_arr):
        for j, row in enumerate(row):
            res[i,j] = (res[i,j] + img2_arr[i,j]) / 2

    return res.astype(np.uint8)

def translation(image_arr, image1_coords, image2_coords):
    mat = np.identity(3)
    mat[0,2] = image2_coords[0,0] - image1_coords[0,0] #T_x
    mat[1,2] = image2_coords[0,1] - image1_coords[0,1] #T_y

    homg_points = homogenize(image_arr)
    homg_points = np.dot(mat, homg_points)
    return reconstruct_2D(homg_points, image_arr)

def similarity(image_arr, image1_coords, image2_coords):
    im1_p2_rel = np.subtract(image1_coords[1,:], image1_coords[0,:])
    im2_p2_rel = np.subtract(image2_coords[1,:], image2_coords[0,:])

    ang1 = np.arctan2(im1_p2_rel[1], im1_p2_rel[0])
    ang2 = np.arctan2(im2_p2_rel[1], im2_p2_rel[0])

    theta = ang1 - ang2
    s, c = np.sin(theta), np.cos(theta)
    rot = np.array([[c, s], [-s, c]])

    p2 = np.dot(rot, image1_coords.transpose()).transpose()
    translation = np.mean(np.subtract(image2_coords, p2), axis=0)

    transform_mat = np.identity(3)
    transform_mat[0,2] = translation[0]
    transform_mat[1,2] = translation[1]
    transform_mat[:2,:2] = rot

    return inv_transform(image_arr, transform_mat)

def affine(image_arr, image1_coords, image2_coords):
    X = np.zeros((0,6))

    for point in image1_coords:
        a = np.append(point, 1)
        x = np.zeros((2, 6))
        x[0, :3] = a
        x[1, 3:] = a
        X = np.vstack((X, x))

    x_prime = image2_coords.reshape((6,1))

    transform_mat = np.linalg.solve(X, x_prime)
    transform_mat = np.vstack((transform_mat.reshape(2,3), [0, 0, 1]))

    return inv_transform(image_arr, transform_mat)

def projective(image_arr, image1_coords, image2_coords):
    # Find the transformation matrix
    image1_homg = np.append(image1_coords.transpose(), np.ones((1, 4)), axis=0)
    image2_homg = np.append(image2_coords.transpose(), np.ones((1, 4)), axis=0)

    a = np.linalg.solve(image1_homg[:,:3], image1_homg[:,3:])
    A = image1_homg[:,:3] * a.transpose()

    b = np.linalg.solve(image2_homg[:,:3], image2_homg[:,3:])
    B = image2_homg[:,:3] * b.transpose()

    # Transforms image1 to image2
    mat = np.dot(B, np.linalg.inv(A))
    # Transform image2 to image1
    mat_inv = np.linalg.inv(mat)

    return inv_transform(image_arr, mat_inv), mat_inv

# python a2.py part2 4 book1 book2 output 318,256 141,131 534,372 480,159 316,670 493,630 73,473 64,601
def inv_transform(image_arr, transform_mat):
    h, w, c = image_arr.shape
    corners = np.array([[0,0,1], [w, 0, 1], [0, h, 1], [w, h, 1]]).transpose()
    corners_transform = np.dot(transform_mat, corners)
    transform_dims = np.amax(corners_transform, axis=1)
    new_h, new_w = int(transform_dims[1]) + 1, int(transform_dims[0]) + 1
    if new_h > 5000 or new_w > 5000:
        sys.exit(f'Image dims ({new_h, new_w, 3}) too large, exiting')

    new_image = np.ones((new_h, new_w, 3), dtype=np.uint8) * 127
    new_image_homg = homogenize(new_image)

    mat_inv = np.linalg.inv(transform_mat)
    inv_transform = np.dot(mat_inv, new_image_homg)
    inv_transform = remove_homogeneous(inv_transform)

    pre_points = [(point[1], point[0]) for point in inv_transform.transpose()]
    post_points = [(int(point[1]), int(point[0])) for point in new_image_homg.transpose()]

    for pre_point, post_point in zip(pre_points, post_points):
        pre_h, pre_w = pre_point

        if within_bound(pre_h, pre_w, h - 1, w - 1):
            # Bilinear interpolation
            # Variables named like wheels on a car
            fl = image_arr[(math.floor(pre_h), math.floor(pre_w))] # (0, 0)
            fr = image_arr[(math.floor(pre_h), math.ceil(pre_w))] # (0, 1)
            rl = image_arr[(math.ceil(pre_h), math.floor(pre_w))] # (1, 0)
            rr = image_arr[(math.ceil(pre_h), math.ceil(pre_w))] # (1, 1)

            # Ugly way of getting the decimals of a float
            decimal_h, decimal_w = (pre_h - math.floor(pre_h), pre_w - math.floor(pre_w))

            color = (1 - decimal_h) * (1 - decimal_w) * fl + decimal_w * (1 - decimal_h) * fr + (1 - decimal_w) * decimal_h * rl + decimal_h * decimal_w * rr
            new_image[post_point] = color

    return new_image

def transform_mat(image1_coords, image2_coords):
    # Find the transformation matrix
    image1_homg = np.append(image1_coords.transpose(), np.ones((1, 4)), axis=0)
    image2_homg = np.append(image2_coords.transpose(), np.ones((1, 4)), axis=0)

    a = np.linalg.solve(image1_homg[:,:3], image1_homg[:,3:])
    A = image1_homg[:,:3] * a.transpose()

    b = np.linalg.solve(image2_homg[:,:3], image2_homg[:,3:])
    B = image2_homg[:,:3] * b.transpose()

    # Transforms image1 to image2
    mat = np.dot(B, np.linalg.inv(A))

    return mat

def transform(image_arr, transform_mat):
    homg_points = homogenize(image_arr)
    transform_points = np.dot(transform_mat, homg_points)

    return reconstruct_2D(transform_points, image_arr)

def homogenize(image_arr):
    h, w = image_arr.shape[:2]
    y, x = np.indices((h, w), dtype=int)
    homg_points = np.stack((x.ravel(), y.ravel(), np.ones(y.size)))

    return homg_points

def reconstruct_2D(homg_points, image_arr):
    # remove homogeneous coordinate
    homg_points = remove_homogeneous(homg_points)

    # moves upper-left corner to (0, 0)
    mins = np.amin(homg_points, axis=1)
    min_y, min_x = mins[1], mins[0]
    if min_x < 0 or min_y < 0:
        homg_points -= np.array([[min_x], [min_y]])

    #reconstruct original image
    dims = np.amax(homg_points, axis=1)
    w, h = int(dims[0]) + 1, int(dims[1]) + 1
    new_image = np.ones((h, w, 3), dtype=np.uint8) * 127

    pre_points = [(int(point[1]), int(point[0])) for point in homogenize(image_arr).transpose()]
    post_points = [(int(point[1]), int(point[0])) for point in homg_points.transpose()]

    for pre_point, post_point in zip(pre_points, post_points):
        new_image[post_point] = image_arr[pre_point]

    return new_image

def within_bound(y, x, h, w):
    return y >= 0 and y < h and x >= 0 and x < w

# divides the first 2 rows by the 3rd
def remove_homogeneous(homg_points):
    return np.array([homg_points[0,] / homg_points[2,], homg_points[1,] / homg_points[2,]])

#test_ransac()

C457 Computer Vision SP22/Assignment 2/a2-group9/transforms.py


"""Script and utilities for simulating with Verilator."""

import itertools
import logging
import os
from pathlib import Path
import random
import sys
from typing import List, Optional, Tuple, Union
import subprocess

MAX_NUM_TESTS = 2**18

def simulate_with_verilator(
    test_module_name: str,
    ground_truth_module_name: str,
    obj_dirpath: Union[str, Path],
    verilog_filepaths: List[Union[str, Path]],
    module_inputs: List[Tuple[str, int]],
    initiation_interval: int,
    testbench_sv_filepath: Union[str, Path],
    testbench_exe_filepath: Union[str, Path],
    testbench_inputs_filepath: Union[str, Path],
    testbench_stdout_log_filepath: Union[str, Path],
    testbench_stderr_log_filepath: Union[str, Path],
    makefile_filepath: Union[str, Path],
    module_outputs: List[Tuple[str, int]],
    clock_name: Optional[str] = None,
    include_dirs: List[Union[str, Path]] = [],
    extra_args: List[str] = [],
    max_num_tests=MAX_NUM_TESTS,
    ignore_missing_test_module_file: bool = False,
    expect_all_zero_outputs: bool = False,
):
    """

    Args:
      obj_dirpah: Path to obj_dir Verilator output directory.
      verilog_filepaths: Verilog files to compile with Verilator. These files
        should at least contain the Verilog code for the test and ground truth
        modules.
      module_inputs: List of tuples of the form (input_name, input_width). We
        assume inputs are the same between the two modules.
      testbench_{c,exe}_output_filepath: Filepath to write the testbench
        code/executable to.
      testbench_log_filepath: Filepath to write the testbench output to.
      ignore_missing_test_module_file: If True, we will not raise an exception
        if the test module file does not exist. This is our current hacky solution
        to handling the fact that Lakeroad doesn't always produce output.
      expect_all_zero_outputs: If True, we will expect that all outputs are
        always 0 on all inputs. This should almost always be False.
    """

    if ignore_missing_test_module_file and not all(
        [Path(path).exists() for path in verilog_filepaths]
    ):
        missing = list(filter(lambda path: not Path(path).exists(), verilog_filepaths))[0]
        logging.warning(
            f"Required Verilog file {missing} does not exist. " "Skipping simulation."
        )
        return

    obj_dirpath = Path(obj_dirpath)
    obj_dirpath.mkdir(parents=True, exist_ok=True)
    testbench_sv_filepath = Path(testbench_sv_filepath)
    testbench_sv_filepath.parent.mkdir(parents=True, exist_ok=True)
    testbench_exe_filepath = Path(testbench_exe_filepath).resolve()
    testbench_exe_filepath.parent.mkdir(parents=True, exist_ok=True)
    testbench_inputs_filepath = Path(testbench_inputs_filepath)
    testbench_inputs_filepath.parent.mkdir(parents=True, exist_ok=True)
    testbench_stdout_log_filepath = Path(testbench_stdout_log_filepath)
    testbench_stdout_log_filepath.parent.mkdir(parents=True, exist_ok=True)
    testbench_stderr_log_filepath = Path(testbench_stderr_log_filepath)
    testbench_stderr_log_filepath.parent.mkdir(parents=True, exist_ok=True)
    makefile_filepath = Path(makefile_filepath)
    makefile_filepath.parent.mkdir(parents=True, exist_ok=True)

    # Instantiate Makefile template for our code.
    if "LAKEROAD_DIR" not in os.environ:
        raise Exception(
            "LAKEROAD_DIR environment variable must be set to the "
            "directory where Lakeroad is located."
        )
    makefile_filepath = Path(makefile_filepath)
    makefile_filepath.write_text(
        (Path(os.environ["LAKEROAD_DIR"]) / "misc" / "verilator.mk.template")
        .read_text()
        .format(
            testbench_exe_filepath=testbench_exe_filepath,
            testbench_inputs_filepath=testbench_inputs_filepath,
            obj_dirpath=obj_dirpath,
            extra_verilator_args=" ".join(
                [str(path) for path in verilog_filepaths]
                + [f"-I{dir}" for dir in include_dirs]
                + extra_args
            ),
            testbench_filepath=testbench_sv_filepath,
        )
    )

    # Instantiate testbench template for our code.
    testbench_template_source = (
        Path(os.environ["LAKEROAD_DIR"]) / "misc" / "verilator_testbench.sv.template"
    ).read_text()
    testbench_source = testbench_template_source.format(
        max_input_bitwidth=max([bw for _, bw in module_inputs]),
        test_module_name=test_module_name,
        ground_truth_module_name=ground_truth_module_name,
        test_module_port_list=",".join(
            [f".{name}({name})" for name, _ in module_inputs]
            + [f".{name}({name}_test)" for name, _ in module_outputs]
        )
        + (f",.{clock_name}({clock_name})" if clock_name else ""),
        ground_truth_module_port_list=",".join(
            [f".{name}({name})" for name, _ in module_inputs]
            + [f".{name}({name}_ground_truth)" for name, _ in module_outputs]
        )
        + (f",.{clock_name}({clock_name})" if clock_name else ""),
        input_output_declarations=" ".join(
            # Modules share inputs.
            [f"logic [{bw-1}:0] {name};" for (name, bw) in module_inputs]
            # Make a different output for each module.
            + [f"logic [{bw-1}:0] {name}_test;" for (name, bw) in module_outputs]
            + [
                f"logic [{bw-1}:0] {name}_ground_truth;"
                for (name, bw) in module_outputs
            ]
        )
        + (f"logic {clock_name};" if clock_name else ""),
        display_inputs=f"$display(\"Inputs: {', '.join([f'{name}=%d' for name, _ in module_inputs])}\", {', '.join([name for name, _ in module_inputs])});",
        display_outputs=f"$display(\"Expected outputs: {', '.join([f'{name}_ground_truth=%d' for name, _ in module_outputs])}\", {', '.join([f'{name}_ground_truth' for name, _ in module_outputs])});"
        + f"$display(\"  Actual outputs: {', '.join([f'{name}_test        =%d' for name, _ in module_outputs])}\", {', '.join([f'{name}_test' for name, _ in module_outputs])});",
        set_inputs=" ".join(
            f"{name}=inputs[{i}][{bw-1}:0];"
            for (i, (name, bw)) in enumerate(module_inputs)
        ),
        clear_clock=f"{clock_name}=1'b0;" if clock_name else "",
        set_clock=f"{clock_name}=1'b1;" if clock_name else "",
        check_outputs="("
        + " && ".join(
            [f"({name}_ground_truth=={name}_test)" for name, _ in module_outputs]
        )
        + ")",
        initiation_interval=initiation_interval,
        randomize_inputs=" ".join(
            f"inputs[{i}]=$urandom();" for i in range(len(module_inputs))
        ),
        outputs_reduced_by_or=f"({'|'.join(f'(|{name}_test)' for name, _ in module_outputs)})",
        expect_all_zero_outputs="1'b1" if expect_all_zero_outputs else "1'b0",
    )
    Path(testbench_sv_filepath).write_text(testbench_source)

    # Generate the input to the testbench.
    with testbench_inputs_filepath.open("w") as f:
        # We can expose this as an argument. You can use this to tune how long
        # the tests take, at the cost of test coverage.
        if 2 ** (sum([width for _, width in module_inputs])) > max_num_tests:
            # logging.warning(
            #     "Exhaustive testing space is too large, doing random testing."
            # )

            # Generate a random subset of the inputs.
            def generate_one():
                return [random.randint(0, 2**width - 1) for _, width in module_inputs]

            all_inputs = [generate_one() for _ in range(max_num_tests)]
        else:
            # Do exhaustive testing.
            all_inputs = list(
                itertools.product(*[range(2**width) for _, width in module_inputs])
            )
        print(f"{len(module_inputs)} {len(all_inputs)}", file=f)
        for one_set_of_inputs in all_inputs:
            print(" ".join([str(hex(x)) for x in one_set_of_inputs]), file=f)

    # --environment-overrides is a brute-force way to allow users to use CXX=...
    # to override the C++ compiler with an environment variable. Overriding
    # doesn't normally work due to the issues brought up here:
    # https://github.com/verilator/verilator/issues/4549
    proc = subprocess.run(
        ["make", "--environment-overrides", "--always-make", "-f", makefile_filepath], capture_output=True
    )
    Path(testbench_stdout_log_filepath).write_bytes(proc.stdout)
    Path(testbench_stderr_log_filepath).write_bytes(proc.stderr)
    if proc.returncode != 0:
        print(proc.stderr.decode("utf-8"), file=sys.stderr)

    # Error if failed.
    proc.check_returncode()

if __name__ == "__main__":
    import argparse
    import tempfile

    parser = argparse.ArgumentParser()

    parser.add_argument(
        "--obj_dirpath",
        type=Path,
        help="Path where we will place the obj_dir folder produced by Verilator.",
        default=False,
    )
    parser.add_argument(
        "--verilog_filepath",
        type=Path,
        help=(
            "Filepath of Verilog file to compile with Verilator. At the very"
            " least, you should use this argument to specify the filepaths to"
            " the modules you're testing and the ground truth module."
        ),
        required=True,
        default=[],
        action="append",
    )
    parser.add_argument(
        "--test_module_name",
        type=str,
        help="Name of the module we're testing.",
        required=True,
    )
    parser.add_argument(
        "--ground_truth_module_name",
        type=str,
        help="Name of the ground truth module we're testing against.",
        required=True,
    )
    parser.add_argument(
        "--input_signal",
        type=str,
        help="Data input to the module we're testing, in the form <name>:<bitwidth>, e.g. a:16.",
        action="append",
        default=[],
    )
    parser.add_argument(
        "--clock_name",
        type=str,
        help="Name of the clock input to the module we're testing.",
        default=None,
    )
    parser.add_argument(
        "--initiation_interval",
        type=int,
        help="Initiation interval of the module we're testing.",
        default=0,
    )
    parser.add_argument(
        "--testbench_sv_filepath",
        type=Path,
        help="Filepath to write the testbench SystemVerilog code to.",
        # Note that mkstemp here will keep the file open, and thus not writeable
        # (e.g. when our Makefile tries to write the executable after
        # compilation.) So we use NamedTemporaryFile, get the name, and then
        # immediately drop the file so that the file gets deleted.
        default=tempfile.NamedTemporaryFile(suffix=".sv").name,
    )
    parser.add_argument(
        "--testbench_exe_filepath",
        type=Path,
        help="Filepath to write the testbench executable to.",
        default=tempfile.NamedTemporaryFile(suffix=".out").name,
    )
    parser.add_argument(
        "--testbench_inputs_filepath",
        type=Path,
        help="Filepath to write the testbench inputs to.",
        default=tempfile.NamedTemporaryFile(suffix=".txt").name,
    )
    parser.add_argument(
        "--testbench_stdout_log_filepath",
        type=Path,
        help="Filepath to write the testbench stdout to.",
        default=tempfile.NamedTemporaryFile(suffix=".stdout.log").name,
    )
    parser.add_argument(
        "--testbench_stderr_log_filepath",
        type=Path,
        help="Filepath to write the testbench stderr to.",
        default=tempfile.NamedTemporaryFile(suffix=".stderr.log").name,
    )
    parser.add_argument(
        "--makefile_filepath",
        type=Path,
        help="Filepath to write the makefile to.",
        default=tempfile.NamedTemporaryFile(suffix=".mk").name,
    )
    parser.add_argument(
        "--output_signal",
        type=str,
        help="Module output, in the form <name>:<bw>.",
        required=True,
        action="append",
        default=[],
    )
    parser.add_argument(
        "--verilator_include_dir",
        type=Path,
        help="Directories to pass to Verilator as include directories.",
        action="append",
        default=[],
    )
    parser.add_argument(
        "--verilator_extra_arg",
        type=str,
        help="Extra argument to pass to Verilator.",
        action="append",
        default=[],
    )
    parser.add_argument(
        "--max_num_tests",
        type=int,
        help="Maximum number of tests to run. If this number is greater than the space of all points, testing will be non-exhaustive.",
        default=MAX_NUM_TESTS,
    )
    parser.add_argument(
        "--expect_all_zero_outputs",
        action=argparse.BooleanOptionalAction,
        default=False,
        help="Whether to expect that all outputs are always 0 on all inputs.",
    )

    args = parser.parse_args()

    # Handle the case where obj_dirpath is not specified.
    if args.obj_dirpath is False:
        tmp_dir = tempfile.TemporaryDirectory()
        args.obj_dirpath = tmp_dir.name

    # Parse something like <signal_name>:<bitwidth> into a tuple.
    parse_signal_str = lambda x: (str(x.split(":")[0]), int(x.split(":")[1]))

    simulate_with_verilator(
        test_module_name=args.test_module_name,
        ground_truth_module_name=args.ground_truth_module_name,
        obj_dirpath=args.obj_dirpath,
        verilog_filepaths=args.verilog_filepath,
        module_inputs=[parse_signal_str(i) for i in args.input_signal],
        clock_name=args.clock_name,
        initiation_interval=args.initiation_interval,
        testbench_sv_filepath=args.testbench_sv_filepath,
        testbench_exe_filepath=args.testbench_exe_filepath,
        testbench_inputs_filepath=args.testbench_inputs_filepath,
        testbench_stdout_log_filepath=args.testbench_stdout_log_filepath,
        testbench_stderr_log_filepath=args.testbench_stderr_log_filepath,
        makefile_filepath=args.makefile_filepath,
        module_outputs=[parse_signal_str(i) for i in args.output_signal],
        extra_args=args.verilator_extra_arg,
        max_num_tests=args.max_num_tests,
        expect_all_zero_outputs=args.expect_all_zero_outputs,
        include_dirs=args.verilator_include_dir,
    )


import json

from telebot.types import InlineKeyboardButton as TelebotInlineKeyboardButton, ReplyKeyboardMarkup, KeyboardButton
from telebot.types import InlineKeyboardMarkup

from telegram_bot.crypt import encrypt

last_module = None
last_button = 0
button_targets = {}
button_targets_keys = {}

def register_button_function(fn):
    global last_button, button_targets, last_module
    if last_module and fn.__module__ != last_module:
        last_button += 100
    if fn.__module__ != last_module:
        last_module = fn.__module__
    last_button += 1
    button_targets[last_button] = fn
    button_targets_keys[fn] = last_button
    return fn

def get_button_function_key(fn):
    return button_targets_keys[fn]

def get_button_function(id):
    return button_targets[id]

class InlineKeyboardButton(TelebotInlineKeyboardButton):
    def __init__(self, main, text, url=None, callback_data=None, switch_inline_query=None, json_data=None,
                 callback=None, callback_kwargs=None):
        self.main = main
        callback_data = callback_data or self.generate_data(json_data) or self.generate_callback(callback,
                                                                                callback_kwargs)
        super(InlineKeyboardButton, self).__init__(text, url=url, callback_data=callback_data,
                                                   switch_inline_query=switch_inline_query)

    def generate_data(self, data):
        if data is None:
            return
        key = self.main.config['api_token'].split(':')[1][:16].encode('utf-8')
        data = json.dumps(data)
        encoded = encrypt(data, key)
        return encoded

    def generate_callback(self, fn, callback_kwargs):
        if fn is None:
            return
        return self.generate_data({'fn': get_button_function_key(fn), 'kw': callback_kwargs})

class InlineKeyboard(InlineKeyboardMarkup):
    def __init__(self, main, row_width=3):
        self.main = main
        super(InlineKeyboard, self).__init__(row_width=row_width)

    def add_button(self, text, url=None, callback_data=None, switch_inline_query=None, json_data=None,
                   callback=None, callback_kwargs=None):
        self.add(InlineKeyboardButton(self.main, text, url=url, callback_data=callback_data,
                                      switch_inline_query=switch_inline_query, json_data=json_data, callback=callback,
                                      callback_kwargs=callback_kwargs))

class ReplyKeyboard(ReplyKeyboardMarkup):
    def add_button(self, text, request_contact=None, request_location=None):
        self.add(KeyboardButton(text, request_contact, request_location))


import logging
import os
from typing import Iterator

import spotipy, re
from progress.bar import Bar
from spotipy import SpotifyClientCredentials

from src.data.downloader import DataDownloader
from src.util import read_csv

SPOTIFY_MAX_TRACKS = 100
PARENS_REGEX = re.compile(r"\(.*\)")

def find_best_match(track: dict, search_results: list[dict]):
    best_match = search_results[0]
    best_score = 0.0

    title = track['title'].lower().strip()
    title_bare = PARENS_REGEX.sub("", title).strip()
    album = str(track['album']).lower().strip() if track['album'] is None else None

    heuristics = [
        (lambda i: title == i['title'], 1),
        (lambda i: (title + " ") in i['title'], .5),
        (lambda i: title_bare == i['title'], .3),
        (lambda i: (title_bare + " ") in i['title'], .3),
        (lambda i: album is not None and album == i['album'], 1),
        (lambda i: album is not None and (album + " ") in i['album'], .5)
    ]

    for result in search_results:
        candidate = {
            'title': result['name'].lower().strip(),
            'album': result['album']['name'].lower().strip()
        }
        score = sum([heuristic[1] for heuristic in heuristics if heuristic[0](candidate)])
        if score > best_score:
            best_score = score
            best_match = result

    return best_match

class FeatureDownloader(DataDownloader):
    def __init__(self, output_file: str, tracks_file: str):
        super().__init__(output_file)

        tracks = read_csv(tracks_file, strict=True)
        features = read_csv(self.output_file, strict=False)

        existing_ids = {feature['tt_id'] for feature in features}
        new_tracks = [track for track in tracks if track['id'] not in existing_ids]

        logging.info(f"{len(new_tracks)} new tracks found since last run")
        self.new_tracks = new_tracks

        credentials = SpotifyClientCredentials(
            client_id=os.getenv('SPOTIFY_CLIENT_ID'),
            client_secret=os.getenv('SPOTIFY_CLIENT_SECRET')
        )
        self.api = spotipy.Spotify(auth_manager=credentials)

    def download(self) -> Iterator[dict]:
        batch = []

        tracks = self.new_tracks

        bar = Bar('Downloading track features...', max=len(tracks))
        for i, track in enumerate(tracks):
            bar.next()

            search_results = self.api.search(q=track['title'], type='track', limit=50)

            if search_results['tracks']['total'] == 0:
                continue

            item = find_best_match(track, search_results['tracks']['items'])

            if item is None:
                continue

            batch.append({
                'id': item['id'],
                'tt_id': track['id'],  # Keep ID for cross-reference
                'title': item['name'],
                'album': item['album']['name'],
                'artist': ", ".join([artist['name'] for artist in item['artists']]),
                'popularity': item['popularity']
            })

            # Download audio features per batch or when reaching the last track, for efficiency
            if len(batch) % SPOTIFY_MAX_TRACKS == 0 or i == len(tracks) - 1:
                ids = [item['id'] for item in batch]
                feature_results = self.api.audio_features(ids)
                for idx, features in enumerate(feature_results):
                    if features is None:
                        continue

                    item = batch[idx]
                    yield {**item, **features}

                batch = []


import yaml
import tarfile
from ansible.module_utils.basic import *
from functools import reduce
import operator

DOCUMENTATION = '''
---
module: get_value_from_yaml_in_tarball
description:
    - Return value from a YAML file that is in a tarball
options:
    tarball:
        description:
          - path to tarball that contains the target yaml file.
        required: true
    target_file:
        description:
          - Path of target YAML file
        required: true
    keys:
        description:
          - List of key(s) to find value in file. It can take multiple values for nested keys.
            For example: ["foreman_proxy", "dhcp"] or ["satellite_version"]
        required: true
    allow_null:
        description:
        - Allows the parameter to be null, defaulting to an empty string. Defaults to false.
        required: false
'''

EXAMPLES = '''
- name: Get puppet user from Satellite answers
  get_value_from_yaml_in_tarball:
    tarball: "/path/to/config_files.tar.gz"
    target_file: "etc/foreman-installer/scenarios.d/satellite-answers.yaml"
    keys: ["puppet", "user"]
  register: puppet_user

  then you can use puppet_user.value
'''

BACKUP_CONFIG = "config_files.tar.gz"

# Takes keys in the format ['foo', 'bar']
# when the dict looks like
# { "foo": { "bar": "hi" }}
# will return None if it a key doesn't exist
def get_value(data, keys):
    try:
        return reduce(operator.getitem, keys, data)
    except KeyError:
        return None

def get_value_from_tarball(params):
    config_tar = tarfile.open(params["tarball"])
    answers_file = config_tar.extractfile(params["target_file"])
    allow_null = params.get("allow_null", False)
    answers = yaml.load(answers_file.read())
    found_value = get_value(answers, params['keys'])
    # The value itself can be false, so only check for NoneType
    if found_value is not None:
        return True, dict(msg="Value found!", changed=False, value=found_value)
    elif allow_null:
        return True, dict(msg="Defaulting to \"\"", changed=False, value="")
    else:
        msg = "Keys {} were not found in {}!".format(
            params["keys"], params["target_file"])
        return False, dict(msg=msg)

def main():
    fields = {
        "tarball": {"required": True, "type": "str"},
        "target_file": {"required": True, "type": "str"},
        "keys": {"required": True, "type": "list"},
        "allow_null": {"required": False, "type": "bool", "default": False}
    }
    module = AnsibleModule(argument_spec=fields)
    success, result = get_value_from_tarball(module.params)
    if success:
        module.exit_json(**result)
    else:
        module.fail_json(**result)

if __name__ == '__main__':
    main()


# loosely inspired by https://github.com/chengyangfu/pytorch-vgg-cifar10
import math
import torch.nn as nn

from layers import RealOpu, SimulatedOpu, Sign, Identity
from tinydfa import DFA, DFALayer

class CifarVGG16(nn.Module):

    def __init__(self, opu, binary_layer, opu_features, features, opu_input, sign_back, real_opu, device, dataset):
        super(CifarVGG16, self).__init__()
        self.features = features
        if dataset == 'cifar10':
            self.number_classes = 10
        if dataset == 'cifar100':
            self.number_classes = 100

        if binary_layer:
            if sign_back:
                print(f'- Binary layer = {binary_layer} but sign_back = {sign_back}--> attack method = FA!')
                self.dfa1 = Identity()
                self.dfa = Identity()
            else:
                self.training_method = 'DFA'
                print(f'- Binary layer = {binary_layer} --> training method = DFA!')
                self.dfa1 = DFALayer()
                self.dfa = DFA([self.dfa1], no_training=(self.training_method == 'SHALLOW'))
        else:
            if opu:
                print(f'- Binary layer = {binary_layer}, opu = {opu} --> training method = FA')
            else:
                print(f'- Binary layer = {binary_layer}, opu = {opu} --> training method = BP')
            self.dfa1 = nn.Dropout()
            self.dfa = Identity()

        if opu:
            print(f'- opu_input = {opu_input}, opu_output = {opu_features}')
            if real_opu:
                print('- VGG with real OPU')
                print(opu_input, opu_features)
                second_classifier_layer = RealOpu(in_features=opu_input, out_features=opu_features, device=device)
            else:
                print('- VGG with simulated OPU')
                second_classifier_layer = SimulatedOpu(in_features=opu_input, out_features=opu_features)

        else:
            print('- VGG without OPU')
            second_classifier_layer = nn.Linear(opu_input, opu_features)

        self.classifier = nn.Sequential(
            nn.Dropout(),
            nn.Linear(512, opu_input),
            nn.ReLU(True),
            self.dfa1,
            Sign(binary_layer, sign_back=sign_back),
            second_classifier_layer,
            nn.ReLU(True),
            nn.Linear(opu_features, self.number_classes),
            self.dfa
        )
        # Initialize weights
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
                m.weight.data.normal_(0, math.sqrt(2. / n))
                m.bias.data.zero_()

    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), -1)
        x = self.classifier(x)
        return x

class AblationCifarVGG16(nn.Module):

    def __init__(self, opu, binary_layer, opu_features, features, opu_input, dataset, sign_back):
        super(AblationCifarVGG16, self).__init__()
        self.features = features
        print(f'OPU: {opu}, binary_layer: {binary_layer}, oo: {opu_features}, oi: {opu_input}, sign back: {sign_back}')

        if dataset == 'cifar10':
            self.number_classes = 10
        if dataset == 'cifar100':
            self.number_classes = 100

        if sign_back:
            self.dfa1 = Identity()
            self.dfa = Identity()
        else:
            self.training_method = 'DFA'
            self.dfa1 = DFALayer()
            self.dfa = DFA([self.dfa1], no_training=(self.training_method == 'SHALLOW'))

        if opu:
            second_classifier_layer = SimulatedOpu(in_features=opu_input, out_features=opu_features)
        else:
            second_classifier_layer = nn.Linear(opu_input, opu_features)

        self.classifier = nn.Sequential(
            nn.Dropout(),
            nn.Linear(512, opu_input),
            nn.ReLU(True),
            self.dfa1,
            Sign(binary_layer, sign_back=sign_back),
            second_classifier_layer,
            nn.ReLU(True),
            nn.Linear(opu_features, self.number_classes),
            self.dfa
        )
        # Initialize weights
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
                m.weight.data.normal_(0, math.sqrt(2. / n))
                m.bias.data.zero_()

    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), -1)
        x = self.classifier(x)
        return x

def make_layers(cfg):
    layers = []
    in_channels = 3
    for v in cfg:
        if v == 'M':
            layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
        else:
            conv2d = nn.Conv2d(in_channels, v, kernel_size=3, padding=1)
            layers += [conv2d, nn.BatchNorm2d(v), nn.ReLU(inplace=True)]
            in_channels = v
    return nn.Sequential(*layers)

cfg = [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M']

def cifar_vgg16(opu, binary_layer, opu_features, opu_input, sign_back, device, dataset, real_opu=False):
    return CifarVGG16(opu=opu, binary_layer=binary_layer, opu_features=opu_features, features=make_layers(cfg),
                      opu_input=opu_input, sign_back=sign_back, real_opu=real_opu, device=device, dataset=dataset)

def ablation_cifar_vgg16(opu, binary_layer, opu_features, opu_input, dataset, sign_back=False):
    return AblationCifarVGG16(opu=opu, binary_layer=binary_layer, opu_features=opu_features, features=make_layers(cfg),
                              opu_input=opu_input, dataset=dataset, sign_back=sign_back)


from PIL import Image
from pylab import *

import matplotlib.pyplot as plt
from matplotlib import animation

import numpy as np
from numpy import interp

from math import tau
from scipy.integrate import quad

def create_close_loop(image_name, level=[200]):
    # Prepare Plot
    fig, ax = plt.subplots(1, 2, figsize=(10, 5))
    ax[0].set_aspect('equal', 'datalim')
    ax[1].set_aspect('equal', 'datalim')
    ax[0].set_title('Before Centered')
    ax[1].set_title('After Centered')

    # read image to array, then get image border with contour
    im = array(Image.open(image_name).convert('L'))
    contour_plot = ax[0].contour(im, levels=level, colors='black', origin='image')

    # Get Contour Path and create lookup-table
    contour_path = contour_plot.collections[0].get_paths()[0]
    x_table, y_table = contour_path.vertices[:, 0], contour_path.vertices[:, 1]
    time_table = np.linspace(0, tau, len(x_table))

    # Simple method to center the image
    x_table = x_table - min(x_table)
    y_table = y_table - min(y_table)
    x_table = x_table - max(x_table) / 2
    y_table = y_table - max(y_table) / 2

    # Visualization
    ax[1].plot(x_table, y_table, 'k-')

    return time_table, x_table, y_table

def f(t, time_table, x_table, y_table):
    return interp(t, time_table, x_table) + 1j*interp(t, time_table, y_table)

def DFT(t, coef_list, order=5):
    kernel = np.array([np.exp(-n*1j*t) for n in range(-order, order+1)])
    series = np.sum( (coef_list[:,0]+1j*coef_list[:,1]) * kernel[:])
    return np.real(series), np.imag(series)

def coef_list(time_table, x_table, y_table, order=5):
    coef_list = []
    for n in range(-order, order+1):
        real_coef = quad(lambda t: np.real(f(t, time_table, x_table, y_table) * np.exp(-n*1j*t)), 0, tau, limit=100, full_output=1)[0]/tau
        imag_coef = quad(lambda t: np.imag(f(t, time_table, x_table, y_table) * np.exp(-n*1j*t)), 0, tau, limit=100, full_output=1)[0]/tau
        coef_list.append([real_coef, imag_coef])
    return np.array(coef_list)

def visualize(x_DFT, y_DFT, coef, order, space, fig_lim):
    fig, ax = plt.subplots()
    lim = max(fig_lim)
    ax.set_xlim([-lim, lim])
    ax.set_ylim([-lim, lim])
    ax.set_aspect('equal')

    # Initialize
    line = plt.plot([], [], 'k-', linewidth=2)[0]
    radius = [plt.plot([], [], 'r-', linewidth=0.5, marker='o', markersize=1)[0] for _ in range(2 * order + 1)]
    circles = [plt.plot([], [], 'r-', linewidth=0.5)[0] for _ in range(2 * order + 1)]

    def update_c(c, t):
        new_c = []
        for i, j in enumerate(range(-order, order + 1)):
            dtheta = -j * t
            ct, st = np.cos(dtheta), np.sin(dtheta)
            v = [ct * c[i][0] - st * c[i][1], st * c[i][0] + ct * c[i][1]]
            new_c.append(v)
        return np.array(new_c)

    def sort_velocity(order):
        idx = []
        for i in range(1,order+1):
            idx.extend([order+i, order-i])
        return idx

    def animate(i):
        # animate lines
        line.set_data(x_DFT[:i], y_DFT[:i])
        # animate circles
        r = [np.linalg.norm(coef[j]) for j in range(len(coef))]
        pos = coef[order]
        c = update_c(coef, i / len(space) * tau)
        idx = sort_velocity(order)
        for j, rad, circle in zip(idx,radius,circles):
            new_pos = pos + c[j]
            rad.set_data([pos[0], new_pos[0]], [pos[1], new_pos[1]])
            theta = np.linspace(0, tau, 50)
            x, y = r[j] * np.cos(theta) + pos[0], r[j] * np.sin(theta) + pos[1]
            circle.set_data(x, y)
            pos = new_pos

    # Animation
    ani = animation.FuncAnimation(fig, animate, frames=len(space), interval=5)
    return ani


#!../venv/bin/python
import os

import connexion

from qg_api.cfg import SWG_DIR
from qg_api.db import ScopedSession

app = connexion.App(__name__, specification_dir=SWG_DIR)
app.add_api('openapi.yaml', arguments={'title': 'qg_api'}, pythonic_params=True)
application = app.app

@app.app.teardown_appcontext
def cleanup(resp_or_exc):
    ScopedSession.remove()

@app.app.before_request
def br():
    print('!!!!!!!!!!!!!!!!!!!!!!!   ' + str(os.getpid()) + '   !!!!!!!!!!!!!!!!!!!!')

if __name__ == '__main__':
    app.run(port=2010)


import asyncio
import csv
import json
import pandas as pd
from playwright.async_api import async_playwright

async def scrape_company_page(url):
    async with async_playwright() as p:
        browser = await p.chromium.launch()
        page = await browser.new_page()
        await page.goto(url)
        company_name = await page.inner_text('h1[itemprop="name"]')
        company_rating = await page.inner_text('div[itemprop="ratingValue"]')
        company_reviews = await page.inner_text('span[itemprop="reviewCount"]')
        company_categories = await page.inner_text_all('a[itemprop="applicationCategory"]')
        await browser.close()
        return {
            "url": url,
            "name": company_name,
            "rating": company_rating,
            "reviews": company_reviews,
            "categories": company_categories
        }

async def scrape_company_pages(urls):
    tasks = []
    for url in urls:
        tasks.append(asyncio.ensure_future(scrape_company_page(url)))
    results = await asyncio.gather(*tasks)
    return results

def save_to_json(data, filename):
    with open(filename, "w") as f:
        json.dump(data, f)

def save_to_csv(data, filename):
    df = pd.DataFrame(data)
    df.to_csv(filename, index=False)

async def main():
    urls = []
    with open("urls.csv", "r") as f:
        reader = csv.reader(f)
        for row in reader:
            urls.extend(row)
    results = await scrape_company_pages(urls)
    save_to_json(results, "results.json")
    save_to_csv(results, "results.csv")

if __name__ == "__main__":
    asyncio.run(main())


from pyasn1.type import char
from pyasn1.type import namedtype
from pyasn1.type import univ

from pyasn1_modules import rfc5280

id_pkix = univ.ObjectIdentifier((1, 3, 6, 1, 5, 5, 7, ))

id_on = id_pkix + (8, )

id_on_permanentIdentifier = id_on + (3, )

class PermanentIdentifier(univ.Sequence):
    componentType = namedtype.NamedTypes(
        namedtype.OptionalNamedType('identifierValue', char.UTF8String()),
        namedtype.OptionalNamedType('assigner', univ.ObjectIdentifier())
    )

# Map of Other Name OIDs to Other Name is added to the
# ones that are in rfc5280.py

_anotherNameMapUpdate = {
    id_on_permanentIdentifier: PermanentIdentifier(),
}

rfc5280.anotherNameMap.update(_anotherNameMapUpdate)


from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('', include('HomePage.urls')),
    path('login/', include('LoginPage.urls')),
    path('register/', include('RegisterPage.urls')),
    path('customize/', include('CustomizePage.urls')),
    path('profile/', include('ProfilePage.urls')),
    path('community/', include('CommunityPage.urls')),
    path('chat/', include('ChatPage.urls')),
    path('admin/', admin.site.urls),
]


# coding=utf-8

import requests
import json
import hashlib

PUBLIC_KEY = "XXXX"
SIGNATURE_KEY = "XXXX"
KEYNAME = "MyKey"
COMPANY_ID = "XXXX"
USER_ID = "1"

url = "https://office.bexio.com/api2.php/" + COMPANY_ID + "/" + USER_ID + "/" + PUBLIC_KEY + "/contact"
payload = {
        'contact_type_id' : input_data['contactTypeId'],
        'name_1' : input_data['contactName'],
        'owner_id' : input_data['contactOwnerId'],
        'user_id' : input_data['contactUserId'],
        'address' : input_data['contactAddress'],
        'city' : input_data['contactCity'],
        'country_id': input_data['contactCountryId'],
        'mail' : input_data['contactMail'],
        'postcode' : input_data['contactPostcode']
        }

#form signature
strSig = "post" + url + json.dumps(payload) + SIGNATURE_KEY

strFin =  hashlib.md5(strSig).hexdigest()

headers = {'Accept': 'application/json',
    'Signature' : strFin
}

r = requests.post(url, data=json.dumps(payload), headers=headers)
data = r.json()

if 'id' in data and data['id'] != '':
    output = {'contactid': data['id']}
else:
    output = {'message':'Contact could not be created', 'err': data}


from datetime import datetime, timedelta
from textwrap import dedent
from airflow.operators import python_operator
from airflow.utils.trigger_rule import TriggerRule

# The DAG object; we'll need this to instantiate a DAG
from airflow import DAG

# Operators; we need this to operate!
from airflow.operators.bash import BashOperator
# These args will get passed on to each operator
# You can override them on a per-task basis during operator initialization
default_args = {
    #'owner': 'airflow',
    'depends_on_past': False,
    #'email': ['airflow@example.com'],
    #'email_on_failure': False,
    #'email_on_retry': False,
    'retries': 1,
    'retry_delay': timedelta(minutes=5),
    # 'queue': 'bash_queue',
    # 'pool': 'backfill',
    # 'priority_weight': 10,
    # 'end_date': datetime(2016, 1, 1),
    # 'wait_for_downstream': False,
    # 'dag': dag,
    # 'sla': timedelta(hours=2),
    # 'execution_timeout': timedelta(seconds=300),
    # 'on_failure_callback': some_function,
    # 'on_success_callback': some_other_function,
    # 'on_retry_callback': another_function,
    # 'sla_miss_callback': yet_another_function,
    # 'trigger_rule': 'all_success'
}
with DAG(
    'sample_dag',
    default_args=default_args,
    description='A simple tutorial DAG',
    schedule_interval=timedelta(days=1),
    start_date=datetime(2021, 1, 1),
    catchup=False,
    tags=['print dag']
) as dag:

  def print_nos():
    i=1
    for i in range(10):
	    print(i)

  t1= python_operator.PythonOperator(
		task_id="printnumbers",
		python_callable=print_nos)

  def print_words():
    print("henna")

  t2= python_operator.PythonOperator(
		task_id="printwords",
		python_callable=print_words)

  t1 >> t2


from django.urls import path
from . import views

urlpatterns = [
    path('', views.home_view, name='api-home'),
    path('Topics/', views.TopicListCreateView.as_view(), name='topic-list'),
    path('Topics/<str:topic_name>/', views.TopicArticleListCreateView.as_view(), name='topic-detail'),
    path('Articles/', views.ArticleListView.as_view(), name='article-list'),
    path('Articles/<int:pk>/', views.ArticleCommentListCreateView.as_view(), name='article-detail'),
    path('Comments/', views.CommentListView.as_view(), name='comment-list'),
    path('Comments/<int:pk>/', views.CommentMessageListCreateView.as_view(), name='comment-detail'),
    path('Messages/', views.MessageListView.as_view(), name='message-list'),
    path('Messages/<int:pk>/', views.MessageRetrieveView.as_view(), name='message-detail'),
]


import os
from discord.ext import commands
from constants import PREFIX, TOKEN, OWNER_IDS

class Bot(commands.Bot):
    def __init__(self):
        super().__init__(command_prefix=commands.when_mentioned_or(PREFIX))
        self.token = TOKEN
        self.owner_ids = OWNER_IDS
        for file in os.listdir('cogs'):
            if file.endswith('.py'):
                try:
                    print(f"Loading {file}")
                    self.load_extension(f'cogs.{file[:-3]}')
                except Exception as e:
                    print(f"Failed to load extension {file}\n{type(e).__name__}: {e}")

    def run(self):
        super().run(self.token, reconnect=True)

    async def on_ready(self):
        print(f"{self.user.name} is now online!")

if __name__ == '__main__':
    Bot().run()


import datetime
import html
import logging
import os
import uuid
import ntpath
import re

from PyQt4 import QtGui

from openlp.core.common import RegistryProperties, Settings, translate, AppLocation, md5_hash
from openlp.core.lib import ImageSource, build_icon, clean_tags, expand_tags, create_thumb
from openlp.plugins.songs.lib.openlyricsxml import OpenLyrics
from openlp.plugins.songs.lib.chords import Chords

log = logging.getLogger(__name__)

class ServiceItemType(object):
    """
    Defines the type of service item
    """
    Text = 1
    Image = 2
    Command = 3

class ItemCapabilities(object):
    """
    Provides an enumeration of a service item's capabilities

    ``CanPreview``
            The capability to allow the ServiceManager to add to the preview tab when making the previous item live.

    ``CanEdit``
            The capability to allow the ServiceManager to allow the item to be edited

    ``CanMaintain``
            The capability to allow the ServiceManager to allow the item to be reordered.

    ``RequiresMedia``
            Determines is the service_item needs a Media Player

    ``CanLoop``
            The capability to allow the SlideController to allow the loop processing.

    ``CanAppend``
            The capability to allow the ServiceManager to add leaves to the
            item

    ``NoLineBreaks``
            The capability to remove lines breaks in the renderer

    ``OnLoadUpdate``
            The capability to update MediaManager when a service Item is loaded.

    ``AddIfNewItem``
            Not Used

    ``ProvidesOwnDisplay``
            The capability to tell the SlideController the service Item has a different display.

    ``HasDetailedTitleDisplay``
            Being Removed and decommissioned.

    ``HasVariableStartTime``
            The capability to tell the ServiceManager that a change to start time is possible.

    ``CanSoftBreak``
            The capability to tell the renderer that Soft Break is allowed

    ``CanWordSplit``
            The capability to tell the renderer that it can split words is
            allowed

    ``HasBackgroundAudio``
            That a audio file is present with the text.

    ``CanAutoStartForLive``
            The capability to ignore the do not play if display blank flag.

    ``CanEditTitle``
            The capability to edit the title of the item

    ``IsOptical``
            Determines is the service_item is based on an optical device

    ``HasDisplayTitle``
            The item contains 'displaytitle' on every frame which should be
            preferred over 'title' when displaying the item

    ``HasNotes``
            The item contains 'notes'

    ``HasThumbnails``
            The item has related thumbnails available

    """
    CanPreview = 1
    CanEdit = 2
    CanMaintain = 3
    RequiresMedia = 4
    CanLoop = 5
    CanAppend = 6
    NoLineBreaks = 7
    OnLoadUpdate = 8
    AddIfNewItem = 9
    ProvidesOwnDisplay = 10
    HasDetailedTitleDisplay = 11
    HasVariableStartTime = 12
    CanSoftBreak = 13
    CanWordSplit = 14
    HasBackgroundAudio = 15
    CanAutoStartForLive = 16
    CanEditTitle = 17
    IsOptical = 18
    HasDisplayTitle = 19
    HasNotes = 20
    HasThumbnails = 21

class ServiceItem(RegistryProperties):
    """
    The service item is a base class for the plugins to use to interact with
    the service manager, the slide controller, and the projection screen
    compositor.
    """
    log.info('Service Item created')

    def __init__(self, plugin=None):
        """
        Set up the service item.

        :param plugin: The plugin that this service item belongs to.
        """
        if plugin:
            self.name = plugin.name
            self.plugin = plugin
        else:
            self.name = '' # Added to stop crash when trying to edit template
        self.title = ''
        self.processor = None
        self.audit = ''
        self.items = []
        self.iconic_representation = None
        self.raw_footer = []
        self.foot_text = ''
        self.theme = None
        self.service_item_type = None
        self._raw_frames = []
        self._display_frames = []
        self.unique_identifier = 0
        self.notes = ''
        self.from_plugin = False
        self.capabilities = []
        self.is_valid = True
        self.icon = None
        self.theme_data = None
        self.main = None
        self.footer = None
        self.bg_image_bytes = None
        self.search_string = ''
        self.data_string = ''
        self.edit_id = None
        self.xml_version = None
        self.start_time = 0
        self.end_time = 0
        self.media_length = 0
        self.from_service = False
        self.image_border = '#000000'
        self.background_audio = []
        self.theme_overwritten = False
        self.temporary_edit = False
        self.auto_play_slides_once = False
        self.auto_play_slides_loop = False
        self.timed_slide_interval = 0
        self.will_auto_start = False
        self.has_original_files = True
        self.extra_data_dict = {}
        self._new_item()

    def _new_item(self):
        """
        Method to set the internal id of the item. This is used to compare service items to see if they are the same.
        """
        self.unique_identifier = str(uuid.uuid1())
        self.validate_item()

    def add_capability(self, capability):
        """
        Add an ItemCapability to a ServiceItem

        :param capability: The capability to add
        """
        self.capabilities.append(capability)

    def is_capable(self, capability):
        """
        Tell the caller if a ServiceItem has a capability

        :param capability: The capability to test for
        """
        return capability in self.capabilities

    def set_extra_data_dict(self, data_dict):
        self.extra_data_dict = data_dict

    def add_icon(self, icon):
        """
        Add an icon to the service item. This is used when displaying the service item in the service manager.

        :param icon: A string to an icon in the resources or on disk.
        """
        self.icon = icon
        self.iconic_representation = build_icon(icon)

    def render(self, provides_own_theme_data=False):
        """
        The render method is what generates the frames for the screen and obtains the display information from the
        renderer. At this point all slides are built for the given display size.

        :param provides_own_theme_data: This switch disables the usage of the item's theme. However, this is
            disabled by default. If this is used, it has to be taken care, that
            the renderer knows the correct theme data. However, this is needed
            for the theme manager.
        """
        log.debug('Render called')
        self._display_frames = []
        self.bg_image_bytes = None
        if not provides_own_theme_data:
            self.renderer.set_item_theme(self.theme)
            self.theme_data, self.main, self.footer = self.renderer.pre_render()
        if self.service_item_type == ServiceItemType.Text:
            log.debug('Formatting slides: %s' % self.title)
            # Save rendered pages to this dict. In the case that a slide is used twice we can use the pages saved to
            # the dict instead of rendering them again.
            if self.get_plugin_name() == 'songs':
                if not self.extra_data_dict:
                    self.extra_data_dict = {}
                    if not self.xml_version.startswith('<?xml') and not self.xml_version.startswith('<song'):
                        # This is an old style song, without XML.
                        verses = self.xml_version.split('\n\n')
                        for count, verse in enumerate(verses):
                            self.extra_data_dict['v' + str(count)] = str(verse).split('\n')

                    elif self.xml_version.startswith('<?xml'):
                        # New style song, output as XML.
                        song_xml_split = re.split('(<verse[\w"= ]*>)', self.xml_version)
                        current_section = ''

                        for song_part in song_xml_split:
                            if song_part.startswith("<verse name"):
                                current_section = song_part.replace('<verse name="', '').replace('">', '')
                            elif song_part.startswith("<lines"):
                                # New line needed between <lines> sections
                                song_part = song_part.replace('</lines><line', '</lines>
<line')
                                # Split out <lines>, </lines>, </verse>, </lyrics> and </song> tags
                                song_part = ''.join(re.split('<lines[\w"= ]*>', song_part))
                                song_part = song_part.replace('</lines>','').replace('</verse>', '')
                                song_part = song_part.replace('</lyrics>','').replace('</song>', '')
                                # Convert to list
                                self.extra_data_dict[current_section] = song_part.split('
')

                previous_pages = {}

                # Get key and transpose amount, if used in this song
                if "<key>" in self.xml_version:
                    current_key = self.xml_version[(self.xml_version.index('<key>') + 5):(self.xml_version.index('<key>')+7)]
                    if current_key[1] == '<':
                        current_key = current_key[0]
                else:
                    current_key = ''

                if "<transposition>" in self.xml_version:
                    current_transpose = self.xml_version[(self.xml_version.index('<transposition>') + 15):(self.xml_version.index('<transposition>')+18)]
                    # Possible options: 1,...,9, 10, 11, -1, ... -9, -10, -11
                    if current_transpose[1] == '<':
                        current_transpose = int(current_transpose[0])
                    elif current_transpose[2] == '<':
                        current_transpose = int(current_transpose[0:2])
                else:
                    current_transpose = 0

                # Calculate resultant key for musician oriented view
                if current_key != '':
                    resultant_key = Chords.transpose_chord(current_key, current_key, current_transpose)
                else:
                    resultant_key = ''

                for slide in self._raw_frames:
                    verse_tag = slide['verseTag']
                    if verse_tag in previous_pages and previous_pages[verse_tag][0] == slide['raw_slide']:
                        pages = previous_pages[verse_tag][1]
                    else:
                        pages = self.renderer.format_slide(slide['raw_slide'], self)
                        previous_pages[verse_tag] = (slide['raw_slide'], pages)

                    xml_lines = self.extra_data_dict[verse_tag.lower()]
                    xml_line_lower, xml_line_upper = 0, 0

                    subpage_count = 0
                    for page in pages:
                        subpage_count += 1

                        # Given the current page_lines, calculate the corresponding xml_lines
                        xml_line_lower = xml_line_upper
                        xml_segment = ''.join(re.split('<chord[\w\+#"=// ]*/>', xml_lines[xml_line_upper]))

                        while (xml_line_upper < len(xml_lines)) and not (xml_segment.strip() == page.strip()):
                            xml_line_upper += 1
                            xml_segment = xml_segment + '
' + ''.join(re.split('<chord[\w\+#"=// ]*/>', xml_lines[xml_line_upper]))

                        xml_line_upper += 1
                        page_xml = xml_lines[xml_line_lower: xml_line_upper]

                        # Exclude any [br] or [---] elements from the XML list
                        page_xml_short = []
                        for item in page_xml:
                            if item != '[br]' and item != '[---]':
								# split item by chord tags, then transpose each chord tag
                                if current_transpose != 0:
                                    item_sections = re.split('(<chord[\w\+#"=// ]*/>)', item)
                                    transposed_item = ''

                                    for item_section in item_sections:
                                        if item_section.startswith('<chord name'):
                                            transposed_item = transposed_item + Chords.transpose_chord_tag(item_section, current_key, current_transpose)
                                        else:
                                            transposed_item = transposed_item + item_section
                                    page_xml_short.append(transposed_item)
                                else:
                                    page_xml_short.append(item)

                        page = page.replace('
', '{br}')
                        html_data = expand_tags(html.escape(page.rstrip()))
                        self._display_frames.append({
                            'title': clean_tags(page),
                            'text': clean_tags(page.rstrip()),
                            'html': html_data.replace('&nbsp;', ' '),
                            'verseTag': verse_tag,
                            'verseSubpage': subpage_count,
                            'extraInfo': '
'.join(page_xml_short),
                            'playedKey': resultant_key
                        })

                        # Deal with any [br] or [---] tag in XML before processing next page
                        if xml_line_upper < len(xml_lines) and \
                            (xml_lines[xml_line_upper].strip() == '[br]' or xml_lines[xml_line_upper].strip() == '[---]'):
                            xml_line_upper += 1

            elif (self.get_plugin_name() == "custom") or (self.get_plugin_name() == ''):
                previous_pages = {}
                for slide in self._raw_frames:
                    verse_tag = slide['verseTag']
                    if verse_tag in previous_pages and previous_pages[verse_tag][0] == slide['raw_slide']:
                        pages = previous_pages[verse_tag][1]
                    else:
                        pages = self.renderer.format_slide(slide['raw_slide'], self)
                        previous_pages[verse_tag] = (slide['raw_slide'], pages)

                    for page in pages:
                        page = page.replace('
', '{br}')
                        html_data = expand_tags(html.escape(page.rstrip()))
                        self._display_frames.append({
                            'title': clean_tags(page),
                            'text': clean_tags(page.rstrip()),
                            'html': html_data.replace('&nbsp;', ' '),
                            'verseTag': verse_tag
                        })

            elif self.get_plugin_name() == "bibles":
                previous_pages = {}
                for slide in self._raw_frames:
                    verse_tag = slide['verseTag']
                    if verse_tag in previous_pages and previous_pages[verse_tag][0] == slide['raw_slide']:
                        pages = previous_pages[verse_tag][1]
                    else:
                        pages = self.renderer.format_slide(slide['raw_slide'], self)
                        previous_pages[verse_tag] = (slide['raw_slide'], pages)

                    for page in pages:
                        page = page.replace('
', '{br}')
                        html_data = expand_tags(html.escape(page.rstrip()))
                        if hasattr(self, 'simple_title'):
                            title = self.simple_title
                        else:
                            title = self.title
                        self._display_frames.append({
                            'title': clean_tags(page),
                            'text': clean_tags(page.rstrip()),
                            'html': html_data.replace('&nbsp;', ' '),
                            'verseTag': verse_tag,
                            'extraInfo': title
                        })

        elif self.service_item_type == ServiceItemType.Image or self.service_item_type == ServiceItemType.Command:
            pass
        else:
            log.error('Invalid value renderer: %s' % self.service_item_type)
        self.title = clean_tags(self.title)
        # The footer should never be None, but to be compatible with a few
        # nightly builds between 1.9.4 and 1.9.5, we have to correct this to
        # avoid tracebacks.
        if self.raw_footer is None:
            self.raw_footer = []
        self.foot_text = '
'.join([_f for _f in self.raw_footer if _f])

    def add_from_image(self, path, title, background=None, thumbnail=None):
        """
        Add an image slide to the service item.

        :param path: The directory in which the image file is located.
        :param title: A title for the slide in the service item.
        :param background:
        :param thumbnail: Optional alternative thumbnail, used for remote thumbnails.
        """
        if background:
            self.image_border = background
        self.service_item_type = ServiceItemType.Image
        if not thumbnail:
            self._raw_frames.append({'title': title, 'path': path})
        else:
            self._raw_frames.append({'title': title, 'path': path, 'image': thumbnail})
        self.image_manager.add_image(path, ImageSource.ImagePlugin, self.image_border)
        self._new_item()

    def add_from_text(self, raw_slide, verse_tag=None):
        """
        Add a text slide to the service item.

        :param raw_slide: The raw text of the slide.
        :param verse_tag:
        """
        if verse_tag:
            verse_tag = verse_tag.upper()
        self.service_item_type = ServiceItemType.Text
        title = raw_slide[:30].split('\n')[0]
        self._raw_frames.append({'title': title, 'raw_slide': raw_slide, 'verseTag': verse_tag})
        self._new_item()

    def add_from_command(self, path, file_name, image, display_title=None, notes=None):
        """
        Add a slide from a command.

        :param path: The title of the slide in the service item.
        :param file_name: The title of the slide in the service item.
        :param image: The command of/for the slide.
        :param display_title: Title to show in gui/webinterface, optional.
        :param notes: Notes to show in the webinteface, optional.
        """
        self.service_item_type = ServiceItemType.Command
        # If the item should have a display title but this frame doesn't have one, we make one up
        if self.is_capable(ItemCapabilities.HasDisplayTitle) and not display_title:
            display_title = translate('OpenLP.ServiceItem', '[slide %d]') % (len(self._raw_frames) + 1)
        # Update image path to match servicemanager location if file was loaded from service
        if image and not self.has_original_files and self.name == 'presentations':
            file_location = os.path.join(path, file_name)
            file_location_hash = md5_hash(file_location.encode('utf-8'))
            image = os.path.join(AppLocation.get_section_data_path(self.name), 'thumbnails',
                                 file_location_hash, ntpath.basename(image))
        self._raw_frames.append({'title': file_name, 'image': image, 'path': path,
                                 'display_title': display_title, 'notes': notes})
        self._new_item()

    def get_item_xml(self):
        if self.xml_version:
            return self.xml_version
        else:
            return ''

    def get_plugin_name(self):
        if self.name:
            return self.name
        else:
            return ''

    def get_service_repr(self, lite_save):
        """
        This method returns some text which can be saved into the service file to represent this item.
        """
        service_header = {
            'name': self.name,
            'plugin': self.name,
            'theme': self.theme,
            'title': self.title,
            'icon': self.icon,
            'footer': self.raw_footer,
            'type': self.service_item_type,
            'audit': self.audit,
            'notes': self.notes,
            'from_plugin': self.from_plugin,
            'capabilities': self.capabilities,
            'search': self.search_string,
            'data': self.data_string,
            'xml_version': self.xml_version,
            'auto_play_slides_once': self.auto_play_slides_once,
            'auto_play_slides_loop': self.auto_play_slides_loop,
            'timed_slide_interval': self.timed_slide_interval,
            'start_time': self.start_time,
            'end_time': self.end_time,
            'media_length': self.media_length,
            'background_audio': self.background_audio,
            'theme_overwritten': self.theme_overwritten,
            'will_auto_start': self.will_auto_start,
            'processor': self.processor
        }
        service_data = []
        if self.service_item_type == ServiceItemType.Text:
            service_data = [slide for slide in self._raw_frames]
        elif self.service_item_type == ServiceItemType.Image:
            if lite_save:
                for slide in self._raw_frames:
                    service_data.append({'title': slide['title'], 'path': slide['path']})
            else:
                service_data = [slide['title'] for slide in self._raw_frames]
        elif self.service_item_type == ServiceItemType.Command:
            for slide in self._raw_frames:
                service_data.append({'title': slide['title'], 'image': slide['image'], 'path': slide['path'],
                                     'display_title': slide['display_title'], 'notes': slide['notes']})
        return {'header': service_header, 'data': service_data}

    def set_from_service(self, service_item, path=None):
        """
        This method takes a service item from a saved service file (passed from the ServiceManager) and extracts the
        data actually required.

        :param service_item: The item to extract data from.
        :param path: Defaults to *None*. This is the service manager path for things which have their files saved
        with them or None when the saved service is lite and the original file paths need to be preserved.
        """
        log.debug('set_from_service called with path %s' % path)
        header = service_item['serviceitem']['header']
        self.title = header['title']
        self.name = header['name']
        self.service_item_type = header['type']
        self.theme = header['theme']
        self.add_icon(header['icon'])
        self.raw_footer = header['footer']
        self.audit = header['audit']
        self.notes = header['notes']
        self.from_plugin = header['from_plugin']
        self.capabilities = header['capabilities']
        # Added later so may not be present in older services.
        self.search_string = header.get('search', '')
        self.data_string = header.get('data', '')
        self.xml_version = header.get('xml_version')
        self.start_time = header.get('start_time', 0)
        self.end_time = header.get('end_time', 0)
        self.media_length = header.get('media_length', 0)
        self.auto_play_slides_once = header.get('auto_play_slides_once', False)
        self.auto_play_slides_loop = header.get('auto_play_slides_loop', False)
        self.timed_slide_interval = header.get('timed_slide_interval', 0)
        self.will_auto_start = header.get('will_auto_start', False)
        self.processor = header.get('processor', None)
        self.has_original_files = True
        # TODO: Remove me in 2,3 build phase
        if self.is_capable(ItemCapabilities.HasDetailedTitleDisplay):
            self.capabilities.remove(ItemCapabilities.HasDetailedTitleDisplay)
            self.processor = self.title
            self.title = None
        if 'background_audio' in header:
            self.background_audio = []
            for filename in header['background_audio']:
                # Give them real file paths.
                filepath = filename
                if path:
                    # Windows can handle both forward and backward slashes, so we use ntpath to get the basename
                    filepath = os.path.join(path, ntpath.basename(filename))
                self.background_audio.append(filepath)
        self.theme_overwritten = header.get('theme_overwritten', False)
        if self.service_item_type == ServiceItemType.Text:
            for slide in service_item['serviceitem']['data']:
                self._raw_frames.append(slide)
        elif self.service_item_type == ServiceItemType.Image:
            settings_section = service_item['serviceitem']['header']['name']
            background = QtGui.QColor(Settings().value(settings_section + '/background color'))
            if path:
                self.has_original_files = False
                for text_image in service_item['serviceitem']['data']:
                    filename = os.path.join(path, text_image)
                    self.add_from_image(filename, text_image, background)
            else:
                for text_image in service_item['serviceitem']['data']:
                    self.add_from_image(text_image['path'], text_image['title'], background)
        elif self.service_item_type == ServiceItemType.Command:
            for text_image in service_item['serviceitem']['data']:
                if not self.title:
                    self.title = text_image['title']
                if self.is_capable(ItemCapabilities.IsOptical):
                    self.has_original_files = False
                    self.add_from_command(text_image['path'], text_image['title'], text_image['image'])
                elif path:
                    self.has_original_files = False
                    self.add_from_command(path, text_image['title'], text_image['image'],
                                          text_image.get('display_title', ''), text_image.get('notes', ''))
                else:
                    self.add_from_command(text_image['path'], text_image['title'], text_image['image'])
        self._new_item()

    def get_display_title(self):
        """
        Returns the title of the service item.
        """
        if self.is_text() or self.is_capable(ItemCapabilities.IsOptical) \
                or self.is_capable(ItemCapabilities.CanEditTitle):
            return self.title
        else:
            if len(self._raw_frames) > 1:
                return self.title
            else:
                return self._raw_frames[0]['title']

    def merge(self, other):
        """
        Updates the unique_identifier with the value from the original one
        The unique_identifier is unique for a given service item but this allows one to replace an original version.

        :param other: The service item to be merged with
        """
        self.unique_identifier = other.unique_identifier
        self.notes = other.notes
        self.temporary_edit = other.temporary_edit
        # Copy theme over if present.
        if other.theme is not None:
            self.theme = other.theme
            self._new_item()
        self.render()
        if self.is_capable(ItemCapabilities.HasBackgroundAudio):
            log.debug(self.background_audio)

    def __eq__(self, other):
        """
        Confirms the service items are for the same instance
        """
        if not other:
            return False
        return self.unique_identifier == other.unique_identifier

    def __ne__(self, other):
        """
        Confirms the service items are not for the same instance
        """
        return self.unique_identifier != other.unique_identifier

    def __hash__(self):
        """
        Return the hash for the service item.
        """
        return self.unique_identifier

    def is_media(self):
        """
        Confirms if the ServiceItem is media
        """
        return ItemCapabilities.RequiresMedia in self.capabilities

    def is_command(self):
        """
        Confirms if the ServiceItem is a command
        """
        return self.service_item_type == ServiceItemType.Command

    def is_image(self):
        """
        Confirms if the ServiceItem is an image
        """
        return self.service_item_type == ServiceItemType.Image

    def uses_file(self):
        """
        Confirms if the ServiceItem uses a file
        """
        return self.service_item_type == ServiceItemType.Image or \
            (self.service_item_type == ServiceItemType.Command and not self.is_capable(ItemCapabilities.IsOptical))

    def is_text(self):
        """
        Confirms if the ServiceItem is text
        """
        return self.service_item_type == ServiceItemType.Text

    def set_media_length(self, length):
        """
        Stores the media length of the item

        :param length: The length of the media item
        """
        self.media_length = length
        if length > 0:
            self.add_capability(ItemCapabilities.HasVariableStartTime)

    def get_frames(self):
        """
        Returns the frames for the ServiceItem
        """
        if self.service_item_type == ServiceItemType.Text:
            return self._display_frames
        else:
            return self._raw_frames

    def get_rendered_frame(self, row):
        """
        Returns the correct frame for a given list and renders it if required.

        :param row: The service item slide to be returned
        """
        if self.service_item_type == ServiceItemType.Text:
            return self._display_frames[row]['html'].split('\n')[0]
        elif self.service_item_type == ServiceItemType.Image:
            return self._raw_frames[row]['path']
        else:
            return self._raw_frames[row]['image']

    def get_frame_title(self, row=0):
        """
        Returns the title of the raw frame
        """
        try:
            return self._raw_frames[row]['title']
        except IndexError:
            return ''

    def get_frame_path(self, row=0, frame=None):
        """
        Returns the path of the raw frame
        """
        if not frame:
            try:
                frame = self._raw_frames[row]
            except IndexError:
                return ''
        if self.is_image() or self.is_capable(ItemCapabilities.IsOptical):
            path_from = frame['path']
        else:
            path_from = os.path.join(frame['path'], frame['title'])
        return path_from

    def remove_frame(self, frame):
        """
        Remove the specified frame from the item
        """
        if frame in self._raw_frames:
            self._raw_frames.remove(frame)

    def get_media_time(self):
        """
        Returns the start and finish time for a media item
        """
        start = None
        end = None
        if self.start_time != 0:
            start = translate('OpenLP.ServiceItem', 'Start: %s') % \
                str(datetime.timedelta(seconds=self.start_time))
        if self.media_length != 0:
            end = translate('OpenLP.ServiceItem', 'Length: %s') % \
                str(datetime.timedelta(seconds=self.media_length))
        if not start and not end:
            return ''
        elif start and not end:
            return start
        elif not start and end:
            return end
        else:
            return '%s
%s' % (start, end)

    def update_theme(self, theme):
        """
        updates the theme in the service item

        :param theme: The new theme to be replaced in the service item
        """
        self.theme_overwritten = (theme is None)
        self.theme = theme
        self._new_item()
        self.render()

    def remove_invalid_frames(self, invalid_paths=None):
        """
        Remove invalid frames, such as ones where the file no longer exists.
        """
        if self.uses_file():
            for frame in self.get_frames():
                if self.get_frame_path(frame=frame) in invalid_paths:
                    self.remove_frame(frame)

    def missing_frames(self):
        """
        Returns if there are any frames in the service item
        """
        return not bool(self._raw_frames)

    def validate_item(self, suffix_list=None):
        """
        Validates a service item to make sure it is valid
        """
        self.is_valid = True
        for frame in self._raw_frames:
            if self.is_image() and not os.path.exists(frame['path']):
                self.is_valid = False
                break
            elif self.is_command():
                if self.is_capable(ItemCapabilities.IsOptical):
                    if not os.path.exists(frame['title']):
                        self.is_valid = False
                        break
                else:
                    file_name = os.path.join(frame['path'], frame['title'])
                    if not os.path.exists(file_name):
                        self.is_valid = False
                        break
                    if suffix_list and not self.is_text():
                        file_suffix = frame['title'].split('.')[-1]
                        if file_suffix.lower() not in suffix_list:
                            self.is_valid = False
                            break


from typing import Dict
from core.qualitymodel.qualitymodel import QualityModel

class NoCpd(QualityModel):
    def __init__(self):
        pass

    def get_desc(self) -> Dict:
        model = {
            "metrics": {
                "method_length": "./metrics/method_length.py",
                "file_length": "./metrics/file_length.py",
                "argument_count": "./metrics/argument_count.py",
                "complex_logic": "./metrics/complex_logic.py",
                "method_count": "./metrics/method_count.py",
                "return_statements": "./metrics/return_statements.py",
                "nested_controlflows": "./metrics/nested_controlflows.py",
                "cognitive_complexity": "./metrics/cognitive_complexity.py",
            },
            "aggregations": {
                "cyclomatic_complexity": self.cyclomatic_complexity,
                "structural_issues": self.structural_issues,
                "cognitive_complexity": self.cognitive_complexity,
                "maintainability": self.maintainability,
            },
        }
        return model

    def maintainability(self, results: Dict) -> int | float:
        return (
            results["cognitive_complexity"]
            + results["structural_issues"]
            + results["cyclomatic_complexity"]
        )

    def cognitive_complexity(self, results: Dict):
        return results["complex_logic"].outcome + results["nested_controlflows"].outcome

    def structural_issues(self, results: Dict):
        return (
            results["argument_count"].outcome
            + results["file_length"].outcome
            + results["method_count"].outcome
        )

    def cyclomatic_complexity(self, results: Dict):
        return results["return_statements"].outcome

model = NoCpd()


import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# Load the dataset
data = pd.read_csv('breast_cancer.csv')  # Replace with the actual path to our CSV file

# Select relevant columns for visualization
selected_features = ['diagnosis', 'radius_mean', 'texture_mean', 'perimeter_mean', 'area_mean', 'smoothness_mean']

# Subset the data for selected features
selected_data = data[selected_features]

# Create pair plot
sns.pairplot(selected_data, hue='diagnosis', markers=['o', 's'], palette={'M': 'red', 'B': 'blue'})
plt.suptitle('Pair Plot of Selected Features', y=1.02)
plt.show()

# Create correlation heatmap
correlation_matrix = selected_data.corr()
plt.figure(figsize=(10, 8))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', fmt=".2f")
plt.title('Correlation Heatmap of Selected Features')
plt.show()


from django.urls import path
from .import views

urlpatterns = [
    path('', views.home, name='home'),
    path('homeAPI/', views.homeAPI, name="homeAPI"),

    path('add_customer/', views.add_customer, name="add_customer"),
    path('add_customerAPI/', views.addCustomerAPI, name="addCustomerFunc"),

    path('write_dept/', views.write_dept, name="write_dept"),
    path('write_deptAPI/', views.write_deptAPI, name="write_deptAPI"),

    path('customerdata/<int:id>/', views.Customerdata, name="customerdata"),

    path('turndept/', views.turnDept, name="turndept"),
    path('turnDeptAPI/', views.turnDeptAPI, name="turnDeptAPI"),

    path('showHistory/<int:id>/', views.showHistory, name="showHistory"),
]

# represented = ifodalangan
# much yet = hali ko'p
# although = garchi
# realize = anglash
# overtake = quvib o'tish
# significant = muhim
# relevant = muvofiq
# refer=murojat qilmoq
# proud=mag'rur