from __future__ import annotations

from typing import Callable

import numpy as np
from matplotlib import colors
from matplotlib import pyplot as plt
from matplotlib import ticker
from numpy.typing import NDArray

from aha.parameters.parameters import (
    ANGULAR_COORDINATES,
    BIOMARKER_FEATURES,
    PLOT_COMPONENTS,
    RADIAL_COORDINATES,
)

def validate_resolution(func: Callable) -> Callable:
    """Validates the resultion of the provided interpolation values used for coloring.

    Args:
        func: Coloring function
    """

    def wrapper(self: Biomarker, ax: plt.Axes, interpolated_segment_values: NDArray) -> plt.Axes:
        assert interpolated_segment_values.shape[0] == self.extended_angular_coordinates.shape[1], (
            "Incorrect resolution of interpolation in angular axis "
            f"({interpolated_segment_values.shape[0]}) "
            f"compared to coloring resolution ({self.extended_angular_coordinates.shape[1]})"
        )

        assert interpolated_segment_values.shape[1] == self.extended_radial_coordinates.shape[0], (
            f"Incorrect resolution of interpolation in radial axis "
            f"({interpolated_segment_values.shape[1]}) "
            f"compared to coloring resolution ({self.extended_radial_coordinates.shape[0]})"
        )
        return func(self, ax, interpolated_segment_values)

    return wrapper

class Biomarker:
    """Base class for biomarker coloring handling"""

    def __init__(self) -> None:
        self._extended_radial_coordinates = np.repeat(
            RADIAL_COORDINATES[:, np.newaxis], PLOT_COMPONENTS["resolution"][0], axis=1
        ).T

        self._extended_angular_coordinates = np.repeat(
            ANGULAR_COORDINATES[:, np.newaxis], self.extended_radial_coordinates.shape[1], axis=1
        )

    @property
    def norm(self) -> tuple[int, int]:
        return (0, 0)

    @property
    def cmap(self) -> plt.colormaps:
        return plt.get_cmap(BIOMARKER_FEATURES[self.__class__.__name__]["cmap"])

    @property
    def units(self) -> str:
        return BIOMARKER_FEATURES[self.__class__.__name__]["units"]

    @property
    def title(self) -> str:
        return BIOMARKER_FEATURES[self.__class__.__name__]["title"]

    @property
    def extended_radial_coordinates(self) -> NDArray:
        return self._extended_radial_coordinates

    @property
    def extended_angular_coordinates(self) -> NDArray:
        return self._extended_angular_coordinates

    def color_plot(self, ax: plt.Axes, interpolated_segment_values: NDArray) -> plt.Axes:
        """Virtual function with unused arguments."""
        _ = (
            ax,
            interpolated_segment_values,
        )
        return ax

class Strain(Biomarker):
    """Class for coloring the AHA plot with strain values"""

    @property
    def norm(self) -> colors.BoundaryNorm:
        norm = colors.BoundaryNorm(self.levels, ncolors=self.cmap.N, clip=True)
        return norm

    @property
    def levels(self) -> ticker.MaxNLocator:
        nbins = BIOMARKER_FEATURES[self.__class__.__name__]["n_bins"]
        tick_values = BIOMARKER_FEATURES[self.__class__.__name__]["norm_values"]
        return ticker.MaxNLocator(nbins=nbins).tick_values(*tick_values)

    @validate_resolution
    def color_plot(self, ax: plt.Axes, interpolated_segment_values: NDArray) -> plt.Axes:
        """Color plot according to the strain visualisation guidelines.

        Args:
            ax: Plot object.
            interpolated_segment_values: Values used for coloring the plot.

        Returns:
            pyplot.Axes: Colored plot object.
        """
        ax.contourf(
            self.extended_angular_coordinates,
            self.extended_radial_coordinates,
            interpolated_segment_values.T,
            cmap=self.cmap,
            levels=self.levels,
        )

        return ax

class MyocardialWork(Biomarker):
    """Class for coloring the AHA plot with myocardial work values"""

    @property
    def norm(self) -> tuple[int, int]:
        norm = tuple(BIOMARKER_FEATURES[self.__class__.__name__]["norm_values"])
        normalized_norm = colors.Normalize(vmin=norm[0], vmax=norm[1])
        return normalized_norm

    @validate_resolution
    def color_plot(self, ax: plt.Axes, interpolated_segment_values: NDArray) -> plt.Axes:
        """Color plot according to the myocardial work visualisation guidelines.

        Args:
            ax: Plot object.
            interpolated_segment_values: Values used for coloring the plot.

        Returns:
            pyplot.Axes: Colored plot object.
        """
        ax.pcolormesh(
            self.extended_angular_coordinates,
            self.extended_radial_coordinates,
            interpolated_segment_values.T,
            cmap=self.cmap,
            norm=self.norm,
        )

        return ax


from fastapi import FastAPI

from src.coil.router import router as coil_router

app = FastAPI(
    title="Warehouse metal coil app",
)

routers = (
    coil_router,
)

[app.include_router(router) for router in routers]


import json

## EMPAREJAMOS LOS TITULOS ##

titulosEs = open('titulosSQuAD.txt').readlines()
titulosEu = open('titulosSQuAD_eu.txt').readlines()
titulos = []

for i in range(len(titulosEs)):
    tituloEs = titulosEs[i]
    tituloEu = titulosEu[i]
    if tituloEs[-1] == '\n':
        tituloEs = tituloEs[:-1]
    if tituloEu[-1] == '\n':
        tituloEu = tituloEu[:-1]
    titulos.append((tituloEs,tituloEu))

## EMPAREJAMOS LOS PÁRRAFOS ##

parrafosEs = open('contextosSQuAD.txt').readlines()
parrafosEu = open('contextosSQuAD_eu.txt').readlines()
parrafos = []

for i in range(len(parrafosEs)):
    parrafoEs = parrafosEs[i]
    parrafoEu = parrafosEu[i]
    while parrafoEs[-1] == '\n':
        parrafoEs = parrafoEs[:-1]
    while parrafoEu[-1] == '\n':
        parrafoEu = parrafoEu[:-1]
    parrafos.append((parrafoEs,parrafoEu))

## EMPAREJAMOS LAS PREGUNTAS ##

preguntasEs = open('preguntasSQuAD.txt').readlines()
preguntasEu = open('preguntasSQuAD_eu.txt').readlines()
preguntas = []

for i in range(len(preguntasEs)):
    preguntaEs = preguntasEs[i]
    preguntaEu = preguntasEu[i]
    while preguntaEs[-1] == '\n':
        preguntaEs = preguntaEs[:-1]
    while preguntaEu[-1] == '\n':
        preguntaEu = preguntaEu[:-1]
    preguntas.append((preguntaEs,preguntaEu))

## EMPAREJAMOS LAS RESPUESTAS ##

respuestasEs = open('respuestasSQuAD.txt').readlines()
respuestasEu = open('respuestasSQuAD_eu.txt').readlines()
respuestas = []

for i in range(len(respuestasEs)):
    respuestaEs = respuestasEs[i]
    respuestaEu = respuestasEu[i]
    while respuestaEs[-1] == '\n':
        respuestaEs = respuestaEs[:-1]
    while respuestaEu[-1] == '\n':
        respuestaEu = respuestaEu[:-1]
    respuestas.append((respuestaEs,respuestaEu))

## EMPAREJAMOS LAS RESPUESTAS PLAUSIBLES ##

respuestasEs = open('respuestasPlausiblesSQuAD.txt').readlines()
respuestasEu = open('respuestasPlausiblesSQuAD_eu.txt').readlines()
respuestasPlausibles = []

for i in range(len(respuestasEs)):
    respuestaEs = respuestasEs[i]
    respuestaEu = respuestasEu[i]
    while respuestaEs[-1] == '\n':
        respuestaEs = respuestaEs[:-1]
    while respuestaEu[-1] == '\n':
        respuestaEu = respuestaEu[:-1]
    respuestasPlausibles.append((respuestaEs,respuestaEu))

## MONTAMOS UNA PRIMERA INSTANCIA DEL DATASET SIN LAS POSICIONES ##

with open('SQuAD-v2.0-eu_small_train.json', 'r') as f:
    data = json.load(f)

    for datos in data['data']:
        datos['title'] = titulos[0][1]
        titulos.pop(0)
        for muestra in datos['paragraphs']:
            muestra['context'] = parrafos[0][1]
            parrafos.pop(0)
            for qas in muestra['qas']:
                qas['question'] = preguntas[0][1]
                preguntas.pop(0)
                if len(qas['answers']) == 0:
                    for respuestaPlausible in qas['plausible_answers']:
                        respuestaPlausible['text'] = respuestasPlausibles[0][1]
                        respuestasPlausibles.pop(0)
                        respuestaPlausible['answer_start'] = -1
                else:
                    for answer in qas['answers']:
                        answer['text'] = respuestas[0][1]
                        respuestas.pop(0)
                        answer['answer_start'] = -1

with open('SQuAD-v2.0-eu_small_train.json', 'w') as f:
    f.write(json.dumps(data))


import os
import numpy as np
import cv2
from pathlib import Path
import pathlib
from tqdm import tqdm
from array import array
import open3d as o3d
import pysnooper
from loguru import logger
import matplotlib.pyplot as plt

PALETTE = [[165, 42, 42], [0, 192, 0], [196, 196, 196], [190, 153, 153],
             [180, 165, 180], [90, 120, 150], [
               102, 102, 156], [128, 64, 255],
             [140, 140, 200], [170, 170, 170], [250, 170, 160], [96, 96, 96],
             [230, 150, 140], [128, 64, 128], [
               110, 110, 110], [244, 35, 232],
             [150, 100, 100], [70, 70, 70], [150, 120, 90], [220, 20, 60],
             [255, 0, 0], [255, 0, 100], [255, 0, 200], [200, 128, 128],
             [255, 255, 255], [64, 170, 64], [230, 160, 50], [70, 130, 180],
             [190, 255, 255], [152, 251, 152], [107, 142, 35], [0, 170, 30],
             [255, 255, 128], [250, 0, 30], [100, 140, 180], [220, 220, 220],
             [220, 128, 128], [222, 40, 40], [100, 170, 30], [40, 40, 40],
             [33, 33, 33], [100, 128, 160], [142, 0, 0], [70, 100, 150],
             [210, 170, 100], [153, 153, 153], [128, 128, 128], [0, 0, 80],
             [250, 170, 30], [192, 192, 192], [220, 220, 0], [140, 140, 20],
             [119, 11, 32], [150, 0, 255], [
               0, 60, 100], [0, 0, 142], [0, 0, 90],
             [0, 0, 230], [0, 80, 100], [128, 64, 64], [0, 0, 110], [0, 0, 70],
             [0, 0, 192], [32, 32, 32], [120, 10, 10], [0, 0, 0]]

CLASSES = ('Bird', 'Ground Animal', 'Curb', 'Fence', 'Guard Rail', 'Barrier',
           'Wall', 'Bike Lane', 'Crosswalk - Plain', 'Curb Cut', 'Parking', 'Pedestrian Area',
           'Rail Track', 'Road', 'Service Lane', 'Sidewalk', 'Bridge', 'Building', 'Tunnel',
           'Person', 'Bicyclist', 'Motorcyclist', 'Other Rider', 'Lane Marking - Crosswalk',
           'Lane Marking - General', 'Mountain', 'Sand', 'Sky', 'Snow', 'Terrain', 'Vegetation',
           'Water', 'Banner', 'Bench', 'Bike Rack', 'Billboard', 'Catch Basin', 'CCTV Camera',
           'Fire Hydrant', 'Junction Box', 'Mailbox', 'Manhole', 'Phone Booth', 'Pothole',
           'Street Light', 'Pole', 'Traffic Sign Frame', 'Utility Pole', 'Traffic Light',
           'Traffic Sign (Back)', 'Traffic Sign (Front)', 'Trash Can', 'Bicycle', 'Boat',
           'Bus', 'Car', 'Caravan', 'Motorcycle', 'On Rails', 'Other Vehicle', 'Trailer',
           'Truck', 'Wheeled Slow', 'Car Mount', 'Ego Vehicle', 'Unlabeled')

# PALETTE = [[210, 170, 100], [153, 153, 153], [128, 128, 128], [0, 0, 80],
#              [250, 170, 30], [192, 192, 192], [220, 220, 0]]
seg_list = [2, 8, 13, 15, 23, 24, 29]
# seg_list = [2, 9, 23, 24]
show_seg_list = [2, 8, 9, 23, 24]

class PLYUtils:
    def __init__(self, min_d=3, max_d=20, batch_size=1, roi=[160, 360, 20, 1200], dropout=0):
        super(PLYUtils, self).__init__()
        self.min_d = min_d
        self.max_d = max_d
        self.roi = roi
        self.dropout = dropout

        # 第一列是xyz的最小值，第二列是xyz的最大值
        self.voxel_bound = np.zeros((3, 2))
        self.voxel_bound[:, 0] = np.inf

        self.data = array('f')

    def write_point_cloud(self, ply_filename):
        length = len(self.data) // 6

        header = "ply\n" \
                 "format binary_little_endian 1.0\n" \
                 f"element vertex {length}\n" \
                 f"property float x\n" \
                 f"property float y\n" \
                 f"property float z\n" \
                 f"property float red\n" \
                 f"property float green\n" \
                 f"property float blue\n" \
                 f"end_header\n"

        with open(ply_filename, "wb") as file:
            file.write(header.encode(encoding="ascii"))
            self.data.tofile(file)

    '''
    用于函数外部保存点云数据
    '''
    @staticmethod
    def save(ply_filename, points):
        formatted_points = []
        for point in points:
            formatted_points.append(
                "%f %f %f %d %d %d 0\n" % (point[0], point[1], point[2], int(point[3]), int(point[4]), int(point[5])))

        out_file = open(ply_filename, "w")
        out_file.write('''ply
        format ascii 1.0
        element vertex %d
        property float x
        property float y
        property float z
        property uchar blue
        property uchar green
        property uchar red
        property uchar alpha
        end_header
        %s
        ''' % (len(points), "".join(formatted_points)))
        out_file.close()

    def backproject(self, depth, scale, intrinsics):
        u = range(0, depth.shape[1])
        v = range(0, depth.shape[0])

        u, v = np.meshgrid(u, v)
        u, v= u.astype(float), v.astype(float)

        Z = depth.astype(float) / scale
        X = (u - intrinsics[0, 2]) * Z / intrinsics[0, 0]
        Y = (v - intrinsics[1, 2]) * Z / intrinsics[1, 1]

        X = np.ravel(X)
        Y = np.ravel(Y)
        Z = np.ravel(Z)

        return np.vstack((X, Y, Z))

    def add_depthmap(self, depth, image, scale, intrinsics, check_bound=False, seg=None, extrinsics=None):
        position = self.backproject(depth, scale, intrinsics)
        position = np.vstack((position, np.ones(len(position[0]))))
        position = np.dot(extrinsics, position)

        depth = np.divide(depth, scale)
        # print(depth.max(), depth.min())
        mask = (self.min_d <= depth) & (depth <= self.max_d)
        if self.roi is not None:
            mask[:self.roi[0], :] = False
            mask[self.roi[1]:, :] = False
            # mask[:, :self.roi[2]] = False
            # mask[:, self.roi[3]:] = False

        if seg is not None:
            mask_seg = np.zeros_like(mask)
            for id in seg_list:
                mask_seg |= (seg == id)

            mask = np.logical_and(mask_seg, mask)

        R = np.ravel(image[:, :, 0])
        G = np.ravel(image[:, :, 1])
        B = np.ravel(image[:, :, 2])

        points = np.transpose(np.vstack((position[0:3, :], R, G, B)))
        mask = mask.reshape((1, -1)).transpose(1, 0).repeat(6, axis = 1)
        # print(points.shape, mask.shape, points[mask].shape)
        # print(mask.reshape((depth.shape[0], -1)))
        points = points[mask]

        if not check_bound:
            self.data.extend(points.tolist())

        check_bound_points = points.reshape((-1, 6)).T[:3, :]
        # logger.debug("check_bound_points shape {}".format(check_bound_points.shape))
        # if check_bound_points.shape[1]:
        # 记录点云的最大最小边界
        self.voxel_bound[:, 0] = np.minimum(self.voxel_bound[:, 0], np.amin(check_bound_points, axis=1))
        self.voxel_bound[:, 1] = np.maximum(self.voxel_bound[:, 1], np.amax(check_bound_points, axis=1))

        return points.reshape((-1, 6))

    @staticmethod
    def draw_pointcloud(pcd_path, output = None):
        if Path(pcd_path).is_dir():
            root = Path(pcd_path)
            ply_path = root.glob("*.ply")

            vis = o3d.Visualizer()

            param = o3d.io.read_pinhole_camera_parameters('utils/viewpoint.json')
            vis.create_window(width=800, height=600)

            opt = vis.get_render_option()
            opt.point_size = 2
            # ctr一定要在create window后面
            ctr = vis.get_view_control()
            pointcloud = o3d.PointCloud()
            vis.add_geometry(pointcloud)

            to_reset = True

            for ply in sorted(ply_path):
                pcl = o3d.read_point_cloud(str(ply))
                # pcl.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
                vis.add_geometry(pcl)
                # 视角转换一定要加载add pcl的后面
                ctr.convert_from_pinhole_camera_parameters(param)
                vis.update_geometry()

                if output:
                    screen_path = Path(output) / ply.name
                    screen_path = screen_path.with_suffix(".jpg")
                    print(str(screen_path))
                    vis.capture_screen_image(str(screen_path), do_render=True)

                if to_reset:
                    vis.reset_view_point(True)
                    to_reset = False
                vis.poll_events()
                vis.update_renderer()
                vis.remove_geometry(pcl)
        else:
            pcl = o3d.read_point_cloud(str(pcd_path))
            pcl.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
            o3d.draw_geometries([pcl])

    '''
    image_files: XXXXXX.png (RGB, 24-bit, PNG)
    depth_files: XXXXXX.png (16-bit, PNG)
    poses: camera-to-world, 4×4 matrix in homogeneous coordinates
    用来看单帧一个视角批量产生点云
    '''
    @staticmethod
    def build_single_frame_point_cloud(dataset_path, scale = 100.0):
        plyutils = PLYUtils(max_d=130)
        dataset_folder = Path(dataset_path)

        K = np.fromfile(os.path.join(dataset_path, "K.txt"), dtype=float, sep="\n ").reshape((3, 3))
        image_files = sorted((dataset_folder / "images").glob("*.png"))
        depth_files = sorted((dataset_folder / "depth_maps").glob("*.png"))
        poses = np.eye(4)

        # for i in tqdm(range(0,1)):
        for i in tqdm(range(len(image_files))):
            image_file = str(image_files[i])
            depth_file = str(depth_files[i])

            rgb = cv2.imread(image_file)
            depth = cv2.imread(depth_file, -1).astype(np.uint16)

            height, weight, _ = rgb.shape
            depth = cv2.resize(depth, (weight, height))
            current_points_3D = plyutils.add_depthmap(depth, rgb, scale=scale, intrinsics=K, extrinsics=poses)
            print("point_3d ", current_points_3D.shape)

            save_ply_name = os.path.basename(os.path.splitext(image_files[i])[0]) + ".ply"
            save_ply_path = Path(dataset_path) / "point_clouds"
            # print(str(save_ply_path))
            # print(save_ply_path, save_ply_name)
            if not os.path.exists(str(save_ply_path)):  # 判断是否存在文件夹如果不存在则创建为文件夹
                os.mkdir(save_ply_path)
            PLYUtils.save(str(save_ply_path / save_ply_name), current_points_3D)

    @staticmethod
    def get_point_cloud_bound(image_files, depth_files, seg_files, K, poses, max_d=20, scale=100.0):
        plyutils = PLYUtils(max_d=max_d)

        # for i in tqdm(range(595,700)):
        for i in tqdm(range(len(image_files))):
            image_file = str(image_files[i])
            depth_file = str(depth_files[i])
            seg_file = str(seg_files[i])

            rgb = cv2.imread(image_file)
            depth = cv2.imread(depth_file, -1).astype(np.uint16)
            seg = cv2.imread(seg_file, 0)

            pose = np.concatenate((poses[i], np.array([[0, 0, 0, 1]])), axis=0)

            height, weight, _ = rgb.shape
            depth = cv2.resize(depth, (weight, height))

            assert depth.shape[:2] == rgb.shape[:2], "depthmap and rgb image size mismatch"
            plyutils.add_depthmap(depth, rgb, scale, check_bound=True, seg=seg, intrinsics=K, extrinsics=pose)
        print(plyutils.voxel_bound.T.flatten().tolist())
        return plyutils.voxel_bound.transpose().flatten().tolist()

class VOXELUtils(PLYUtils):
    def __init__(self, leaf_size, max_d, voxel_bound, cls=66):
        super(VOXELUtils, self).__init__()
        self.cls = cls
        self.max_d = max_d
        self.leaf_size = leaf_size
        self.voxel_bound = voxel_bound
        self.voxel_map = np.array([])
        self.x_min, self.y_min, self.z_min = self.voxel_bound[:3]
        self.x_max, self.y_max, self.z_max = self.voxel_bound[3:]

    def voxel_init(self):
        Dx = (self.x_max - self.x_min) // self.leaf_size + 5
        Dy = (self.y_max - self.y_min) // self.leaf_size + 5
        Dz = (self.z_max - self.z_min) // self.leaf_size + 5
        # 注意uint8可能会爆255
        self.voxel_map = np.zeros((int(Dx), int(Dy), int(Dz), self.cls), dtype=np.uint8)
        logger.info("voxel_map shape [{}, {}, {}]".format(Dx, Dy, Dz))

    def add_voxel(self, depth, seg, intrinsic, extrinsic, scale=100):
        position = self.backproject(depth, scale, intrinsic)
        position = np.vstack((position, np.ones(len(position[0]))))
        position = np.dot(extrinsic, position)

        logger.debug("pointcloud numpy array shape {}".format(position.shape))

        depth = np.divide(depth, scale)
        mask = (self.min_d <= depth) & (depth <= self.max_d)
        if self.roi is not None:
            mask[:self.roi[0], :] = False
            mask[self.roi[1]:, :] = False

        if seg is not None:
            mask_seg = np.zeros_like(mask)
            for id in seg_list:
                mask_seg |= (seg == id)

            mask = np.logical_and(mask_seg, mask)

        logger.debug("mask shape {}".format(mask.shape))
        seg = np.ravel(seg)

        points = np.transpose(np.vstack((position[0:3, :], seg)))

        logger.debug("point cloud with cls shape {}".format(points.shape))
        mask = mask.reshape((1, -1)).transpose(1, 0).repeat(4, axis=1)

        points = points[mask].reshape((-1, 4))
        # logger.debug("point cloud info {}".format(points.reshape((-1,4))[0]))

        point_index = (points[:, :3] - np.asarray([[self.x_min, self.y_min, self.z_min]]))
        point_index = np.floor_divide(point_index, self.leaf_size).astype(np.int)

        for idx in range(len(point_index)):
            x, y, z = point_index[idx]
            cls = int(points[idx, 3])
            # if x > 0 and y > 0 and z > 0:
            self.voxel_map[x, y, z, cls] += 1

    def voxel2bev(self, palette):
        virtical_sum = np.sum(self.voxel_map, axis=1)
        bev_map = np.argmax(virtical_sum, axis=2)

        img = np.zeros((bev_map.shape[0], bev_map.shape[1], 3), dtype=np.uint8)

        for label in show_seg_list:
            img[label == bev_map, :] = palette[label]
            # i += 1
        # for label, color in enumerate(palette):
        #     if label != 0:
        #         img[label == bev_map, :] = color
        # img = img[..., ::-1]

        return img

def main():
    K = np.fromfile("test_depth_dataset/kitti04/K.txt", dtype=float, sep="\n ").reshape((3, 3))
    image_files = sorted(Path("test_depth_dataset/kitti04/image_seg").glob("*.jpg"))
    depth_files = sorted(Path("test_depth_dataset/kitti04/depth_maps").glob("*.png"))
    seg_files = sorted(Path("test_depth_dataset/kitti04/segmentation").glob("*.png"))
    # 这里使用pose的真值
    poses = np.loadtxt("test_depth_dataset/kitti04/poses.txt").reshape((-1, 3, 4))

    # 先走一遍确定边界
    logger.info("waiting to initialize the voxel boundry")
    voxel_bound = PLYUtils.get_point_cloud_bound(image_files, depth_files, seg_files, K, poses, max_d=20)

    voxel = VOXELUtils(leaf_size=0.2, max_d=20, voxel_bound=voxel_bound)
    voxel.voxel_init()
    logger.info("voxel map shape : {}".format(voxel.voxel_map.shape))

    logger.info("waiting to generate the voxel map")
    # for idx in tqdm(range(595,700)):
    for idx in tqdm(range(len(poses))):
        image_file = str(image_files[idx])
        depth_file = str(depth_files[idx])
        seg_file = str(seg_files[idx])

        image = cv2.imread(image_file)
        depth = cv2.imread(depth_file, -1).astype(np.uint16)
        seg = cv2.imread(seg_file, 0)

        pose = np.concatenate((poses[idx], np.array([[0, 0, 0, 1]])), axis=0)
        height, weight, _ = image.shape
        depth = cv2.resize(depth, (weight, height))

        voxel.add_voxel(depth, seg, K, pose)
    img = voxel.voxel2bev(PALETTE)
    cv2.imwrite("bev.jpg", img)

    # args = parse_args()
    # PLYUtils.build_concat_cloud("test_depth_dataset/kitti04/", 'test04.ply')
    # PLYUtils.build_single_frame_point_cloud("test_depth_dataset/kitti09")
    # PLYUtils.draw_pointcloud('test_depth_dataset/kitti09/point_clouds', output="test_depth_dataset/kitti09/output")
    # PLYUtils.draw_pointcloud('test04_side.ply')
    # PLYUtils.draw_pointcloud('/data2/kitti/pointcloud/test12.ply')

if __name__ == '__main__':
    main()


import ast
import os
import random
from typing import Dict, List

import openai

from evalplus.data import to_raw
from evalplus.gen import BaseGen
from evalplus.gen.util import trusted_check_exec
from evalplus.gen.util.api_request import create_chatgpt_config, request_chatgpt_engine

class ChatGPTGen(BaseGen):
    def __init__(self, inputs: List, signature: str, contract_code: str, gd_code: str):
        super().__init__(inputs, signature, contract_code)
        self.gd_code = gd_code
        self.prompt_messages = [
            "Please generate complex inputs to test the function.",
            "Please generate corner case inputs to test the function.",
            "Please generate difficult inputs to test the function.",
        ]
        self.iteration = 20
        openai.api_key = os.environ.get("OPENAI_API_KEY", "dummy")

    def seed_selection(self) -> List:
        # get 5 for now.
        return random.sample(self.seed_pool, k=min(len(self.seed_pool), 5))

    @staticmethod
    def _parse_ret(ret: Dict) -> List:
        rets = []
        output = ret["choices"][0]["message"]["content"]
        if "```" in output:
            for x in output.split("```")[1].splitlines():
                if x.strip() == "":
                    continue
                try:
                    # remove comments
                    input = ast.literal_eval(f"[{x.split('#')[0].strip()}]")
                except:  # something wrong.
                    continue
                rets.append(input)
        return rets

    def chatgpt_generate(self, selected_inputs: List) -> List:
        # append the groundtruth function
        # actually it can be any function (maybe we can generate inputs for each llm generated code individually)
        message = f"Here is a function that we want to test:\n```\n{self.gd_code}\n```"
        str_inputs = "\n".join(
            [
                ", ".join([f"'{to_raw(i)}'" if type(i) == str else str(i) for i in x])
                for x in selected_inputs
            ]
        )
        message += f"\nThese are some example inputs used to test the function:\n```\n{str_inputs}\n```"
        message += f"\n{random.choice(self.prompt_messages)}"
        config = create_chatgpt_config(message, 256)
        ret = request_chatgpt_engine(config)
        return self._parse_ret(ret)

    def generate(self, num: int):
        while len(self.new_inputs) < num and self.iteration >= 0:
            seeds = self.seed_selection()
            new_inputs = self.chatgpt_generate(seeds)
            for new_input in new_inputs:
                if hash(str(new_input)) not in self.seed_hash:
                    if trusted_check_exec(self.contract, [new_input], self.entry_point):
                        self.seed_pool.append(new_input)
                        self.seed_hash.add(hash(str(new_input)))
                        self.new_inputs.append(new_input)
            self.iteration -= 1
        return self.new_inputs[:num]


# dp[i][j] 定义为以(i,j)位置为右下角的矩形区域内的苹果数量
# 状态转移方程为:
# dp[i][j] = dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1] + (pizza[i][j]=='A)

# def ways(pizza, k):
#     rows, cols = len(pizza), len(pizza[0])
#     dp = [[0]*cols for _ in range(rows)]
#     for i in range(rows):
#         for j in range(cols):
#             dp[i][j] = (dp[i-1][j] if i>0 else 0) + (dp[i][j-1] if j>0 else 0) - (dp[i-1][j-1] if i>0 and j>0 else 0) + (pizza[i][j]=='A')

#     def dfs(r, c, cuts):
#         if dp[r][c] == 0:
#             return 0
#         if cuts == k-1:
#             return 1
#         result = 0
#         for i in range(r+1, rows):
#             if dp[i][c] > 0:
#                 result += dfs(i, c, cuts+1)
#         for j in range(c+1, cols):
#             if dp[r][j] > 0:
#                 result += dfs(r, j, cuts+1)
#         return result

#     return dfs(0,0,0)

# import functools

# def ways(pizza, k):
#     rows, cols = len(pizza), len(pizza[0])
#     @functools.lru_cache(None)
#     def f(x, y, k):
#         if not k:
#             return any('A' in p[y:cols] for p in pizza[x:rows])
#         res = 0
#         for i in range(x+1, rows):
#             if any('A' in p[y:cols] for p in pizza[x:i]):
#                 res += f(i, y, k-1)
#         for j in range(y+1, cols):
#             if any('A' in p[y:j] for p in pizza[x:rows]):
#                 res += f(x, j, k-1)
#         return res
#     return f(0, 0, k-1) % (10**9+7)

from functools import lru_cache
from itertools import product
def ways(pizza, k):
    m, n = len(pizza), len(pizza[0])

    @lru_cache(None)
    def dfs(k, i=0, j=0, res=0):
        if not (0<=i<m and 0<=j<n): return 0
        for x,y in product(range(i,m), range(j,n)):
            if pizza[x][y] == 'A':
                if not k: return 1
                res += sum(dfs(k-1,X,j) for X in range(x+1,m))
                break
        for y,x in product(range(j,n), range(i,m)):
            if pizza[x][y] == 'A':
                if not k: return 1
                res += sum(dfs(k-1,i,Y) for Y in range(y+1,n))
                break
        return res

    return dfs(k-1) % 1000000007

pizza = ["A..","AAA","..."]
k = 3
print(ways(pizza,k))


from tastypie.resources import ModelResource
from tastypie import fields
from angularize.models import Host, Data
import json
from django.http import HttpResponse
import datetime
import random

class HostResource(ModelResource):
    class Meta:
        queryset = Host.objects.all()
        resource_name = 'hosts'

class DataResource(ModelResource):
    host = fields.ToOneField(HostResource, 'host')

    class Meta:
        queryset = Data.objects.all().order_by('timestamp')
        resource_name = 'data'

    def dehydrate(self, bundle):

        # build up some fake data to output ... base it on the 'limit' asked for
        fake_data = []
        base = datetime.datetime.today()
        fake_data = [{'time': (base - (5 * datetime.timedelta(seconds=x))).isoformat(), 'value': random.randint(1, 101)} for x in range(20)]

        # There is a better way to do this, but its just fake data... I can make it more efficient later if needed
        bundle.data['timestamp'] = datetime.datetime.now().isoformat()
        bundle.data['value'] = random.randint(1, 101)
        return bundle

    # Lets hijack the data for assignment purposes :)
    # We want to simulate real time data, so lets fake it
    def get_list(self, request, **kwargs):
        resp = super(DataResource, self).get_list(request, **kwargs)
        data = json.loads(resp.content)

        # build up some fake data to output ... base it on the 'limit' asked for
        fake_data = []
        base = datetime.datetime.today()
        fake_data = [{'time': (base - (5 * datetime.timedelta(seconds=x))).isoformat(), 'value': random.randint(1, 101)} for x in range(0, data['meta']['limit'])]

        # There is a better way to do this, but its just fake data... I can make it more efficient later if needed
        data['fake'] = list(reversed(fake_data))
        data = json.dumps(data)
        return HttpResponse(data, mimetype='application/json', status=200)


"""
 @author Zhenyu Jiang
 @email stevetod98@gmail.com
 @date 2022-01-12
 @desc Pyrender utils
"""
import os
from turtle import color

os.environ["PYOPENGL_PLATFORM"] = "egl"
import numpy as np
import pyrender
import trimesh

class PyRenderer:
    def __init__(
        self,
        resolution=(640, 480),
        camera_kwargs={"yfov": np.pi / 3.0},
        light_kwargs={"color": np.ones(3), "intensity": 3},
    ):
        """Renderer init function

        Args:
            resolution (tuple, optional): render resolution, . Defaults to (640, 480).
            camera_kwargs (dict, optional): camera properties. Defaults to {'yfov': np.pi/ 3.0}.
            light_kwargs (dict, optional): light properties. Defaults to {'color': np.ones(3), 'intensity': 3}.
        """
        self.renderer = pyrender.OffscreenRenderer(*resolution)
        self.camera = pyrender.PerspectiveCamera(**camera_kwargs)
        self.light = pyrender.SpotLight(**light_kwargs)

    def render_mesh(self, scene_or_mesh, camera_pose, light_pose):
        """render a mesh or a scene

        Args:
            scene_or_mesh (trimesh.Trimesh or trimesh.Scene): the scene or mesh to render
            camera_pose (np.ndarray): camera transformation
            light_pose (np.ndarray): light transformation

        Returns:
            np.ndarray: rendered rgb image
            np.ndarray: rendered depth image
        """
        if isinstance(scene_or_mesh, trimesh.Trimesh):
            scene = trimesh.Scene(scene_or_mesh)
        else:
            scene = scene_or_mesh

        r_scene = pyrender.Scene()
        for mesh in scene.geometry.values():
            o_mesh = pyrender.Mesh.from_trimesh(mesh, smooth=False)
            r_scene.add(o_mesh)
        r_scene.add(self.camera, name="camera", pose=camera_pose)
        r_scene.add(self.light, name="light", pose=light_pose)
        rgb, depth = self.renderer.render(r_scene)
        return rgb, depth

    def render_pointcloud(
        self, xyz, camera_pose, light_pose, radius=0.005, colors=[102, 102, 102, 102]
    ):
        """render a point cloud

        Args:
            xyz (np.ndarray): point cloud to render.
            camera_pose (np.ndarray): camera
            light_pose ([type]): [description]
            radius (float, optional): radius of each ball representing the point. Defaults to 0.005.
            colors (list or np.ndarray, optional): colors of the points. Defaults to [102, 102, 102, 102].

        Returns:
            np.ndarray: rendered rgb image
            np.ndarray: rendered depth image
        """
        r_scene = pyrender.Scene()
        tfs = np.tile(np.eye(4), (len(xyz), 1, 1))
        tfs[:, :3, 3] = xyz
        if colors is None or isinstance(colors, list) or len(colors.shape) == 1:
            # one color for all points
            sm = trimesh.creation.uv_sphere(radius=radius)
            if colors is None:
                sm.visual.vertex_colors = [0.4, 0.4, 0.4, 0.8]
            else:
                sm.visual.vertex_colors = colors
            o_mesh = pyrender.Mesh.from_trimesh(sm, poses=tfs)

            r_scene.add(o_mesh)
        else:
            # different color for different pints
            for idx, tf in enumerate(tfs):
                sm = trimesh.creation.uv_sphere(radius=radius)
                sm.visual.vertex_colors = colors[idx]
                o_mesh = pyrender.Mesh.from_trimesh(sm, poses=tf)
                r_scene.add(o_mesh)

        r_scene.add(self.camera, name="camera", pose=camera_pose)
        r_scene.add(self.light, name="light", pose=light_pose)
        rgb, depth = self.renderer.render(r_scene)
        return rgb, depth


import matplotlib.pyplot as plt
import numpy as np
import random

def makepoint():
    x = random.uniform(0,1)
    y = random.uniform(0,1)
    return np.array([[x,y]])

def dist(p1):
    distance = np.linalg.norm(p1, ord=2)
    return distance

if __name__ == "__main__":
    limit = 1000000
    num = 0
    dem = 0
    points = np.empty((0,2))
    #print(points[:,0],points[:,1])

    for number in range(limit):
        point = makepoint()
        #print(point.shape,point.shape)
        points = np.append(points,point, axis = 0)
        #print(point)
        dem += 1
        #print("test:",num,":",dist(point)<0.0)
        distance = dist(point)
        if(distance<1.0):
            num += 1
        #plt.scatter(points[:,0],points[:,1])
        #plt.xlim(0,1)
        #plt.ylim(0,1)
        #plt.draw()
        #print(num,dem,4*(num/dem))
        #plt.show(block=False)
        #input("Press Enter to continue...")
    print(num,dem,4*(num/dem))


import turtle
import random
t = turtle.Turtle()
r=70
tt= 20
i =1

while i<=50:
    t.right(tt)
    for loop in range(2):
        t.circle(r,90)
        t.circle(r/2,90)
        tt += 1
t.mainloop()


import asyncio
import concurrent.futures
import json
import requests
import os
import sys
import falcon

from functools import partial

# Load Environmental Variables
max_workers = int(os.environ['GET_KEYS_ACCOUNTS_UPSTREAM_WORKERS'])
max_results = int(os.environ['GET_KEYS_ACCOUNTS_LIMIT'])
upstream = os.environ['UPSTREAM_API']

async def get_keys_accounts(public_keys):
    account_cache = {}
    with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as pool:
        loop = asyncio.get_event_loop()
        futures = []
        # Create a future execution of the post request in the futures pool
        for public_key in public_keys:
            futures.append(
                loop.run_in_executor(
                    pool,
                    partial(
                        requests.post,
                        upstream + '/v1/history/get_key_accounts',
                        json={
                            "public_key": public_key
                        }
                    )
                )
            )
        results = {
            'account_names': [],
            'permissions': [],
            'map': {}
        }
        # Await for all processes to complete
        for r in await asyncio.gather(*futures):
            if r.status_code == 200:
                body = json.loads(r.request.body)
                for account_name in r.json()['account_names']:
                    if account_name not in account_cache:
                        sys.stdout.flush()
                        r = requests.post(upstream + '/v1/chain/get_account', json={
                            "account_name": account_name
                        })
                        if r.status_code == 200:
                            account_cache[account_name] = r.json()
                    permissions = account_cache[account_name].get('permissions')
                    for permission in permissions:
                        for key in permission['required_auth']['keys']:
                            if key['key'] == body['public_key']:
                                account_authority = account_name + '@' + permission['perm_name']
                                results['account_names'].append(account_name)
                                results['permissions'].append(account_authority)
                                if body['public_key'] in results['map']:
                                    results['map'][body['public_key']].append(account_authority)
                                else:
                                    results['map'][body['public_key']] = [account_authority]
            pass
        # Return results
        return results

class GetKeysAccounts:
    def on_get(self, req, resp):
        self.on_post(req, resp);
    def on_post(self, req, resp):
        # Process the request to retrieve the account name
        request = json.loads(req.stream.read())
        # Accounts to load
        public_keys = request.get('public_keys')
        # Throw exception if exceeding limit
        requested_public_keys = len(public_keys)
        if requested_public_keys > max_results:
            resp.body = json.dumps({
                "code": 500,
                "message": "Exceeded maximum number of requested accounts per request (requested {}, limit {})".format(requested_accounts, max_results)
            })
        else:
            # Establish session for retrieval
            with requests.Session() as session:
                # Launch async event loop for results
                loop = asyncio.get_event_loop()
                results = loop.run_until_complete(get_keys_accounts(public_keys))
                # Server the response
                resp.body = json.dumps(results)

# Launch falcon API
app = falcon.API()
app.add_route('/v1/history/get_keys_accounts', GetKeysAccounts())


print(2**3)#normal exponential funcion in python i.e raising 2 to the power of 3

#using for loop in solving exponent
def raise_to_power(base_num, pow_num): #naming the exponent function as *raise to power*
    result = 1 #creating a variable naming/assigning it as 1
    for index in range(pow_num): #creating a for loop with a range of the pow_num, i.e if pow_num is 4 it'll loop through 4 times if 3 it"ll loop 3 times etc.
        result = result * base_num
    return result

print(raise_to_power(3,7))


import math
from PIL import Image, ImageDraw
import random
import uuid

# Set the dimensions of the image
width = 3840
height = 3840

run_id = uuid.uuid1()

print(f'Processing run_id: {run_id}')

# Create a blank image with a black background
image = Image.new("RGB", (width, height), "black")
draw = ImageDraw.Draw(image)

# Generate random color palette with colors
def generate_glitch_color():
    r = random.randint(0, 255)
    g = random.randint(0, 255)
    b = random.randint(0, 255)
    return (r, g, b)

# Function to draw the logo
def draw_logo(x, y, size, color):
    outer_circle_radius = size // 2
    inner_circle_radius = outer_circle_radius * 0.8
    line_length = outer_circle_radius * 0.55

    # Draw outer circle
    draw.ellipse([(x - outer_circle_radius, y - outer_circle_radius), (x + outer_circle_radius, y + outer_circle_radius)], fill=color)

    # Draw inner circle
    draw.ellipse([(x - inner_circle_radius, y - inner_circle_radius), (x + inner_circle_radius, y + inner_circle_radius)], fill="black")

    # Draw lines
    num_lines = 8
    angle_increment = 360 / num_lines

    for i in range(num_lines):
        angle = i * angle_increment
        x1 = x + int(line_length * (1 - 0.1) * math.cos(math.radians(angle)))
        y1 = y + int(line_length * (1 - 0.1) * math.sin(math.radians(angle)))
        x2 = x + int(line_length * (1 + 0.2) * math.cos(math.radians(angle)))
        y2 = y + int(line_length * (1 + 0.2) * math.sin(math.radians(angle)))
        draw.line([(x1, y1), (x2, y2)], fill=color, width=3)

# Generate logos randomly with glitch colors
num_logos = 100
logo_size_range = (300, 800)

for _ in range(num_logos):
    x = random.randint(0, width)
    y = random.randint(0, height)
    size = random.randint(logo_size_range[0], logo_size_range[1])
    color = generate_glitch_color()
    draw_logo(x, y, size, color)

# Save the image
image.save(f'{run_id}.png')


# -- coding: utf-8 --
# @File : basepage.py

from appium.webdriver.webdriver import WebDriver
import yaml

class BasePage:
    def __init__(self,driver:WebDriver=None):
        self.driver=driver

    def find_ele(self,by,locator):
        return self.driver.find_element(by,locator)

    def data_driven(self,path,by_method,ele_locator,action=None,send_info=None):
        with open(path,encoding='utf-8') as q:
            datas = yaml.safe_load(q)
        ele = self.find_ele(datas[by_method],datas[ele_locator])
        if datas[action] == 'click':
            ele.click()
        elif datas[action] == 'send':
            ele.send_keys(send_info)
        elif datas[action] == 'text':
            return  ele.text


import random

lst = ["s","w","g"]

def game(rounds):

    comp_point=0
    user_point=0

    print("\n\tWELCOME TO SNAKE, WATER, GUN GAME:\n\t     \"s\" for SNAKE\n\t     \"g\" for GUN\n\t     \"w\" for WATER")

    while (rounds != 0):

        rounds -= 1
        user = input("\nEnter your play: ")
        comp = random.choice(lst)
        print(f"Computer's play: {comp}")

        if (comp == "s" and user == "s") or (comp == "g" and user == "g") or (comp == "w" and user == "w"):
            print("Both played the same move, it's a tie.")

        if (comp == "s" and user == "w") or (comp == "g" and user == "s") or (comp == "w" and user == "g"):
            print("Computer wins the play, 1 point alloted to computer!!")
            comp_point += 1

        if (comp == "w" and user == "s") or (comp == "s" and user == "g") or (comp == "g" and user == "w"):
            print("User wins the play, 1 point alloted to user!!")
            user_point += 1
        print(f"\n\tRounds left: {rounds}\n")

    print(f"Total point of user: {user_point}")
    print(f"Total point of computer: {comp_point}")

    if user_point>comp_point:
        print("\n-----USer wins the most rounds. Congratulations!!-----")

    elif comp_point>user_point:
        print("\n-----Computer wins the most rounds. Better luck next time!!-----")

    elif comp_point == user_point:
        print("\n-----Both of you played very hard game. It's a tie!!-----")

rounds = int(input("Enter the number of rounds you want to play: "))

game(rounds)


class Solution:
    def longestPalindrome(self, s: str) -> str:
        res = ""
        for i in range(len(s)):
            # 以 s[i] 为中心的最长回文子串
            s1 = self.palindrome(s, i, i)
            # 以 s[i] 和 s[i+1] 为中心的最长回文子串
            s2 = self.palindrome(s, i, i + 1)
            # res = longest(res, s1, s2)
            res = res if len(res) > len(s1) else s1
            res = res if len(res) > len(s2) else s2
        return res

    def palindrome(self, s: str, l: int, r: int) -> str:
        # 防止索引越界
        while l >= 0 and r < len(s) and s[l] == s[r]:
            # 向两边展开
            l -= 1
            r += 1
        # 返回以 s[l] 和 s[r] 为中心的最长回文串
        return s[l+1:r]


from heapq import heappop, heappush

def findkthsmallest(nums, k):
	maxHeap = []
	for i in range(k + 1):
		heappush(maxHeap, nums[i])
	for i in range(k + 1, len(nums)):
		if nums[i] > maxHeap[0]:
			heappop(maxHeap)
		# heappush(maxHeap, nums[i])
	return maxHeap[0]

var = [6, 4, 9, 3, 1]
k = 2
print(findkthsmallest(var, k))


# Coder: Wenxin Xu
# Github: https://github.com/wenxinxu/resnet_in_tensorflow
# ==============================================================================
'''
This is the resnet structure
'''
import numpy as np
from hyper_parameters import *

BN_EPSILON = 0.001

def activation_summary(x):
    '''
    :param x: A Tensor
    :return: Add histogram summary and scalar summary of the sparsity of the tensor
    '''
    tensor_name = x.op.name
    tf.summary.histogram(tensor_name + '/activations', x)
    tf.summary.scalar(tensor_name + '/sparsity', tf.nn.zero_fraction(x))

def create_variables(name, shape, initializer=tf.contrib.layers.xavier_initializer(), is_fc_layer=False):
    '''
    :param name: A string. The name of the new variable
    :param shape: A list of dimensions
    :param initializer: User Xavier as default.
    :param is_fc_layer: Want to create fc layer variable? May use different weight_decay for fc
    layers.
    :return: The created variable
    '''

    ## TODO: to allow different weight decay to fully connected layer and conv layer
    regularizer = tf.contrib.layers.l2_regularizer(scale=FLAGS.weight_decay)

    new_variables = tf.get_variable(name, shape=shape, initializer=initializer,
                                    regularizer=regularizer)
    return new_variables

def output_layer(input_layer, num_labels):
    '''
    :param input_layer: 2D tensor
    :param num_labels: int. How many output labels in total? (10 for cifar10 and 100 for cifar100)
    :return: output layer Y = WX + B
    '''
    input_dim = input_layer.get_shape().as_list()[-1]
    fc_w = create_variables(name='fc_weights', shape=[input_dim, num_labels], is_fc_layer=True,
                            initializer=tf.uniform_unit_scaling_initializer(factor=1.0))
    fc_b = create_variables(name='fc_bias', shape=[num_labels], initializer=tf.zeros_initializer())

    fc_h = tf.matmul(input_layer, fc_w) + fc_b
    return fc_h

def batch_normalization_layer(input_layer, dimension):
    '''
    Helper function to do batch normalziation
    :param input_layer: 4D tensor
    :param dimension: input_layer.get_shape().as_list()[-1]. The depth of the 4D tensor
    :return: the 4D tensor after being normalized
    '''
    mean, variance = tf.nn.moments(input_layer, axes=[0, 1, 2])
    beta = tf.get_variable('beta', dimension, tf.float32,
                               initializer=tf.constant_initializer(0.0, tf.float32))
    gamma = tf.get_variable('gamma', dimension, tf.float32,
                                initializer=tf.constant_initializer(1.0, tf.float32))
    bn_layer = tf.nn.batch_normalization(input_layer, mean, variance, beta, gamma, BN_EPSILON)

    return bn_layer

def conv_bn_relu_layer(input_layer, filter_shape, stride):
    '''
    A helper function to conv, batch normalize and relu the input tensor sequentially
    :param input_layer: 4D tensor
    :param filter_shape: list. [filter_height, filter_width, filter_depth, filter_number]
    :param stride: stride size for conv
    :return: 4D tensor. Y = Relu(batch_normalize(conv(X)))
    '''

    out_channel = filter_shape[-1]
    filter = create_variables(name='conv', shape=filter_shape)

    conv_layer = tf.nn.conv2d(input_layer, filter, strides=[1, stride, stride, 1], padding='SAME')
    bn_layer = batch_normalization_layer(conv_layer, out_channel)

    output = tf.nn.relu(bn_layer)
    return output

def bn_relu_conv_layer(input_layer, filter_shape, stride):
    '''
    A helper function to batch normalize, relu and conv the input layer sequentially
    :param input_layer: 4D tensor
    :param filter_shape: list. [filter_height, filter_width, filter_depth, filter_number]
    :param stride: stride size for conv
    :return: 4D tensor. Y = conv(Relu(batch_normalize(X)))
    '''

    in_channel = input_layer.get_shape().as_list()[-1]

    bn_layer = batch_normalization_layer(input_layer, in_channel)
    relu_layer = tf.nn.relu(bn_layer)

    filter = create_variables(name='conv', shape=filter_shape)
    conv_layer = tf.nn.conv2d(relu_layer, filter, strides=[1, stride, stride, 1], padding='SAME')
    return conv_layer

def residual_block(input_layer, output_channel, first_block=False):
    '''
    Defines a residual block in ResNet
    :param input_layer: 4D tensor
    :param output_channel: int. return_tensor.get_shape().as_list()[-1] = output_channel
    :param first_block: if this is the first residual block of the whole network
    :return: 4D tensor.
    '''
    input_channel = input_layer.get_shape().as_list()[-1]

    # When it's time to "shrink" the image size, we use stride = 2
    if input_channel * 2 == output_channel:
        increase_dim = True
        stride = 2
    elif input_channel == output_channel:
        increase_dim = False
        stride = 1
    else:
        raise ValueError('Output and input channel does not match in residual blocks!!!')

    # The first conv layer of the first residual block does not need to be normalized and relu-ed.
    with tf.variable_scope('conv1_in_block'):
        if first_block:
            filter = create_variables(name='conv', shape=[3, 3, input_channel, output_channel])
            conv1 = tf.nn.conv2d(input_layer, filter=filter, strides=[1, 1, 1, 1], padding='SAME')
        else:
            conv1 = bn_relu_conv_layer(input_layer, [3, 3, input_channel, output_channel], stride)

    with tf.variable_scope('conv2_in_block'):
        conv2 = bn_relu_conv_layer(conv1, [3, 3, output_channel, output_channel], 1)

    # When the channels of input layer and conv2 does not match, we add zero pads to increase the
    #  depth of input layers
    if increase_dim is True:
        pooled_input = tf.nn.avg_pool(input_layer, ksize=[1, 2, 2, 1],
                                      strides=[1, 2, 2, 1], padding='VALID')
        padded_input = tf.pad(pooled_input, [[0, 0], [0, 0], [0, 0], [input_channel // 2,
                                                                     input_channel // 2]])
    else:
        padded_input = input_layer

    output = conv2 + padded_input
    return output

def inference(input_tensor_batch, n, reuse):
    '''
    The main function that defines the ResNet. total layers = 1 + 2n + 2n + 2n +1 = 6n + 2
    :param input_tensor_batch: 4D tensor
    :param n: num_residual_blocks
    :param reuse: To build train graph, reuse=False. To build validation graph and share weights
    with train graph, resue=True
    :return: last layer in the network. Not softmax-ed
    '''

    layers = []
    with tf.variable_scope('conv0', reuse=reuse):
        conv0 = conv_bn_relu_layer(input_tensor_batch, [3, 3, 3, 16], 1)
        activation_summary(conv0)
        layers.append(conv0)

    for i in range(n):
        with tf.variable_scope('conv1_%d' %i, reuse=reuse):
            if i == 0:
                conv1 = residual_block(layers[-1], 16, first_block=True)
            else:
                conv1 = residual_block(layers[-1], 16)
            activation_summary(conv1)
            layers.append(conv1)

    for i in range(n):
        with tf.variable_scope('conv2_%d' %i, reuse=reuse):
            conv2 = residual_block(layers[-1], 32)
            activation_summary(conv2)
            layers.append(conv2)

    for i in range(n):
        with tf.variable_scope('conv3_%d' %i, reuse=reuse):
            conv3 = residual_block(layers[-1], 64)
            layers.append(conv3)
        assert conv3.get_shape().as_list()[1:] == [8, 8, 64]

    with tf.variable_scope('fc', reuse=reuse):
        in_channel = layers[-1].get_shape().as_list()[-1]
        bn_layer = batch_normalization_layer(layers[-1], in_channel)
        relu_layer = tf.nn.relu(bn_layer)
        global_pool = tf.reduce_mean(relu_layer, [1, 2])

        assert global_pool.get_shape().as_list()[-1:] == [64]
        output = output_layer(global_pool, 10)
        layers.append(output)

    return layers[-1]

def test_graph(train_dir='logs'):
    '''
    Run this function to look at the graph structure on tensorboard. A fast way!
    :param train_dir:
    '''
    input_tensor = tf.constant(np.ones([128, 32, 32, 3]), dtype=tf.float32)
    result = inference(input_tensor, 2, reuse=False)
    init = tf.initialize_all_variables()
    sess = tf.Session()
    sess.run(init)
    summary_writer = tf.train.SummaryWriter(train_dir, sess.graph)


from collections import deque
# this is the big file of things i should just remember

# Quicksort:
def quicksort(arr, s, e):
    if (e-s +1) <= 1:
        return
    pivot = arr[e]
    left = s
    for i in range(s, e):
        if(arr[i] <= pivot):
            #Swap with left
            arr[i], arr[left]  = arr[left], arr[i]
            left+= 1
    #Swap pivot with the middle
    arr[e] , arr[left] = arr[left], arr[e]
    quicksort(arr, s, left-1) # the middle one is alredy in order
    quicksort(arr, left+1, e)
    return arr

# Binary Search:
def binarySearch(a, target):
    left, right  = 0, len(a)-1
    while left<= right:
        mid = (left+right)//2
        if target > a[mid] : left = mid+1
        elif target < a[mid] : right = mid-1
        else: return mid
    return -1

# Binary search generalized for minimalizing X such that f(x) is the minimum
def binary_search(array) -> int:
    def condition(value) -> bool:
        pass
    left, right = 0, len(array)
    while left < right:
        mid = left + ((right - left)>>1)
        if condition(mid):
            right = mid
        else:
            left = mid + 1
    return left

# BSF:
def bfs(root):
    queue = deque()

    if root:
        queue.append(root)

    level = 0
    while len(queue) > 0:
        print("level: ", level)
        for i in range(len(queue)):
            curr = queue.popleft()
            print(curr.val)
            if curr.left:
                queue.append(curr.left)
            if curr.right:
                queue.append(curr.right)
        level += 1

# DSF:
    def dfs(root):
        if not root:
            return
        # stop condition
        # early killswitches
        dfs(root.left)
        dfs(root.right)

def binary_search(array) -> int:
    def condition(value) -> bool:
        pass
    left, right = 0, len(array)
    while left < right:
        mid = left + ((right - left)>>1)
        if condition(mid):
            right = mid
        else:
            left = mid + 1
    return left

# generalized algorithm is for finding minimum number k in a search space such that a condition holds
# apply when some form of monotonicity is found within the search space.

# left is the minimun number s.t condition = true.
# left-1 is the maximun number s.t condition = false.

#Union Find

class UnionFind:
    def __init__(self, n):
        self.parents = {}
        self.rank = {}
        #graphs with node marked 1 to n
        for i in ranger(1, n+1):
            self.parents[i] = i
            self.rank[i] = 0

    def find(self, n):
        par = self.parents[n]
        while par != self.parents[par]:
            #path compression
            self.parents[par] = self.parents[self.parents[par]]
            par = self.parents[par]
        return par

    def union(self, n, m):
        p1, p2 = self.find(n), self.find(m)

        if p1 == p2: return False

        if self.rank[p1] > self.rank[p2]:
            self.parents[p2] = p1
        elif self.rank[p2] > self.rank[p1]:
            self.parents[p1] = p2
        else:
            self.parents[p1] = p2
            self.rank[p2] += 1
        return True

# Kruskal's -> minimun spannign tree
    # joga tudo num minheap
    # vai tirando do heap até que arestas = nodos-1
    # se union(i,j) == false continue
    # se nao poe na msp

# Kadane:
    cur = max(cur+n, n)
    max =max(cur, max)


#import random module to shuffle the deck

import random

#define global variables to call on when creating classes

suits = ('Hearts', 'Diamonds', 'Spades', 'Clubs')
ranks = ('Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Jack', 'Queen', 'King', 'Ace')
values = {'Two':2, 'Three':3, 'Four':4, 'Five':5, 'Six':6, 'Seven':7, 'Eight':8, 'Nine':9, 'Ten':10, 'Jack':10,
         'Queen':10, 'King':10, 'Ace':11}

#set a playing variable equal to true in order to use while loops to control the game

playing = True

class Card:

    #each card object takes in a suit and rank attribute

    def __init__(self,suit,rank):
        self.suit = suit
        self.rank = rank

    #add a string method that returns rank and suit when asked to print a card

    def __str__(self):
        return self.rank + " of "+ self.suit

class Deck:

    #To create the deck class start with an empty list, then
    #iterate through each suit and rank and append it to the list

    def __init__(self):
        self.deck = []
        for suit in suits:
            for rank in ranks:
                self.deck.append(Card(suit,rank))

    def __str__(self):
        deck_comp = ''
        for card in self.deck:
            deck_comp += '\n'+card.__str__()
        return "The deck has: "+deck_comp

    #create a shuffle method by randomizing the order of the deck list

    def shuffle(self):
        random.shuffle(self.deck)

    #create a deal method by using pop to remove the last item in the deck list
    #and have the popped item exist as a single_card variable for later use

    def deal(self):
        single_card = self.deck.pop()
        return single_card

#start with an empty list to create a hand class
#create attributes to keep track of the value of a hand and to

class Hand:
    def __init__(self):
        self.cards = []
        self.value = 0
        self.aces = 0

    def add_card(self,card):
        self.cards.append(card)
        self.value += values[card.rank]

        if card.rank == 'Ace':
            self.aces += 1

    #to adjust for aces check if the value of a hand is greater than 21 and if aces exist in the hand
    #then reduce the hand value by 10 (aces = 11 or 1) and the ace counter by 1

    def adjust_for_ace(self):

        while self.value > 21 and self.aces:
            self.value -= 10
            self.aces -= 1

#A chip class keeps track of the player and dealer chips using counter variables
#self.total is set equal to the number of chips each player starts with

class Chips:
    def __init__(self):
        self.total = 100
        self.bet = 0
    def win_bet(self):
        self.total += self.bet
    def lose_bet(self):
        self.total -= self.bet

#create a take_bet function to ask the player how much they would like to bet
#use try and accept blocks to make sure the bet is an integer and the player has enough chips

def take_bet(chips):

    #use a while loop to continue prompting the player in the case of an invalid input

    while True:

        try:
            chips.bet = int(input("How much would you like to bet? "))
        except:
            print("please use an integer")
        else:
            if chips.bet > chips.total:
                print('you only have {}'.format(chips.total))
            else:
                break

#define a hit function to take a card from the deck and add it to a players hand
#make sure to run the ace adjustment function

def hit(deck,hand):

    single_card = deck.deal()
    hand.add_card(single_card)
    hand.adjust_for_ace()

def hit_or_stand(deck,hand):

    #use a while loop again to continue hitting until the player wants to stand

    global playing

    while True:
        x = input('Hit or Stand? Enter h or s ')

        if x[0].lower() == 'h':
            hit(deck,hand)

        elif x[0].lower() == 's':
            print("Player Stands, Dealer's Turn")
            playing = False

        else:
            print("Sorry, I do not understand")
            continue

        break

#create two functions to show all or a partial amount of cards to the player

def show_some(player,dealer):

#show only 1 of the dealers cards, show all (2) of the players cards

    print("\n Dealer's Hand: ")
    print("Hidden Card")
    print(dealer.cards[1])
    print("\n Player Hand")
    for card in player.cards:
        print(card)

def show_all(player,dealer):
#show all dealer and player cards and display values

    print("\n Dealer's Hand")
    for card in dealer.cards:
        print(card)
    print(f"Dealer Value: {dealer.value}")

    print("\n Player Hand")
    for card in player.cards:
        print(card)
    print(f"Value of Player's Hand is: {player.value}")

#create a series of functions to account for all potential outcomes of each game
#then adjust the chips accordingly

def player_busts(player,dealer,chips):
    print("Player Busts")
    chips.lose_bet()

def player_wins(player,dealer,chips):
    print("Player Wins")
    chips.win_bet()

def dealer_busts(player,dealer,chips):
    print("Dealer Busts, Player Wins")
    chips.win_bet()

def dealer_wins(player,dealer,chips):
    print("Dealer Wins")
    chips.lose_bet()

def push(player,dealer):
    print("Push")

while True:

    print("Let the Games Begin!")

    #create the deck list and then shuffle the list

    deck = Deck()
    deck.shuffle()

    #create a hand for the dealer and the player
    #deal 2 cards to each

    player_hand = Hand()
    player_hand.add_card(deck.deal())
    player_hand.add_card(deck.deal())

    dealer_hand = Hand()
    dealer_hand.add_card(deck.deal())
    dealer_hand.add_card(deck.deal())

    #set up players chips

    player_chips = Chips()

    #ask player for their bet

    take_bet(player_chips)

    #use show_some to show the player's cards but keep the dealer's cards hidden

    show_some(player_hand,dealer_hand)

    while playing:

        #Ask player to hit or stand now that they have a hand and placed a bet

        hit_or_stand(deck,player_hand)

        #show some to keep one dealer card hidden

        show_some(player_hand,dealer_hand)

        #if the player hand exceeds 21 break out of the loop and run player busts

        if player_hand.value > 21:
            player_busts(player_hand,dealer_hand,player_chips)

            break

    #if player does not bust, dealer keeps hitting until their hand is exceeds 17

    if player_hand.value <= 21:

        while dealer_hand.value < 17:
            hit(deck,dealer_hand)

        #when player and dealer are done hitting, show all cards

        show_all(player_hand,dealer_hand)

        #run through potential outcomes of the game

        if dealer_hand.value > 21:
            dealer_busts(player_hand,dealer_hand,player_chips)

        elif dealer_hand.value > player_hand.value:
            dealer_wins(player_hand,dealer_hand,player_chips)
        elif dealer_hand.value < player_hand.value:
            player_wins(player_hand,dealer_hand,player_chips)
        else:
            push(player_hand,dealer_hand)

        #tell the player how many chips they have left and ask if they want to continue

        print(f'\n Player has {player_chips.total} chips')

        new_game = input("Would you like to play again? y/n")

        if new_game[0].lower() == 'y':
            playing = True
            continue
        else:
            print("Game Over")
            break


import logging
import os

import ujson as json

from table_augmentation.cell_filling.utils import HOME, normalize_entity, process_table, fill_from_args_
from util.line_corpus import write_open

logger = logging.getLogger(__name__)

class Options:
    def __init__(self):
        # inputs
        self.table_dir = os.path.join(HOME, "data/WP_table/tables_redi2_1")
        self.test_query_gt = os.path.join(HOME, "codes/cikm2019-table/data/qrel/gt_all_norm.tsv")
        self.test_query_table = os.path.join(HOME, "codes/cikm2019-table/query/query_table.txt")
        # outputs
        self.output_path = os.path.join(HOME, "data/cell_filling/dpr/queries/test_tables.jsonl.gz")
        # filtering options
        self.max_char_title = 100
        self.max_char_cell = 50

def main(opts: Options):
    query_table = {}
    with open(opts.test_query_table) as f:
        for line in f:
            line = line.strip().split()
            query_table[line[0]] = [int(line[1]), int(line[2]), ]

    test_tables = []
    with open(opts.test_query_gt) as f:
        for line in f:
            table_row_id, _, answer, _ = line.strip().split()
            row_id = int(table_row_id.split("-")[-1])
            table_id = "-".join(table_row_id.split("-")[:-1])
            col_id = query_table[table_id][1]
            answer = normalize_entity(answer)
            if len(test_tables) == 0 or test_tables[-1]['table_id'] != table_id:
                test_tables.append(dict(table_id=table_id, answers=[]))
            if len(test_tables[-1]["answers"]) == 0 or test_tables[-1]["answers"][-1][0] != row_id:
                test_tables[-1]["answers"].append([row_id, col_id, [], ])
            test_tables[-1]["answers"][-1][-1].append(answer)
    test_tables = sorted(test_tables, key=lambda x: x['table_id'])

    # CONSIDER: track the max cell length in test, max title length - use it to filter train tables
    truncated_title_count = 0
    total_title_count = 0

    last_tables = None
    last_table_fn = None
    with write_open(opts.output_path) as out_q:
        for test_table in test_tables:
            table_id = test_table['table_id']
            table_fn = table_id.split("-")[1]
            if table_fn != last_table_fn:
                with open(os.path.join(opts.table_dir, "re_tables-{}.json".format(table_fn))) as f:
                    tables = json.load(f)
                last_table_fn = table_fn
                last_tables = tables
            else:
                tables = last_tables

            train_table = process_table(table_id, tables[table_id], opts)
            full_title = train_table["title"]
            if len(full_title) > opts.max_char_title:
                truncated_title_count += 1
            total_title_count += 1

            # format passages separately for row-population and col-population
            train_table['answers'] = test_table['answers']
            out_q.write(json.dumps(train_table) + '\n')

    print(f'Truncated title count = {truncated_title_count} out of {total_title_count}')

if __name__ == "__main__":
    opts = Options()
    fill_from_args_(opts)
    main(opts)


import torch

__all__ = ["log_sum_exp", "log_sum_exp_elem"]

def log_sum_exp(tensor: torch.Tensor, dim: int, keepdim: bool = False):
    bias = tensor.max(dim=dim, keepdim=True)[0].detach()
    ans = bias + (tensor - bias).exp().sum(dim=dim, keepdim=True).log()
    if keepdim:
        return ans
    else:
        return ans.squeeze(dim=dim)

def log_sum_exp_elem(*a):
    """
    :param a: elements
    :return: (a[0].exp() + a[1].exp() + ...).log()
    """
    bias = max(a).detach()
    ans = bias + sum([(ai-bias).exp() for ai in a]).log()
    return ans


import pandas as pd
import numpy as np
import matplotlib.pyplot as pyplot
from random import randint
from random import random
import math
import seaborn as sns

np.random.seed(60)

# offenisve and defensive rolls, always sorted in ascending order

offensiveRoll = np.sort(np.floor(6*np.random.random(size = 3)+1))
defensiveRoll = np.sort(np.floor(6*np.random.random(size = 2)+1))

# number of deaths for offensive and defensive players

deathTally = np.array([0,0])

# roll function. input death tally, roll, and update death tally

def roll(offUnits, defUnits, offRollNum = 3, defRollNum = 2):

	offRoll = np.sort(np.floor(6*np.random.random(size = offRollNum)+1))
	defRoll = np.sort(np.floor(6*np.random.random(size = defRollNum)+1))
	offRemainingDie = offRollNum
	defRemainingDie = defRollNum
	print('roll is ' + str(offRoll) + str(defRoll))
	i =0
	while (offRemainingDie > 0) & (defRemainingDie > 0):

		if offRoll[offRemainingDie-1] > defRoll[defRemainingDie-1]:
			deathTally[1] += 1
			defUnits -= 1
			offRemainingDie -= 1
			defRemainingDie -= 1
			"""print('death tally is ' + str(deathTally))
			print('remaining die are ' + str([offRemainingDie,defRemainingDie]))
			print('remaining units are ' + str([offUnits,defUnits]))"""
		else:
			deathTally[0] += 1
			offUnits -= 1
			defRemainingDie -= 1
			offRemainingDie -= 1
			"""print('death tally is ' + str(deathTally))
			print('remaining die are ' + str([offRemainingDie,defRemainingDie]))
			print('remaining units are ' + str([offUnits,defUnits]))"""
	return [offUnits,defUnits]

# define the map state and structure
ColoursInGame = ['Red','Blue']

mapState = pd.DataFrame(columns = ['Controlled By','Number of Armies',],index = ['territory1','territory2','territory3'])
mapStructure = pd.DataFrame(columns = ['territory1','territory2','territory3'],index = ['territory1','territory2','territory3'])

mapState['Controlled By'] = ['Red','Blue','Blue']
mapState['Number of Armies'] = [10,6,6]

# dictionary defining the map structure, territory:list of neighbours

mapDict = {'territory1':[1,1,1],'territory2':[1,1,0],'territory3':[1,0,1]}

# defines the map in a data frame. Warning, for visualization purposes only...use dictionary in code

mapStructure['territory1'] = [1,1,1]
mapStructure['territory2'] = [1,1,0]
mapStructure['territory3'] = [1,0,1]

# battle functions. input tuples, country attacking and country being attacked.
# roll strategy to go in the while conditional

def Battle(offensive,defensive,attackTerr,defendTerr):

	offUnits = mapState['Number of Armies'][attackTerr]
	defUnits = mapState['Number of Armies'][defendTerr]

	while((offUnits > 1) & (defUnits >0)):
		offRollNum = min(offUnits -1, 3)
		defRollNum = min(defUnits,2)
		offUnits,defUnits = roll(offUnits,defUnits,offRollNum,defRollNum)

	# move units step

	if defUnits > 0:
		mapState.loc[mapState.index == attackTerr, 'Number of Armies'] = offUnits
		mapState.loc[mapState.index == defendTerr, 'Number of Armies'] = defUnits
		print('No units moved')
	else:
		mapState.loc[mapState.index == attackTerr, 'Number of Armies'] = min(2,offUnits-1)
		mapState.loc[mapState.index == defendTerr, 'Number of Armies'] = max(offUnits-2, 1)
		mapState.loc[mapState.index == defendTerr, 'Controlled By'] = offensive
		print(str(max(offUnits-2, 1)) + ' units moved from ' + attackTerr + ' to ' + defendTerr)

	print(mapState)
	return mapState

#print(Battle('Red','Blue','territory1','territory2'))

# a dictionary defining the neighbours

neighbours = {'territory1':['territory2','territory3'], 'territory2':['territory1'], 'territory3':['territory1']}

# returns a list of potential territories to attack, and from which controlled territory, should include a ranking of potential attacks

def PotentialAttacks(color):
	results = []
	for index,info in mapState.iterrows():
		if info[0] == color:
			currentNeighbours = neighbours[index]
			hostileBorders =[(index,neighbour) for neighbour in currentNeighbours if mapState.loc[neighbour][0] != color]
			results=results + hostileBorders
	return results

# a color chooses whether or not to attack a hostile neighbour in the list of potential attacks
def Turn(color):
	print(color + ' turn:')

	for attackTerr,defendTerr in PotentialAttacks(color):
		print(PotentialAttacks(color))
		if color == mapState['Controlled By'][defendTerr]:
					break
		if mapState['Number of Armies'][attackTerr] > 1:
			if (mapState['Number of Armies'][attackTerr] >= mapState['Number of Armies'][defendTerr]):
						print(color + ' attacks ' + mapState['Controlled By'][defendTerr] + ' from ' + attackTerr + ' to ' + defendTerr)
						Battle(color, mapState['Controlled By'][defendTerr], attackTerr, defendTerr)
	EliminationCheck()
def EliminationCheck():
	for color in ColoursInGame:
		if sum(mapState.loc[mapState['Controlled By'] == color,'Number of Armies']) == 0:
			print(color + ' has been eliminated')
			ColoursInGame.remove(color)
		if len(ColoursInGame) == 1:
			print('Game over: Winner is ' + ColoursInGame[0])
			return True
numberOfRounds = 3

for i in range(numberOfRounds):
	if EliminationCheck() == True:
		break
	Turn('Red')
	if EliminationCheck() == True:
		break
	Turn('Blue')


from docx import Document
from pathlib import Path
import datetime

today = datetime.date.today()
next_week = today + datetime.timedelta(days=7)
formatted_next_week = next_week.strftime("%b %d %Y")

player_name_list = []
player_name = ''
while player_name != "conf_exit":
    player_name = input('Enter the player name (type "conf_exit" if there are no more names): ')
    if player_name != "conf_exit":
        player_name_list.append(player_name)

for player in player_name_list:
    document_load_path = Path(__file__).parent / "Team_Fidelity_Offer_Letter_Template.docx"
    document = Document(document_load_path)
    document_save_path = Path(__file__).parent / f"Team_Fidelity_Offer_Letter_{player}.docx"
    for paragraph in document.paragraphs:
        if '<player_name>' in paragraph.text:
            paragraph.text = f"Dear {player}"
        if '<response_date>' in paragraph.text:
            paragraph.text = f"We would like to have your response by {formatted_next_week} 11:59pm EST. In the meantime, please feel free to contact anyone on the Administrator team by tagging anyone with the Administrator role should you have any questions."
    document.save(document_save_path)

print("Acceptance letter(s) created")


import os
from flask import Flask, render_template, render_template_string, Markup, request, redirect, url_for, session, make_response
from flask_flatpages import FlatPages
from flask_flatpages.utils import pygmented_markdown
from contactform import ContactForm
from flask_wtf.csrf import CsrfProtect
from flask_mail import Message, Mail
#from werkzeug.contrib.atom import AtomFeed

app = Flask(__name__)

app.secret_key = os.urandom(36)

app.config.from_object(__name__)

CsrfProtect(app)

# email server
app.config["MAIL_SERVER"] = "smtp.gmail.com"
app.config["MAIL_PORT"] = 465
app.config["MAIL_USE_SSL"] = True
app.config["MAIL_USERNAME"] = os.environ.get('MAIL_USERNAME')
app.config["MAIL_PASSWORD"] = os.environ.get('MAIL_PASSWORD')

mail=Mail(app)

HOSTING_DOMAIN = "https://maipatana.me"

#  ------------------------ Markdown Content System Management ------------------------ #
                                                                                #
                                                                                #
#DEBUG = True
#FLATPAGES_AUTO_RELOAD = DEBUG
per_page = 5
POSTS_DIR = 'blogs'

def pagenum(totalposts, postperpage):
    pages = [1]
    num = 2
    while totalposts > postperpage:
        pages.append(num)
        totalposts -= postperpage
        num += 1
    return pages

# # Take Jinja
# def prerender_jinja(text):
#     return pygmented_markdown(render_template_string(Markup(text)))

def my_renderer(text):
    prerendered_body = render_template_string(text)
    return pygmented_markdown(prerendered_body)

app.config['FLATPAGES_ROOT'] = 'content'
app.config['FLATPAGES_EXTENSION'] = '.md'
app.config['FLATPAGES_HTML_RENDERER'] = my_renderer

flatpages = FlatPages(app)
#  ------------------------ Markdown Content System Management ------------------------ #

#  -------------------------------------- Blogs ----------------------------------------#
                                                                                #
                                                                                #
@app.route('/blogs/', defaults={'page': 1})
@app.route("/blogs/page/<int:page>/")
def posts(page):
    cat = 'blogs'
    posts = [p for p in flatpages if p.path.startswith(POSTS_DIR) and cat in p.meta.get('cats', [])]
    posts.sort(key=lambda item:item['date'], reverse=True)
    total = len(posts)
    pages = pagenum(total, per_page)
    posts = posts[(page*per_page)-per_page:page*per_page]
    return render_template('posts.html', posts=posts, page=page, pages=pages, cat=cat)

@app.route('/blogs/<name>/')
def post(name):
    path = u'{}/{}'.format(POSTS_DIR, name)
    post = flatpages.get_or_404(path)
    return render_template('post.html', post=post)

@app.route('/tags/<string:tag>/', defaults={'page': 1})
@app.route('/tags/<string:tag>/page/<int:page>/')
def tags(tag, page):
    posts = [p for p in flatpages if tag in p.meta.get('tags', [])]
    posts.sort(key=lambda item:item['date'], reverse=True)
    total = len(posts)
    pages = pagenum(total, per_page)
    posts = posts[(page*per_page)-per_page:page*per_page]
    return render_template('posts.html', posts=posts, tag=tag, page=page, pages=pages)

#  ------------------------------------ Tutorials --------------------------------------#
                                                                                #
                                                                                #
@app.route('/tutorials/', defaults={'page': 1})
@app.route("/tutorials/page/<int:page>/")
def tutorials(page):
    cat = 'tutorials'
    posts = [p for p in flatpages if p.path.startswith(POSTS_DIR) and cat in p.meta.get('cats', [])]
    posts.sort(key=lambda item:item['date'], reverse=True)
    total = len(posts)
    pages = pagenum(total, per_page)
    posts = posts[(page*per_page)-per_page:page*per_page]
    return render_template('tutorials.html', posts=posts, page=page, pages=pages, cat=cat)

@app.route('/tutorials/<name>/')
def tutorial(name):
    path = u'{}/{}'.format(POSTS_DIR, name)
    post = flatpages.get_or_404(path)
    return render_template('post.html', post=post)

#  ------------------------------------ Projects ---------------------------------------#
                                                                                #
                                                                                #
@app.route('/projects/', defaults={'page': 1})
@app.route("/projects/page/<int:page>/")
def projects(page):
    cat = 'projects'
    posts = [p for p in flatpages if p.path.startswith(POSTS_DIR) and cat in p.meta.get('cats', [])]
    posts.sort(key=lambda item:item['date'], reverse=True)
    total = len(posts)
    pages = pagenum(total, per_page)
    posts = posts[(page*per_page)-per_page:page*per_page]
    return render_template('projects.html', posts=posts, page=page, pages=pages, cat=cat)

@app.route(u'/projects/<name>/')
def project(name):
    path = u'{}/{}'.format(POSTS_DIR, name)
    post = flatpages.get_or_404(path)
    return render_template('post.html', post=post)

#  ---------------------------- Redirect from old urls----------------------------------#
                                                                                #
                                                                                #
@app.route(u'/<name>/')
def redirectfromoldurls(name):
    path = u'{}/{}'.format(POSTS_DIR, name)
    post = flatpages.get_or_404(path)
    if "tutorials" in post.meta.get('cats',[]):
        return redirect(url_for('tutorial',name=name), code=301)
    return redirect(url_for('post', name=name), code=301)

#  ------------------------------------ About Me ---------------------------------------#
                                                                                #
                                                                                #
@app.route('/aboutme/')
def aboutme():
    # Contact Message
    form = ContactForm(request.form)
    if 'name' in session:
        name = session['name']
    else:
        name = []
    if request.method == 'POST' and form.validate():
        email = form.email.data.lower()
        name = form.name.data
        message = form.message.data
        subject = form.subject.data
        msg = Message('[maipatana]'+subject,
                      sender=email, recipients= ['maipatana@gmail.com'])
        msg.body = """
        From: %s Email: %s
        %s
        """ % (name, email, message)
        mail.send(msg)
        session['name'] = name
        return redirect(url_for('home'))
    return render_template('aboutme.html', form=form, name=name)

#  -------------------------------------- Home -----------------------------------------#
                                                                                #
                                                                                #
@app.route('/', methods=['GET', 'POST'])
def home():
    # Recent Posts
    tags = [tag for p in flatpages if p.path.startswith(POSTS_DIR) for tag in p.meta.get('tags', []) ]
    blogs = [p for p in flatpages if p.path.startswith(POSTS_DIR) and 'blogs' in p.meta.get('cats', [])]
    blogs.sort(key=lambda item:item['date'], reverse=True)
    projects = [p for p in flatpages if p.path.startswith(POSTS_DIR) and 'projects' in p.meta.get('cats', [])]
    projects.sort(key=lambda item:item['date'], reverse=True)
    energy = [p for p in flatpages if p.path.startswith(POSTS_DIR) and 'tutorials' in p.meta.get('cats', [])
              and 'energy' in p.meta.get('tags', [])]
    energy.sort(key=lambda item:item['date'], reverse=True)
    ottv = [p for p in flatpages if p.path.startswith(POSTS_DIR) and 'tutorials' in p.meta.get('cats', [])
              and 'ottv' in p.meta.get('tags', [])]
    ottv.sort(key=lambda item:item['date'], reverse=False)
    simulation = [p for p in flatpages if p.path.startswith(POSTS_DIR) and 'tutorials' in p.meta.get('cats', [])
              and 'simulation' in p.meta.get('tags', [])]
    simulation.sort(key=lambda item:item['date'], reverse=False)
    grasshopper = [p for p in flatpages if p.path.startswith(POSTS_DIR) and 'tutorials' in p.meta.get('cats', [])
                   and 'grasshopper' in p.meta.get('tags', [])]
    grasshopper.sort(key=lambda item:item['date'], reverse=True)
    python = [p for p in flatpages if p.path.startswith(POSTS_DIR) and 'tutorials' in p.meta.get('cats', [])
              and 'python' in p.meta.get('tags', [])]
    python.sort(key=lambda item:item['date'], reverse=True)
    basicpy = [p for p in flatpages if p.path.startswith(POSTS_DIR) and 'tutorials' in p.meta.get('cats', [])
              and 'basic python' in p.meta.get('tags', [])]
    basicpy.sort(key=lambda item:item['date'], reverse=False)

    # Contact Message
    form = ContactForm(request.form)
    if 'name' in session:
        name = session['name']
    else:
        name = []
    if request.method == 'POST' and form.validate():
        email = form.email.data.lower()
        name = form.name.data
        message = form.message.data
        subject = form.subject.data
        msg = Message('[maipatana]'+subject,
                      sender=email, recipients= ['maipatana@gmail.com'])
        msg.body = """
        From: %s Email: %s
        %s
        """ % (name, email, message)
        mail.send(msg)
        session['name'] = name
        return redirect(url_for('home'))
    # Render
    return render_template('home.html', blogs=blogs[:5], ottv=ottv[:5], projects=projects[:5], simulation=simulation[:5], basicpy=basicpy[:10],
                           energy=energy[:5], grasshopper=grasshopper[:5], python=python[:5], form=form, name=name, tags=set(tags))
#  ----------------------------------- End Home ----------------------------------------#

# Logout
@app.route('/logout/')
def logout():
    # remove the username from the session if it's there
    session.pop('name', None)
    return redirect(url_for('home'))

#  -------------------------------- Error Handling -------------------------------------#
@app.errorhandler(404)
def page_not_found(e):
    tags = [tag for p in flatpages if p.path.startswith(POSTS_DIR) for tag in p.meta.get('tags', []) ]
    return render_template("404.html", tags=set(tags))

@app.errorhandler(405)
def methodnotfound(e):
    return render_template("405.html", error='')

@app.errorhandler(500)
def internalerror(e):
    return render_template("500.html", error='')

#  ---------------------------- Sitemap Robot -------------------------------------#
@app.route('/sitemap.xml')
def generate_sitemap():
    posts = [p for p in flatpages if p.path.startswith(POSTS_DIR)]
    sitemap =  render_template("sitemap.xml", posts=posts)
    response= make_response(sitemap)
    response.headers["Content-Type"] = "application/xml"
    return response

@app.route('/robot.txt')
def robot():
    return ("""
    User-agent: *
    Disallow: /logout/
    Allow: /
    Sitemap: https://maipatana.me/sitemap.xml
    """)

# Run App
if __name__ == "__main__":
    app.run()


import pandas as pd
df=pd.read_excel("car.xlsx")
x=df[["Volume", "Weight"]]
y=df["CO2"]
from sklearn.linear_model import LinearRegression
model=LinearRegression()
model.fit(x,y)
co2pred=model.predict([[1300,2300]])
print(co2pred)
print(model.coef_)

#co2pred.model.predict(x)
#from sklearn.metrics import r2_score
#print("r2=",r2_score(y,co2pred"""ypred""")))


from range import value, bins
from misc import *
from rule import RULE

class XPLN:
    def __init__(self, best, rest):
        self.tmp = []
        self.maxSizes = {}
        self.best = best
        self.rest = rest

    def xpln1(self, data, best, rest):
        def v(has):
            return value(has, len(best.rows), len(rest.rows), 'best')
        def score(self, ranges):
            rule = RULE.RULE_SIZE(self,ranges, self.maxSizes)
            if rule:
                bestr = self.selects(rule, self.best.rows)
                restr = self.selects(rule, self.rest.rows)
                if len(bestr) + len(restr) > 0:
                    return value({'best': len(bestr), 'rest': len(restr)}, len(self.best.rows), len(self.rest.rows), 'best'), rule
        tmp,self.maxSizes = [],{}
        for _,ranges in enumerate(bins(data.cols.x,{'best':best.rows, 'rest':rest.rows})):
            self.maxSizes[ranges[0].txt] = len(ranges)
            for _,range in enumerate(ranges):
                tmp.append({'range':range, 'max':len(ranges),'val': v(range.y.has)})
        rule,most=self.firstN1(sorted(tmp,key = lambda x: x['val'],reverse=True),score)
        return rule,most

    def xpln2(self, data, best, rest):
        def v(has):
            return value(has, len(best.rows), len(rest.rows), 'best')
        def score(ranges, negranges):
            rule = {'pos':RULE.RULE_SIZE(self,ranges, maxSizes), 'neg':RULE.RULE_SIZE(self,negranges, maxSizes)}
            if rule['pos']:
                bestr= self.selects2(rule, best.rows)
                restr= self.selects2(rule, rest.rows)
                if len(bestr) + len(restr) > 0:
                    return v({"best": len(bestr), "rest": len(restr)}), rule
        tmp, maxSizes = [], {}
        for ranges in bins(data.cols.x, {'best': best.rows, 'rest': rest.rows}):
            ranges = list(ranges.values()) if isinstance(ranges, dict) else ranges
            maxSizes[ranges[0].txt] = len(ranges)
            for range in ranges:
                tmp.append({'range': range, 'max': len(ranges), 'val': v(range.y.has)})

        rule, most = self.firstN2(sorted(tmp, key=lambda x: x["val"], reverse=True), score)
        return rule, most

    def firstN1(self, sorted_ranges, scoreFun):
        first = sorted_ranges[0]['val']

        def useful(range):
            if range['val'] > 0.05 and range['val'] > first / 10:
                return range
        sorted_ranges = [s for s in sorted_ranges if useful(s)]
        most = -1
        out = -1
        for n in range(len(sorted_ranges)):
            tmp, rule = scoreFun([r['range'] for r in sorted_ranges[:n+1]])
            if tmp is not None and tmp > most:
                out, most = rule, tmp
        return out, most

    def firstN2(self, sorted_ranges, scoreFun):
        first = sorted_ranges[0]['val']

        def useful(range):
            if range['val'] > 0.05 and range['val'] > first / 10:
                return range

        def neg(range):
            if range['val'] < 0.05 and range['val'] < first / 10:
                return range

        negranges = list(filter(neg, sorted_ranges))
        negranges.reverse()
        sorted_ranges = list(filter(useful, sorted_ranges))
        sorted_ranges = [s for s in sorted_ranges if useful(s)]
        most,out = -1,-1
        for n in range(len(sorted_ranges)):
            tmp, rule = scoreFun([r['range'] for r in sorted_ranges[:n+1]])
            if tmp is not None and tmp > most:
                out, most = rule, tmp
        return out, most

    def showRule(rule):
        def pretty(range):
            return range['lo'] if range['lo'] == range['hi'] else [range['lo'], range['hi']]
        def merges(attr, ranges):
            return list(map(pretty, merge(sorted(ranges, key=lambda x: x['lo'])))), attr
        def merge(t0):
            t = []
            j = 0
            while j < len(t0):
                left = t0[j]
                right = None if j+1 >= len(t0) else t0[j+1]
                if right and left['hi'] == right['lo']:
                    left['hi'] = right['hi']
                    j = j +  1
                t.append({'lo': left['lo'], 'hi': left['hi']})
                j = j +  1
            return t if len(t0) == len(t) else merge(t)
        return kap(rule, merges)

    def selects(rule, rows):
        def disjunction(ranges, row):
            for rang in ranges:
                at = rang['at']
                x = row.cells[at]
                lo = rang['lo']
                hi = rang['hi']
                if x == '?' or (lo == hi and lo == x) or (lo <= x and x< hi):
                    return True
            return False

        def conjunction(row):
            for _,ranges in rule.items():
                if not disjunction(ranges, row):
                    return False
            return True

        def function(r):
            return r if conjunction(r) else None

        r = []
        for item in list(map(function, rows)):
            if item:
                r.append(item)
        return r

    def selects2(rule, rows):
        def disjunction(ranges, row):
            for rang in ranges:
                at = rang['at']
                x = row.cells[at]
                lo = rang['lo']
                hi = rang['hi']
                if x == '?' or (lo == hi and lo == x) or (float(lo) <= float(x) and float(x)< float(hi)):
                    return True
                if x.replace(".", "").isnumeric():
                    x = float(x)
                else:
                    x
            return False

        def conjunction(row):
            if rule:
                for ranges in rule['pos'].values():
                    for neg in rule['neg'].values():
                        if disjunction(neg, row):
                            return False
                    if not disjunction(ranges, row):
                        return False
                return True
            else:
                return True

        def function(r):
            return r if conjunction(r) else None

        r = []
        for item in list(map(function, rows)):
            if item:
                r.append(item)
        return r


import numpy as np

from .common import projection_back

def auxiva(
    X,
    n_src=None,
    n_iter=20,
    proj_back=True,
    W0=None,
    model="laplace",
    init_eig=False,
    return_filters=False,
    callback=None,
):
    """
    This is an implementation of AuxIVA/OverIVA that separates the input
    signal into statistically independent sources. The separation is done
    in the time-frequency domain and the FFT length should be approximately
    equal to the reverberation time.

    Two different statistical models (Laplace or time-varying Gauss) can
    be used by using the keyword argument `model`. The performance of Gauss
    model is higher in good conditions (few sources, low noise), but Laplace
    (the default) is more robust in general.

    Parameters
    ----------
    X: ndarray (nframes, nfrequencies, nchannels)
        STFT representation of the signal
    n_src: int, optional
        The number of sources or independent components. When
        ``n_src==nchannels``, the algorithms is identical to AuxIVA. When
        ``n_src==1``, then it is doing independent vector extraction.
    n_iter: int, optional
        The number of iterations (default 20)
    proj_back: bool, optional
        Scaling on first mic by back projection (default True)
    W0: ndarray (nfrequencies, nsrc, nchannels), optional
        Initial value for demixing matrix
    model: str
        The model of source distribution 'gauss' or 'laplace' (default)
    init_eig: bool, optional (default ``False``)
        If ``True``, and if ``W0 is None``, then the weights are initialized
        using the principal eigenvectors of the covariance matrix of the input
        data. When ``False``, the demixing matrices are initialized with identity
        matrix.
    return_filters: bool
        If true, the function will return the demixing matrix too
    callback: func
        A callback function called every 10 iterations, allows to monitor
        convergence

    Returns
    -------
    Returns an (nframes, nfrequencies, nsources) array. Also returns
    the demixing matrix (nfrequencies, nchannels, nsources)
    if ``return_values`` keyword is True.
    """

    n_frames, n_freq, n_chan = X.shape

    # default to determined case
    if n_src is None:
        n_src = n_chan

    assert (
        n_src <= n_chan
    ), "The number of sources cannot be more than the number of channels."

    if model not in ["laplace", "gauss"]:
        raise ValueError("Model should be either " "laplace" " or " "gauss" ".")

    # covariance matrix of input signal (n_freq, n_chan, n_chan)
    Cx = np.mean(X[:, :, :, None] * np.conj(X[:, :, None, :]), axis=0)

    W_hat = np.zeros((n_freq, n_chan, n_chan), dtype=X.dtype)
    W = W_hat[:, :n_src, :]
    J = W_hat[:, n_src:, :n_src]

    def tensor_H(T):
        return np.conj(T).swapaxes(1, 2)

    def update_J_from_orth_const():
        tmp = np.matmul(W, Cx)
        J[:, :, :] = tensor_H(np.linalg.solve(tmp[:, :, :n_src], tmp[:, :, n_src:]))

    # initialize A and W
    if W0 is None:
        if init_eig:
            # Initialize the demixing matrices with the principal
            # eigenvectors of the input covariance
            v, w = np.linalg.eig(Cx)
            for f in range(n_freq):
                ind = np.argsort(v[f])[-n_src:]
                W[f, :, :] = np.conj(w[f][:, ind])

        else:
            # Or with identity
            for f in range(n_freq):
                W[f, :, :n_src] = np.eye(n_src)

    else:
        W[:, :, :] = W0

    # We still need to initialize the rest of the matrix
    if n_src < n_chan:
        update_J_from_orth_const()
        for f in range(n_freq):
            W_hat[f, n_src:, n_src:] = -np.eye(n_chan - n_src)

    eps = 1e-15
    eyes = np.tile(np.eye(n_chan, n_chan), (n_freq, 1, 1))
    V = np.zeros((n_freq, n_chan, n_chan), dtype=X.dtype)
    r_inv = np.zeros((n_src, n_frames))
    r = np.zeros((n_src, n_frames))

    # Things are more efficient when the frequencies are over the first axis
    Y = np.zeros((n_freq, n_src, n_frames), dtype=X.dtype)
    X_original = X
    X = X.transpose([1, 2, 0]).copy()

    # Compute the demixed output
    def demix(Y, X, W):
        Y[:, :, :] = np.matmul(W, X)

    for epoch in range(n_iter):
        demix(Y, X, W)

        if callback is not None and epoch % 10 == 0:
            Y_tmp = Y.transpose([2, 0, 1])
            if proj_back:
                z = projection_back(Y_tmp, X_original[:, :, 0])
                callback(Y_tmp * np.conj(z[None, :, :]))
            else:
                callback(Y_tmp)

        # shape: (n_frames, n_src)
        if model == "laplace":
            r[:, :] = 2.0 * np.linalg.norm(Y, axis=0)
        elif model == "gauss":
            r[:, :] = (np.linalg.norm(Y, axis=0) ** 2) / n_freq

        # ensure some numerical stability
        r[r < eps] = eps

        r_inv[:, :] = 1.0 / r

        # Update now the demixing matrix
        for s in range(n_src):
            # Compute Auxiliary Variable
            # shape: (n_freq, n_chan, n_chan)
            V[:, :, :] = (
                np.matmul((X * r_inv[None, s, None, :]), np.conj(X.swapaxes(1, 2)))
                / n_frames
            )

            WV = np.matmul(W_hat, V)
            W[:, s, :] = np.conj(np.linalg.solve(WV, eyes[:, :, s]))

            # normalize
            denom = np.matmul(
                np.matmul(W[:, None, s, :], V[:, :, :]), np.conj(W[:, s, :, None])
            )
            W[:, s, :] /= np.sqrt(denom[:, :, 0])

            # Update the mixing matrix according to orthogonal constraints
            if n_src < n_chan:
                update_J_from_orth_const()

    demix(Y, X, W)

    Y = Y.transpose([2, 0, 1]).copy()

    if proj_back:
        z = projection_back(Y, X_original[:, :, 0])
        Y *= np.conj(z[None, :, :])

    if return_filters:
        return Y, W
    else:
        return Y


#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
@Project ：LeetCodePthonVersion
@File ：剑指 Offer 33. 二叉搜索树的后序遍历序列.py
@Author ：HuntingGame
@Date ：2023-03-15 20:39
C'est la vie!!! enjoy ur day :D
'''
class Solution:
    def verifyPostorder(self, postorder: [int]) -> bool:
        def recur(i,j):
            if i >=j:return True
            p = i
            while postorder[p] < postorder[j]: p+=1
            m = p
            while postorder[p] > postorder[j]: p+=1
            return p == j and recur(i,m-1) and recur(m,j-1)

        return recur(0,len(postorder) - 1)

树/剑指 Offer 33. 二叉搜索树的后序遍历序列.py

剑指 Offer 33. 二叉搜索树的后序遍历序列.py