#!/usr/bin/python3
from Sastrawi.Stemmer.StemmerFactory import StemmerFactory
from Sastrawi.StopWordRemover.StopWordRemoverFactory import StopWordRemoverFactory
from pathlib import Path
from tqdm import tqdm
import os
import sys
import math

def index(hashs, lists):
    for i in lists:
        if i in hashs:
            hashs[i] += 1
        else:
            hashs[i] = 1

# stopword dalam bahasa indonesian
get_stopword = StopWordRemoverFactory()
stopwords = get_stopword.create_stop_word_remover()

# stemming dalam bahasa indonesian
get_stemmer = StemmerFactory()
stemmer = get_stemmer.create_stemmer()

# hash
tf, df, idf, kalimatUtama, judul = dict(), dict(), dict(), dict(), dict()

if os.path.exists('../data/clean'):
    print(f'Directory : ../data/clean')
    for f in tqdm(Path('../data/clean').glob("*.txt")):
        name = str(f).split('/')
        df[name[3]], kalimatUtama[name[3]], judul[name[3]] = dict(), dict(), dict()

        File = open(f, 'r').read()
        File = stopwords.remove(File)

        sentence = File.split('\n')
        title = stemmer.stem(sentence[0].lower()).split()
        main = stemmer.stem(sentence[1].lower()).split()
        hasil = stemmer.stem(File.lower()).split()

        index(judul[name[3]], title)
        index(kalimatUtama[name[3]], main)
        index(tf, hasil)
        index(df[name[3]], hasil)
else:
    print("Wrong directory path")
    sys.exit(1)

print(f'unique words : {len(tf)}\n')

with open('../data/index/index.txt', 'w') as file:
    for term, freq in tqdm(tf.items()):
        idf[term] = 1 + math.log10(len(df)/tf[term])
        file.write(f"{term}")
        for doc, tfdoc in df.items():
            if term in tfdoc:
                if term in judul[doc]:
                    weigth = (tfdoc[term] * idf[term])*1
                elif term in kalimatUtama[doc]:
                    weigth = (tfdoc[term] * idf[term])*2/3
                else:
                    weigth = (tfdoc[term] * idf[term])*1/3
            else:
                file.write(f' {doc}:0')
                continue
            file.write(f' {doc}:{weigth}')
        file.write('\n')
print('done')


import graphviz as gv

def create_image(graph, filename):
    """
    Создаёт граф в формате graphviz и отрисовывает его
    сполученное изображение хранится в img/graph.svg
    :type graph: object
    :param graph:
    :return:
    """
    g = gv.Digraph(format='svg')
    for vertex in graph.dictionary:
        for connection in graph.dictionary[vertex]:
            g.node(connection)
            g.node(vertex)
    for vertex in graph.dictionary:
        for connection in graph.dictionary[vertex]:
            g.edge(vertex, connection)
    g.render("./img/"+filename)

def render_path(graph, path, filename):
    """
    Отрисовывает граф, отмечая посещённые вершины и рёбра
    :type graph: object
    """
    g = gv.Digraph(format='svg')
    edges = []
    for vertex_num, vertex in enumerate(path):
        if vertex_num < len(path)-1:
            edges.append([vertex, path[vertex_num+1]])
        else:
            break
    for vertex in graph.dictionary:
        for connection in graph.dictionary[vertex]:
            if connection in path:
                g.node(connection, color='red')
            if vertex in path:
                g.node(vertex, color='red')
            g.node(connection)
            g.node(vertex)
    for vertex in graph.dictionary:
        for connection in graph.dictionary[vertex]:
            if len(path) == 1 and vertex == connection:
                g.edge(vertex, connection, color='red', label='step 1')
                continue
            if [vertex, connection] in edges:
                g.edge(vertex, connection, color='red', label="step " + str(path.index(connection)) + "\n weight " + str(graph.dictionary[vertex][connection]))
            else:
                g.edge(vertex, connection)
    g.render("./img/"+filename)


#Modules for Pi
import os
import time
from gpiozero import Button
import RPi.GPIO as GPIO

#Modules for Object Detection
from imutils.video import VideoStream
from imutils.video import FPS
import numpy as np
import argparse
import imutils
import time
import cv2
import pyttsx3 as pt

#Modules for Text Recognition
import logging
import shutil
import subprocess
import sys
import tempfile
from constants import VALID_IMAGE_EXTENSIONS, WINDOWS_CHECK_COMMAND, DEFAULT_CHECK_COMMAND, TESSERACT_DATA_PATH_VAR

GPIO.setmode(GPIO.BCM)

GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP)

GPIO.setup(6, GPIO.IN, pull_up_down=GPIO.PUD_UP)

n = pt.init(driverName='espeak');

def observeMode():
    # construct the argument parse and parse the arguments
    ap = argparse.ArgumentParser()
    ap.add_argument("-c", "--confidence", type=float, default=0.2,
        help="minimum probability to filter weak detections")
    args = vars(ap.parse_args())

    prototext = "MobileNetSSD_deploy.prototxt.txt"
    model = "MobileNetSSD_deploy.caffemodel"

    # initialize the list of class labels MobileNet SSD was trained to
    # detect, then generate a set of bounding box colors for each class
    CLASSES = ["background", "aeroplane", "bicycle", "bird", "boat",
        "bottle", "bus", "car", "cat", "chair", "cow", "diningtable",
        "dog", "horse", "motorbike", "person", "plant", "sheep",
        "sofa", "train", "monitor"]
    COLORS = np.random.uniform(0, 255, size=(len(CLASSES), 3))

    # load our serialized model from disk
    print("[INFO] loading model...")
    net = cv2.dnn.readNetFromCaffe(prototext, model)
    # initialize the video stream, allow the cammera sensor to warmup,
    # and initialize the FPS counter
    print("[INFO] starting video stream...")
    vs = VideoStream(src=0).start()
    time.sleep(2.0)
    fps = FPS().start()

    # loop over the frames from the video stream
    while True:
        dict = {"L":{"background":0, "aeroplane":0, "bicycle":0, "bird":0, "boat":0,
        "bottle":0, "bus":0, "car":0, "cat":0, "chair":0, "cow":0, "diningtable":0,
        "dog":0, "horse":0, "motorbike":0, "person":0, "plant":0, "sheep":0,
        "sofa":0, "train":0, "monitor":0},"C" : {"background":0, "aeroplane":0, "bicycle":0, "bird":0, "boat":0,
        "bottle":0, "bus":0, "car":0, "cat":0, "chair":0, "cow":0, "diningtable":0,
        "dog":0, "horse":0, "motorbike":0, "person":0, "plant":0, "sheep":0,
        "sofa":0, "train":0, "monitor":0},"R":{"background":0, "aeroplane":0, "bicycle":0, "bird":0, "boat":0,
        "bottle":0, "bus":0, "car":0, "cat":0, "chair":0, "cow":0, "diningtable":0,
        "dog":0, "horse":0, "motorbike":0, "person":0, "plant":0, "sheep":0,
        "sofa":0, "train":0, "monitor":0}}
        # grab the frame from the threaded video stream and resize it
        # to have a maximum width of 400 pixels
        frame = vs.read()
        frame = imutils.resize(frame, width=400)

        #print(frame.shape)
        # grab the frame dimensions and convert it to a blob
        (h, w) = frame.shape[:2]
        blob = cv2.dnn.blobFromImage(frame,
            0.007843, (300, 300), 127.5)
        # print(blob)
        # pass the blob through the network and obtain the detections and
        # predictions
        net.setInput(blob)
        detections = net.forward()
        # print(detections)
        # break
        # loop over the detections
        print("--------------------")
        label_left = []
        label_right = []
        label_center = []
        for i in np.arange(0, detections.shape[2]):
            #count+=1

            # extract the confidence (i.e., probability) associated with
            # the prediction
            confidence = detections[0, 0, i, 2]
            #print(confidence , detections.shape[2])
            # filter out weak detections by ensuring the `confidence` is
            # greater than the minimum confidence
            if confidence > args["confidence"]:
                # extract the index of the class label from the
                # `detections`, then compute the (x, y)-coordinates of
                # the bounding box for the object
                idx = int(detections[0, 0, i, 1])
                box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
                (startX, startY, endX, endY) = box.astype("int")

                # draw the prediction on the frame
                label = "{}: {:.2f}%".format(CLASSES[idx],
                    confidence * 100)
                #print(count)
                label_cut = label.split(':')
                print(label,"----")
                if((startX+endX)/2<=125):
                    print("Left")
                    label_t = label.split(':')
                    label_left.append(label_t[0])
                    if(label_cut[0] in CLASSES):
                        dict['L'][label_cut[0]]+=1
                elif((startX+endX)/2 >=175):
                    label_t = label.split(':')
                    print("Right")
                    label_right.append(label_t[0])
                    if(label_cut[0] in CLASSES):
                        dict['R'][label_cut[0]]+=1
                else:
                    label_t = label.split(':')
                    print("Center")
                    label_center.append(label_t[0])
                    if(label_cut[0] in CLASSES):
                        dict['C'][label_cut[0]]+=1

                cv2.rectangle(frame, (startX, startY), (endX, endY),
                    COLORS[idx], 2)
                y = startY - 15 if startY - 15 > 15 else startY + 15
                cv2.putText(frame, label, (startX, y),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5, COLORS[idx], 2)
                # print("left",label_left)
                # print("right",label_right)
                # print('center',label_center)

                print(dict)

                print("Left label",label_left)
                print("Right label",label_right)
                print("Center label",label_center)
                print("----------------\n",label_left,"\n---------------")
                if(len(label_left)>0):
                    label_for_left = label_left[0].split(':')
                    print(dict['L'][label_for_left[0]])
                if(len(label_center)>0):
                    label_for_center = label_center[0].split(':')
                    print(dict['C'][label_for_center[0]])
                if(len(label_right)>0):
                    label_for_right = label_right[0].split(':')
                    print(dict['R'][label_for_right[0]])
                for j in (label_left):
                    if(dict['L'][j]!=0):
                        cnt = dict['L'][j]
                        if(cnt!=1):
                            if(j == 'person'):
                                textl = "In Left There are "+str(cnt)+" People"
                            elif(j == 'sheep'):
                                textl = "In Left There are "+str(cnt)+"Sheep"
                            elif(j == 'bus'):
                                textl = "In Left There are "+str(cnt)+"buses"
                            else:
                                textl = "In Left There are "+str(cnt)+" "+str(j)+"s"
                        else:
                            textl = "In Left There is "+str(cnt)+" "+str(j)
                    print(str(textl))
                    n.say(str(textl))
                    n.runAndWait()
                for k in (label_center):
                    if(dict['C'][k]!=0):
                        cnt = dict['C'][k]
                        if(cnt!=1):
                            if(k == 'person'):
                                textl = "In Left There are "+str(cnt)+" People"
                            elif(j == 'sheep'):
                                textl = "In Left There are "+str(cnt)+"Sheep"
                            elif(j == 'bus'):
                                textl = "In Left There are "+str(cnt)+"buses"
                            else:
                                textc = "In Front there are "+str(cnt)+" "+str(k)+"s"
                        else:
                            textc = "In Front there is "+str(cnt)+" "+str(k)
                    print(str(textc))
                    n.say(str(textc))
                    n.runAndWait()
                for l in (label_right):
                    if(dict['R'][l]!=0):
                        cnt = dict['R'][l]
                        if(cnt!=1):
                            if(l == 'person'):
                                textl = "In Left There are "+str(cnt)+" People"
                            elif(j == 'sheep'):
                                textl = "In Left There are "+str(cnt)+"Sheep"
                            elif(j == 'bus'):
                                textl = "In Left There are "+str(cnt)+"buses"
                            else:
                                textr = "In Right There are "+str(cnt)+" "+str(l)+"s"
                        else:
                            textr = "In Right There is "+str(cnt)+" "+str(l)
                    print(str(textr))
                    n.say(str(textr))
                    n.runAndWait()
        # show the output frame
        cv2.imshow("Frame", frame)
        key = cv2.waitKey(1) & 0xFF

        # if the `q` key was pressed, break from the loop
        if key == ord("q"):
            break

        # update the FPS counter
        fps.update()

    # stop the timer and display FPS information

    fps.stop()
    print("[INFO] elapsed time: {:.2f}".format(fps.elapsed()))
    print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))

    # do a bit of cleanup
    cv2.destroyAllWindows()
    vs.stop()

def create_directory(path):
        """
        Create directory at given path if directory does not exist
        :param path:
        :return:
        """
        if not os.path.exists(path):
            os.makedirs(path)

def check_path(path):
        """
        Check if file path exists or not
        :param path:
        :return: boolean
        """
        return bool(os.path.exists(path))

def get_command():
        """
        Check OS and return command to identify if tesseract is installed or not
        :return:
        """
        if sys.platform.startswith('win'):
            return WINDOWS_CHECK_COMMAND
        return DEFAULT_CHECK_COMMAND

def run_tesseract(filename, output_path, image_file_name):
    # Run tesseract
    filename_without_extension = os.path.splitext(filename)[0]
    # If no output path is provided
    if not output_path:
        temp_dir = tempfile.mkdtemp()
        temp_file = os.path.join(temp_dir, filename_without_extension)
        subprocess.run(['tesseract', image_file_name, temp_file],
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE)
        with open('{}.txt'.format(temp_file), 'r', encoding="utf8") as f:
            text = f.read()
        shutil.rmtree(temp_dir)
        return text
    text_file_path = os.path.join(output_path, filename_without_extension)
    subprocess.run(['tesseract', image_file_name, text_file_path],
                   stdout=subprocess.PIPE,
                   stderr=subprocess.PIPE)
    return

def check_pre_requisites_tesseract():
    """
    Check if the pre-requisites required for running the tesseract application are satisfied or not
    :param : NA
    :return: boolean
    """
    check_command = get_command()
    logging.debug("Running `{}` to check if tesseract is installed or not.".format(check_command))

    result = subprocess.run([check_command, 'tesseract'], stdout=subprocess.PIPE)
    if not result.stdout:
        logging.error("tesseract-ocr missing, install `tesseract` to resolve. Refer to README for more instructions.")
        return False
    logging.debug("Tesseract correctly installed!\n")

    if sys.platform.startswith('win'):
        environment_variables = os.environ
        logging.debug(
            "Checking if the Tesseract Data path is set correctly or not.\n")
        if TESSERACT_DATA_PATH_VAR in environment_variables:
            if environment_variables[TESSERACT_DATA_PATH_VAR]:
                path = environment_variables[TESSERACT_DATA_PATH_VAR]
                logging.debug("Checking if the path configured for Tesseract Data Environment variable `{}` \
                as `{}` is valid or not.".format(TESSERACT_DATA_PATH_VAR, path))
                if os.path.isdir(path) and os.access(path, os.R_OK):
                    logging.debug("All set to go!")
                    return True
                else:
                    logging.error(
                        "Configured path for Tesseract data is not accessible!")
                    return False
            else:
                logging.error("Tesseract Data path Environment variable '{}' configured to an empty string!\
                ".format(TESSERACT_DATA_PATH_VAR))
                return False
        else:
            logging.error("Tesseract Data path Environment variable '{}' needs to be configured to point to\
            the tessdata!".format(TESSERACT_DATA_PATH_VAR))
            return False
    else:
        return True

def main(input_path, output_path):
    # Check if tesseract is installed or not
    if not check_pre_requisites_tesseract():
        return

    # Check if a valid input directory is given or not
    if not check_path(input_path):
        logging.error("Nothing found at `{}`".format(input_path))
        return

    # Create output directory
    if output_path:
        create_directory(output_path)
        logging.debug("Creating Output Path {}".format(output_path))

    # Check if input_path is directory or file
    if os.path.isdir(input_path):
        logging.debug("The Input Path is a directory.")
        # Check if input directory is empty or not
        total_file_count = len(os.listdir(input_path))
        if total_file_count == 0:
            logging.error("No files found at your input location")
            return

        # Iterate over all images in the input directory
        # and get text from each image
        other_files = 0
        successful_files = 0
        logging.info("Found total {} file(s)\n".format(total_file_count))
        for ctr, filename in enumerate(os.listdir(input_path)):
            logging.debug("Parsing {}".format(filename))
            extension = os.path.splitext(filename)[1]

            if extension.lower() not in VALID_IMAGE_EXTENSIONS:
                other_files += 1
                continue

            image_file_name = os.path.join(input_path, filename)
            print(run_tesseract(filename, output_path, image_file_name))
            successful_files += 1

        logging.info("Parsing Completed!\n")
        if successful_files == 0:
            logging.error("No valid image file found.")
            logging.error("Supported formats: [{}]".format(
                ", ".join(VALID_IMAGE_EXTENSIONS)))
        else:
            logging.info(
                "Successfully parsed images: {}".format(successful_files))
            logging.info(
                "Files with unsupported file extensions: {}".format(other_files))

    else:
        filename = os.path.basename(input_path)
        logging.debug("The Input Path is a file {}".format(filename))
        text = run_tesseract(filename, output_path, input_path)
        print(text)
        n.say(text);
        n.runAndWait()

def readMode():
    n = pt.init(driverName='espeak');
    path = "/home/nisarg/image2text-master/realtime.jpg"
    #os.system("cheese")
    os.system("fswebcam -r 640x480 --jpeg 85 -D 0 "+path)
    os.system("eog /home/nisarg/image2text-master/realtime.jpg")

    parser = argparse.ArgumentParser()
    parser._action_groups.pop()
    #required = parser.add_argument_group('required arguments')
    optional = parser.add_argument_group('optional arguments')
    #required.add_argument('-i', '--input', help="Single image file path or images directory path", required=True)
    optional.add_argument('-o', '--output', help="(Optional) Output directory for converted text")
    optional.add_argument('-d', '--debug', action='store_true', help="Enable verbose DEBUG logging")

    args = parser.parse_args()
    #input_path = os.path.abspath(args.input)
    input_path = path
    #print("Args : ",args)
    if args.output:
        output_path = os.path.abspath(args.output)
    else:
        output_path = None

    if args.debug:
        logging.getLogger().setLevel(logging.DEBUG)
    else:
        logging.getLogger().setLevel(logging.INFO)

    logging.debug("Input Path is {}".format(input_path))

    # Check Python version
    if sys.version_info[0] < 3:
        logging.error("You are using Python {0}.{1}. Please use Python>=3".format(
            sys.version_info[0], sys.version_info[1]))
        exit()

    main(input_path, output_path)

while(True):
    if GPIO.input(5)==0:
        observeMode()
        #time.sleep(3)
    elif GPIO.input(6)==0:
        readMode()


"""
Compute experimental OTF of microscope, based on a series of DMD pictures taken a range of angles/pattern spacings.

Using known affine transformation as a starting point, identify peaks in fluorescence image. These must be normalized
to the DC component of the fluorescence image (laser intensity may change between frames) and to the size of the fourier
component at the frequency in the given pattern.

Actually, we need to the fourier transform of the intensity for our DMD pattern properly bandlimited for the effect
of the imaging system on the coherent light.
"""

import time
# import sys
import numpy as np
from scipy import fft
import scipy.signal
import scipy.optimize

import matplotlib.colors
from matplotlib.colors import PowerNorm
import matplotlib.patches
import matplotlib.pyplot as plt

import dmd_patterns
import simulate_dmd
import affine
import analysis_tools as tools
import sim_reconstruction
import fit_psf

def frq2angles(frq_2d, wavelength, n):
    """
    Convert from frequency vectors (in angular spectrum representation) to angles

    f = n/lambda * [cos(phi)*sin(theta), sin(phi)*sin(theta), cos(theta)]

    :param frq_2d:
    :param wavelength:
    :param n:

    :return phi:
    :return theta:
    """
    frq_2d = np.array(frq_2d, copy=True)

    # phi = np.arctan(wavelength / n * frq_2d[..., 1] / frq_2d[..., 0])
    # phi[frq_2d[..., 0] == 0] = np.pi/2
    phi = np.atleast_1d(np.angle(frq_2d[..., 0] + 1j * frq_2d[..., 1]))
    theta = np.atleast_1d(np.arcsin(wavelength / n * np.linalg.norm(frq_2d, axis=-1)))

    # ensure disallowed points return nans
    disallowed = np.linalg.norm(frq_2d, axis=-1) > n/wavelength
    phi[disallowed] = np.nan
    theta[disallowed] = np.nan

    return phi, theta

def angles2frq(theta, phi, wavelength, n):
    """

    :param theta:
    :param phi:
    :param float wavelength:
    :param float n: index of refraction of medium

    :return frq:
    """
    frq = n/wavelength * np.array([np.cos(phi) * np.sin(theta),
                                   np.sin(phi) * np.sin(theta),
                                   np.cos(theta)])
    return frq

def interfere_polarized(theta1, phi1, theta2, phi2, alpha):
    """
    Let the optical axis point along z. theta is the angle with respect to the optical axis,
    and phi is the azimuthal angle of the ray. Alpha is the azimuthal angle of the polarization,
    which we assume is initially orthogonal to the optical axis

    The polarization vector is
    p = [np.cos(alpha), np.sin(alpha), 0]
    The s/p unit vectors are
    ep = [np.cos(phi), np.sin(phi), 0]
    es = [-np.sin(phi), np.cos(phi), 0]
    after refracting through the lens, the polarization vector is
    pr = (p.dot(ep)) * er + (p.odt(es)) * es
    with er now pointing orthothogonal to the propogation of the refracted ray
    er = [np.cos(phi) * np.cos(theta), np.sin(phi) * np.cos(theta), np.sin(theta)]

    This function compute pr(theta1, phi1, alpha).dot(pr(theta2, phi2, alpha))

    :param theta1: angle of first ray
    :param phi1: azimuthal angle of first ray
    :param theta2: angle of second ray
    :param phi2: azimuthal angle of second ray
    :param alpha: polarization angle

    :return: dot product of the two polarization vectors
    """
    int = np.cos(alpha - phi1) * np.cos(alpha - phi2) * np.cos(phi1) * np.cos(phi2) * np.cos(theta1) * np.cos(theta2) + \
        np.sin(alpha - phi1) * np.sin(alpha - phi2) * np.sin(phi1) * np.sin(phi2) + \
        -np.cos(alpha - phi1) * np.sin(alpha - phi2) * np.cos(phi1) * np.sin(phi2) * np.cos(theta1) + \
        -np.sin(alpha - phi1) * np.cos(alpha - phi2) * np.sin(phi1) * np.cos(phi2) * np.cos(theta2) + \
        np.cos(alpha - phi1) * np.cos(alpha - phi2) * np.sin(phi1) * np.sin(phi2) * np.cos(theta1) * np.cos(theta2) + \
        np.sin(alpha - phi1) * np.sin(alpha - phi2) * np.cos(phi1) * np.cos(phi2) + \
        np.cos(alpha - phi1) * np.sin(alpha - phi2) * np.sin(phi1) * np.cos(phi2) * np.cos(theta1) + \
        np.sin(alpha - phi1) * np.cos(alpha - phi2) * np.cos(phi1) * np.sin(phi2) * np.cos(theta2) + \
        np.cos(alpha - phi1) * np.cos(alpha - phi2) * np.sin(theta1) * np.sin(theta2)

    return int

def interfere_unpolarized(theta1, phi1, theta2, phi2):
    """
    Intereference averaged over input polarization
    :param theta1:
    :param phi1:
    :param theta2:
    :param phi2:
    :return:
    """
    int = 0.5 * np.cos(phi1 - phi2)**2 * (1 + np.cos(theta1) * np.cos(theta2)) + \
          0.5 * np.cos(phi1 - phi2) * np.sin(theta1) * np.sin(theta2) + \
          0.5 * np.sin(phi1 - phi2)**2 * (np.cos(theta1) + np.cos(theta2))

    return int

def get_int_fc(efield_fc):
    """
    Generate intensity fourier components from efield fourier components ignoring polarization effects

    :param efield_fc: electric field Fourier components nvec1 x nvec2 array,
     where efield_fc[ii, jj] is the electric field at frequencies f = ii * v1 + jj * v2.

    :return intensity_fc: intensity Fourier components at the same frequencies, f = ii * v1 + jj * v2
    """
    ny, nx = efield_fc.shape
    if np.mod(ny, 2) == 0 or np.mod(nx, 2) == 0:
        raise ValueError("not implemented for even sized arrays")

    intensity_fc = scipy.signal.fftconvolve(efield_fc, np.flip(efield_fc, axis=(0, 1)).conj(), mode='same')

    return intensity_fc

def get_int_fc_pol(efield_fc, vecs, wavelength, n, polarization_angle=None):
    """
    Calculate intensity from electric field including effect of polarization.

    :param efield_fc: electric field Fourier components nvec1 x nvec2 array, where efield_fc[ii, jj]
     is the electric field at frequencies f = ii * v1 + jj * v2.
    :param vecs: nvec1 x nvec2 x 2
    :param float wavelength: wavelength of excitation light. If vecs are given in 1/unit, then wavelength must be given
    in unit.
    :param n: index of refraction of medium
    :param polarization_angle: can either be an angle in radians, or "None" in which case assume unpolarized light.

    :return intensity_fc: nvec1 x nvec2 x 2
    """
    ny, nx = efield_fc.shape
    if np.mod(ny, 2) == 0 or np.mod(nx, 2) == 0:
        raise ValueError("not implemented for even sized arrays")

    # define convolution
    def conv(efield): return scipy.signal.fftconvolve(efield, np.flip(efield, axis=(0, 1)).conj(), mode='same')

    # convert frequencies in distance units to polar angles
    phis, thetas = frq2angles(vecs, wavelength, n)

    if polarization_angle is None:
        # these expressions can be arrived at by factoring those found in interfere_unpolarized()
        # see also eq. 9 in https://doi.org/10.1364/OE.22.011140
        polx_a = np.sin(phis)**2 + np.cos(thetas) * np.cos(phis)**2
        poly_a = np.sin(phis) * np.cos(phis) * (np.cos(thetas) - 1)
        polz_a = np.cos(phis) * np.sin(thetas)
        polx_b = np.sin(phis) * np.cos(phis) * (np.cos(thetas) - 1)
        poly_b = np.cos(phis)**2 + np.cos(thetas) * np.sin(phis)**2
        polz_b = np.sin(phis) * np.sin(thetas)

        polx_a[np.isnan(polx_a)] = 0
        poly_a[np.isnan(poly_a)] = 0
        polz_a[np.isnan(polz_a)] = 0
        polx_b[np.isnan(polx_b)] = 0
        poly_b[np.isnan(poly_b)] = 0
        polz_b[np.isnan(polz_b)] = 0

        intensity_fc = 0.5 * (conv(efield_fc * polx_a) + conv(efield_fc * poly_a) + conv(efield_fc * polz_a) +
                              conv(efield_fc * polx_b) + conv(efield_fc * poly_b) + conv(efield_fc * polz_b))
    else:
        # similar to above, but not 0.5 and simpler factorization because no averaging
        polx = np.cos(polarization_angle - phis) * np.cos(phis) * np.cos(thetas) - np.sin(polarization_angle - phis) * np.sin(phis)
        poly = np.cos(polarization_angle - phis) * np.sin(phis) * np.cos(thetas) + np.sin(polarization_angle - phis) * np.cos(phis)
        polz = np.cos(polarization_angle - phis) * np.sin(thetas)

        polx[np.isnan(polx)] = 0
        poly[np.isnan(poly)] = 0
        polz[np.isnan(polz)] = 0

        intensity_fc = conv(efield_fc * polx) + conv(efield_fc * poly) + conv(efield_fc * polz)

    return intensity_fc

def get_all_fourier_exp(imgs, frq_vects_theory, roi, pixel_size_um, fmax_img,
                        to_use=None, use_guess_frqs=True, max_frq_shift_pix=1.5, force_start_from_guess=True,
                        peak_pix=2, bg=100):
    """
    Calculate Fourier components from a set of images.

    :param imgs: nimgs x ny x nx
    :param vects: nimgs x nvecs1 x nvecs2 x 2
    :param float pixel_size_um:
    :param bool use_guess_frqs: if True, use guess frequencies computed from frq_vects_theory, if False use fitting
    procedure to find peak
    :param int peak_pix: number of pixels to use when calculating peak. Typically 2.
    :param float bg:

    :return intensity:
    :return intensity_unc:
    :return frq_vects_expt:
    """
    if to_use is None:
        to_use = np.ones(frq_vects_theory[:, :, :, 0].shape, dtype=np.int)

    nimgs = frq_vects_theory.shape[0]
    n1_vecs = frq_vects_theory.shape[1]
    n2_vecs = frq_vects_theory.shape[2]

    intensity = np.zeros(frq_vects_theory.shape[:-1], dtype=np.complex) * np.nan
    intensity_unc = np.zeros(intensity.shape) * np.nan

    # apodization, 2D window from broadcasting
    nx_roi = roi[3] - roi[2]
    ny_roi = roi[1] - roi[0]
    window = scipy.signal.windows.hann(nx_roi)[None, :] * scipy.signal.windows.hann(ny_roi)[:, None]

    # generate frequency data for image FT's
    fxs = tools.get_fft_frqs(nx_roi, pixel_size_um)
    dfx = fxs[1] - fxs[0]
    fys = tools.get_fft_frqs(ny_roi, pixel_size_um)
    dfy = fys[1] - fys[0]

    if imgs.shape[0] == nimgs:
        multiple_images = True
    elif imgs.shape[0] == 1:
        multiple_images = False
        icrop = imgs[0, roi[0]:roi[1], roi[2]:roi[3]]

        img = icrop - bg
        img[img < 0] = 1e-6

        img_ft = fft.fftshift(fft.fft2(fft.ifftshift(img * window)))
        noise_power = sim_reconstruction.get_noise_power(img_ft, fxs, fys, fmax_img)
    else:
        raise Exception()

    frq_vects_expt = np.zeros(frq_vects_theory.shape)
    tstart = time.process_time()
    for ii in range(nimgs):
        tnow = time.process_time()
        print("%d/%d, %d peaks, elapsed time = %0.2fs" % (ii + 1, nimgs, np.sum(to_use[ii]), tnow - tstart))

        if multiple_images:
            # subtract background and crop to ROI
            # img = img[0, roi[0]:roi[1], roi[2]:roi[3]] - bg
            # img[img < 0] = 1e-6
            icrop = imgs[ii, roi[0]:roi[1], roi[2]:roi[3]]
            img = icrop - bg
            img[img < 0] = 1e-6

            # fft
            img_ft = fft.fftshift(fft.fft2(fft.ifftshift(img * window)))
            # get noise
            noise_power = sim_reconstruction.get_noise_power(img_ft, fxs, fys, fmax_img)

        # minimimum separation between reciprocal lattice vectors
        vnorms = np.linalg.norm(frq_vects_theory[ii], axis=2)
        min_sep = np.min(vnorms[vnorms > 0])

        # get experimental weights of fourier components
        for aa in range(n1_vecs):
            for bb in range(n2_vecs):

                frq_vects_expt[ii, aa, bb] = frq_vects_theory[ii, aa, bb]

                # only do fitting if peak size exceeds tolerance, and only fit one of a peak and its compliment
                if not to_use[ii, aa, bb]:
                    continue

                max_frq_shift = np.min([max_frq_shift_pix * dfx, 0.5 * vnorms[aa, bb], 0.5 * min_sep])

                # get experimental frequency
                if (max_frq_shift/dfx) < 1 or use_guess_frqs or np.linalg.norm(frq_vects_expt[ii, aa, bb]) == 0:
                    # if can't get large enough ROI, then use our guess
                    pass
                else:
                    # fit real fourier component in image space
                    # only need wavelength and na to get fmax
                    frq_vects_expt[ii, aa, bb], mask = sim_reconstruction.fit_modulation_frq(
                        img_ft, img_ft, pixel_size_um, fmax_img,
                        frq_guess=frq_vects_theory[ii, aa, bb], max_frq_shift=max_frq_shift,
                        force_start_from_guess=force_start_from_guess)

                    sim_reconstruction.plot_correlation_fit(img_ft, img_ft, frq_vects_expt[ii, aa, bb],
                                                            pixel_size_um, fmax_img,
                                                            frqs_guess=frq_vects_theory[ii, aa, bb], roi_size=3)

                try:
                    # get peak value and phase
                    intensity[ii, aa, bb] = tools.get_peak_value(img_ft, fxs, fys, frq_vects_expt[ii, aa, bb],
                                                                         peak_pixel_size=peak_pix)

                    intensity_unc[ii, aa, bb] = np.sqrt(noise_power) * peak_pix ** 2

                    # handle complimentary point with aa > bb
                    aa_neg = n1_vecs - 1 - aa
                    bb_neg = n2_vecs - 1 - bb
                    intensity[ii, aa_neg, bb_neg] = intensity[ii, aa, bb].conj()
                    intensity_unc[ii, aa_neg, bb_neg] = intensity_unc[ii, aa, bb]

                except:
                    pass

    return intensity, intensity_unc, frq_vects_expt

def get_all_fourier_thry(vas, vbs, nmax, nphases, phase_index, dmd_size):
    """
    Calculate theory intensity/electric field fourier components

    :param vas:
    :param vbs:
    :param roi:
    :param affine_xform:
    :param pixel_size_um:
    :param nmax:
    :param nphases:
    :param phase_index:
    :param dmd_size:
    :param use_blaze_correction:
    :param dmd_params:

    :return efield_theory:
    :return ns:
    :return ms:
    :return frq_vects_dmd:
    """
    npatterns = len(vas)

    norders = 2 * nmax + 1
    efield_theory = np.zeros((npatterns, norders, norders), dtype=np.complex) * np.nan
    frq_vects_dmd = np.zeros((npatterns, norders, norders, 2))

    tstart = time.process_time()
    for ii in range(npatterns):
        tnow = time.process_time()
        print("%d/%d, elapsed time = %0.2fs" % (ii + 1, npatterns, tnow - tstart))
        # sys.stdout.write("\033[F")
        # sys.stdout.flush()
        va = vas[ii]
        vb = vbs[ii]

        # recp_vec_a, recp_vec_b = dmd_patterns.get_reciprocal_vects(va, vb)
        unit_cell, xcell, ycell = dmd_patterns.get_sim_unit_cell(va, vb, nphases)

        # get expected values
        efield_theory[ii], ns, ms, frq_vects_dmd[ii] = \
            dmd_patterns.get_efield_fourier_components(unit_cell, xcell, ycell, va, vb, nphases, phase_index,
                                                       dmd_size=dmd_size, nmax=nmax)

        # change normalization from 1 being maximum possible fourier component to 1 being DC component
        efield_theory[ii] = efield_theory[ii] / np.nansum(unit_cell) * np.nansum(unit_cell >= 0)

    return efield_theory, ns, ms, frq_vects_dmd

def get_intensity_fourier_thry(efields, frq_vects_dmd, roi, affine_xform, wavelength_ex, fmax_efield_ex,
                               index_of_refraction, pixel_size_um, dmd_shape,
                               use_blaze_correction=False, use_polarization_correction=False, dmd_params=None):
    """

    :param efields: nimgs x nvecs1 x nvecs2, electric field Fourier components from DMD pattern, with no blaze
     condition corrections.
    :param frq_vects_dmd: frequency vectors in 1/mirrors in DMD space. Size nimgs x nvecs1 x nvecs2 x 2
    :param list[int] roi: region of interest within image. [ystart, yend, xstart, xend]
    :param affine_xform: affine transformation connecting image space and DMD space
     (using pixels as coordinates on both ends). This is a 3x3 matrix.
    :param float fmax_efield_ex: maximum electric field frequency that can pass throught he imaging system from the
     DMD to sample, in 1/mirrors
    :param float pixel_size_um: camera pixel size in um
    :param bool use_blaze_correction: whether or not to use blaze correction
    :param bool use_polarization_correction: whether or not to correct for polarization effects. Assumes input is
    completely unpolarized. # todo: can add other polarization options
    :param dmd_params: {"wavelength", "gamma", "wx", "wy", "theta_ins": [tx, ty], "theta_outs": [tx, ty]}. These can be
    omitted if use_blaze_correction is False

    :return intensity_theory: theoretical intensity using DMD coordinates. nimgs x nvecs1 x nvecs2
    :return intensity_theory_xformed: theoretical intensity using camera ROI coordinates. Same magnitude but different
    phase versus intensity_theory. nimgs x nvecs1 x nvecs2. This is identical to intensity_theory in magnitude, but
    different in phase
    :return frq_vects_cam: frequency vectors in camera space in 1/pixels. nimgs x nvecs1 x nvecs2 x 2
    :return frq_vects_um: frequency vectors in camera space in 1/microns. nimgs x nvecs1 x nvecs2 x 2
    """

    # define pupil function
    if use_blaze_correction:
        def pupil_fn(fx, fy):
            fx = np.atleast_1d(fx)
            fy = np.atleast_1d(fy)
            tx_out = dmd_params["theta_outs"][0] + dmd_params["wavelength"] * fx / dmd_params["dx"]
            ty_out = dmd_params["theta_outs"][1] + dmd_params["wavelength"] * fy / dmd_params["dy"]
            envelope = simulate_dmd.blaze_envelope(dmd_params["wavelength"], dmd_params["gamma"], dmd_params["wx"],
                                               dmd_params["wy"], dmd_params["theta_ins"][0], dmd_params["theta_ins"][1],
                                               tx_out, ty_out)
            return envelope * (np.sqrt(fx ** 2 + fy ** 2) <= fmax_efield_ex)
    else:
        def pupil_fn(fx, fy):
            return np.sqrt(fx ** 2 + fy ** 2) <= fmax_efield_ex

    # compute pupil
    pupil = pupil_fn(frq_vects_dmd[..., 0], frq_vects_dmd[..., 1])

    # compute frequency vectors in camera space (1/pixels)
    frq_vects_cam = np.zeros(frq_vects_dmd.shape)
    frq_vects_cam[..., 0], frq_vects_cam[..., 1], _ = affine.xform_sinusoid_params_roi(
        frq_vects_dmd[..., 0], frq_vects_dmd[..., 1], 0, dmd_shape, roi, affine_xform,
        input_origin="fft", output_origin="fft")

    # correct frequency vectors in camera space to be in real units (1/um)
    frq_vects_um = frq_vects_cam / pixel_size_um

    # calculate intensities for each image
    intensity_theory = np.zeros(efields.shape, dtype=np.complex) * np.nan
    for ii in range(frq_vects_cam.shape[0]):
        if use_polarization_correction:
            intensity_theory[ii] = get_int_fc_pol(efields[ii] * pupil[ii], frq_vects_um[ii], wavelength_ex, index_of_refraction)
        else:
            intensity_theory[ii] = get_int_fc(efields[ii] * pupil[ii])

    # normalize to DC values
    intensity_theory = intensity_theory / np.max(np.abs(intensity_theory), axis=(1, 2))[:, None, None]

    # compute phase in new coordinates
    _, _, intensity_phases = affine.xform_sinusoid_params_roi(frq_vects_dmd[..., 0], frq_vects_dmd[..., 1],
                                                              np.angle(intensity_theory),
                                                              dmd_shape, roi, affine_xform, input_origin="fft", output_origin="fft")
    intensity_theory_xformed = np.abs(intensity_theory) * np.exp(1j * intensity_phases)

    return intensity_theory, intensity_theory_xformed, frq_vects_cam, frq_vects_um

def fit_phase_diff(phase_th, phase_expt, frqs):
    """
    Match theory and experimental phases as best as possible by modifying affine transformation
    :param phase_th:
    :param phase_expt:
    :param frqs:
    :return:
    """
    def phase_diff_fn(phi1, phi2):
        diff = np.array(np.mod(phi1 - phi2, 2*np.pi))
        to_flip = np.abs(diff - 2*np.pi) < np.abs(diff)
        diff[to_flip] = diff[to_flip] - 2*np.pi
        return diff

    def phase_xform_fn(phi, fx, fy, p): return np.mod(phi + 2 * np.pi * fx * p[0] + 2 * np.pi * fy * p[1], 2 * np.pi)

    def min_fn(p): return np.nansum(np.abs(phase_diff_fn(phase_xform_fn(phase_th, frqs[:, 0], frqs[:, 1], p), phase_expt)))

    results = scipy.optimize.minimize(min_fn, [0, 0])

    figh = plt.figure()
    plt.plot(np.linalg.norm(frqs, axis=-1), phase_xform_fn(phase_th, frqs[:, 0], frqs[:, 1], results["x"]), '.')
    plt.plot(np.linalg.norm(frqs, axis=-1), np.mod(phase_th, 2*np.pi), '.')
    plt.plot(np.linalg.norm(frqs, axis=-1), np.mod(phase_expt, 2*np.pi), 'x')
    plt.legend(["th fit", "th", "expt"])

    return figh, results

def plot_pattern(img, va, vb, frq_vects, fmax_img, pixel_size_um, dmd_size, affine_xform, roi, nphases, phase_index, fmax_in=None,
                 peak_int_exp=None, peak_int_exp_unc=None, peak_int_theory=None, otf=None, otf_unc=None, to_use=None,
                 figsize=(20, 10)):
    """
    plot image and affine xformed pattern it corresponds to
    :param img: image ny x nx
    :param va: [vx, vy]
    :param vb: [vx, vy]
    :param frq_vects: vecs1 x nvecs2 x 2. in 1/um
    :param float fmax_img: in 1/um
    :param float pixel_size_um:
    :param dmd_size: []
    :param affine_xform: affine transformation between DMD space and camera space
    :param roi: [ystart, yend, xstart, xend] region of interest in image
    :param nphases: number of phaseshifts used to generate the DMD pattern. Needed in addition to va/vb to specify pattern
    :param phase_index:  index of phaseshift. Needed in addition to va, vb, nphases to specify pattern

    :return fig_handle:
    """

    if to_use is None:
        to_use = np.ones(peak_int_exp.shape, dtype=np.bool)

    fmags = np.linalg.norm(frq_vects, axis=-1)
    n1max = int(np.round(0.5 * (fmags.shape[0] - 1)))
    n2max = int(np.round(0.5 * (fmags.shape[1] - 1)))

    # generate DMD pattern
    pattern, _ = dmd_patterns.get_sim_pattern(dmd_size, va, vb, nphases, phase_index)

    # crop image
    img_roi = img[roi[0]:roi[1], roi[2]:roi[3]]
    ny, nx = img_roi.shape

    # transform pattern using affine transformation
    xform_roi = affine.xform_shift_center(affine_xform, cimg_new=(roi[2], roi[0]))
    img_coords = np.meshgrid(range(nx), range(ny))
    pattern_xformed = affine.affine_xform_mat(pattern, xform_roi, img_coords, mode="interp")
    # pattern_xformed_ft = fft.fftshift(fft.fft2(fft.ifftshift(pattern_xformed)))

    # get fourier transform of image
    fxs = tools.get_fft_frqs(nx, pixel_size_um)
    dfx = fxs[1] - fxs[0]
    fys = tools.get_fft_frqs(ny, pixel_size_um)
    dfy = fys[1] - fys[0]

    extent = [fxs[0] - 0.5 * dfx, fxs[-1] + 0.5 * dfx, fys[-1] + 0.5 * dfy, fys[0] - 0.5 * dfy]

    window = scipy.signal.windows.hann(nx)[None, :] * scipy.signal.windows.hann(ny)[:, None]
    img_ft = fft.fftshift(fft.fft2(fft.ifftshift(img_roi * window)))

    # plot results
    figh = plt.figure(figsize=figsize)
    grid = plt.GridSpec(2, 6)

    period = dmd_patterns.get_sim_period(va, vb)
    angle = dmd_patterns.get_sim_angle(va, vb)
    frq_main_um = frq_vects[n1max, n2max + 1]

    plt.suptitle("DMD period=%0.3f mirrors, angle=%0.2fdeg\n"
                 "Camera period=%0.1fnm = 1/%0.3f um, angle=%0.2fdeg\n"
                 "va=(%d, %d); vb=(%d, %d)" % (period, angle * 180/np.pi, 1 / np.linalg.norm(frq_main_um) * 1e3,
                                               np.linalg.norm(frq_main_um),
                                               np.mod(np.angle(frq_main_um[0] + 1j * frq_main_um[1]), 2*np.pi) * 180/np.pi,
                                               va[0], va[1], vb[0], vb[1]))

    plt.subplot(grid[0, 0:2])
    plt.imshow(img_roi)
    plt.title('image')

    plt.subplot(grid[0, 2:4])
    plt.imshow(pattern_xformed)
    plt.title('pattern after affine xform')

    ax = plt.subplot(grid[0, 4:6])
    plt.title('image FFT')

    plt.imshow(np.abs(img_ft) ** 2, norm=PowerNorm(gamma=0.1), extent=extent)

    # to_plot = np.logical_not(np.isnan(intensity_exp_norm))
    nmax = int(np.round((frq_vects.shape[1] - 1) * 0.5))
    plt.scatter(frq_vects[to_use, 0].ravel(), frq_vects[to_use, 1].ravel(), facecolor='none', edgecolor='r')
    plt.scatter(-frq_vects[to_use, 0].ravel(), -frq_vects[to_use, 1].ravel(), facecolor='none', edgecolor='m')
    # plt.scatter(frq_vects[nmax, nmax + 1, 0], frq_vects[nmax, nmax + 1, 1], facecolor="none", edgecolor='k')
    # plt.scatter(frq_vects[nmax, nmax - 1, 0], frq_vects[nmax, nmax - 1, 1], facecolor="none", edgecolor='k')
    # plt.scatter(frq_vects[nmax, nmax + 2, 0], frq_vects[nmax, nmax + 2, 1], facecolor="none", edgecolor='k')
    # plt.scatter(frq_vects[nmax, nmax - 2, 0], frq_vects[nmax, nmax - 2, 1], facecolor="none", edgecolor='k')

    circ = matplotlib.patches.Circle((0, 0), radius=fmax_img, color='k', fill=0, ls='--')
    ax.add_artist(circ)

    if fmax_in is not None:
        circ2 = matplotlib.patches.Circle((0, 0), radius=(fmax_in/2), color='r', fill=0, ls='--')
        ax.add_artist(circ2)

    plt.xlim([-fmax_img, fmax_img])
    plt.ylim([fmax_img, -fmax_img])

    ax = plt.subplot(grid[1, :2])
    plt.title("peaks amp expt/theory")
    plt.xlabel("Frequency (1/um)")
    plt.ylabel("Intensity")

    plt.plot([fmax_img, fmax_img], [0, 1], 'k')

    phs = []
    legend_entries = []

    if peak_int_theory is not None:
        ph, = ax.plot(fmags[to_use], np.abs(peak_int_theory[to_use]).ravel() / np.nanmax(np.abs(peak_int_theory[to_use])), '.')
        phs.append(ph)
        legend_entries.append("theory")

    if peak_int_exp is not None:
        if peak_int_exp_unc is None:
            peak_int_exp_unc = np.zeros(peak_int_exp.shape)

        ph = ax.errorbar(fmags[to_use], np.abs(peak_int_exp[to_use]).ravel() / np.nanmax(np.abs(peak_int_exp)),
                         yerr=peak_int_exp_unc[to_use].ravel() / np.nanmax(np.abs(peak_int_exp)), fmt='x')
        phs.append(ph)
        legend_entries.append("experiment")

    ax.set_ylim([1e-4, 1.2])
    ax.set_xlim([-0.1 * fmax_img, 1.1 * fmax_img])
    ax.set_yscale('log')

    plt.legend(phs, legend_entries)

    # plot phase
    ax = plt.subplot(grid[1, 2:4])
    plt.title("peaks phase expt/theory")
    plt.xlabel("Frequency (1/um)")
    plt.ylabel("phase")

    plt.plot([fmax_img, fmax_img], [-np.pi, np.pi], 'k')

    phs = []
    legend_entries = []

    if peak_int_theory is not None:
        ph, = ax.plot(fmags[to_use], np.angle(peak_int_theory[to_use]).ravel(), '.')
        phs.append(ph)
        legend_entries.append("theory")

    if peak_int_exp is not None:
        ph, = ax.plot(fmags[to_use], np.angle(peak_int_exp[to_use]).ravel(), 'x')
        phs.append(ph)
        legend_entries.append("experiment")

    ax.set_xlim([-0.1 * fmax_img, 1.1 * fmax_img])

    plt.legend(phs, legend_entries)

    # plot otf
    ax = plt.subplot(grid[1, 4:])
    plt.title("otf")
    plt.xlabel("Frequency (1/um)")
    plt.ylabel("otf")

    ax.plot([0, fmax_img], [0, 0], 'k')
    ax.plot([fmax_img, fmax_img], [0, 1], 'k')
    if otf is not None:
        if otf_unc is None:
            otf_unc = np.zeros(otf.shape)
        ax.errorbar(fmags[to_use], np.abs(otf[to_use]).ravel(), yerr=otf_unc[to_use].ravel(), fmt='.')

    ax.set_ylim([-0.05, 1.2])
    ax.set_xlim([-0.1 * fmax_img, 1.1 * fmax_img])

    return figh

def plot_otf(frq_vects, fmax_img, otf, otf_unc=None, to_use=None, wf_corrected=None, figsize=(20, 10)):
    """
    Plot complete OTF
    :param frq_vects:
    :param fmax_img:
    :param otf:
    :param figsize:
    :return:
    """
    if otf_unc is None:
        otf_unc = np.zeros(otf.shape)

    if to_use is None:
        to_use = np.ones(otf.shape, dtype=np.int)

    nmax1 = int(np.round(0.5 * (otf.shape[1] - 1)))
    nmax2 = int(np.round(0.5 * (otf.shape[2] - 1)))

    fmag = np.linalg.norm(frq_vects, axis=-1)

    fmag_interp = np.linspace(0, fmax_img, 1000)
    # only care about fmax value, so create na/wavelength that give us this
    na = 1
    wavelength = 2 * na / fmax_img
    otf_ideal = fit_psf.circ_aperture_otf(fmag_interp, 0, na, wavelength)

    figh = plt.figure(figsize=figsize)
    grid = plt.GridSpec(2, 6)

    # 1D otf
    ax = plt.subplot(grid[0, :2])
    ylim = [-0.05, 1.2]
    plt.title("otf mag")
    plt.xlabel("Frequency (1/um)")
    plt.ylabel("otf")

    ph_ideal, = plt.plot(fmag_interp, otf_ideal, 'k')
    plt.errorbar(fmag[to_use], np.abs(otf[to_use]), yerr=otf_unc[to_use], color="b", fmt='.')

    colors = ["g", "m", "r", "y", "c"]
    phs = [ph_ideal]
    labels = ["OTF ideal, fmax=%0.2f (1/um)" % fmax_img] + list(range(1, 6))
    # plot main series peaks
    for jj in range(1, 6):
        ph = plt.errorbar(fmag[:, nmax1, nmax2 + jj][to_use[:, nmax1, nmax2 + jj]],
                     np.abs(otf[:, nmax1, nmax2 + jj][to_use[:, nmax1, nmax2 + jj]]),
                     yerr=otf_unc[:, nmax1, nmax2 + jj][to_use[:, nmax1, nmax2 + jj]],
                     color=colors[jj - 1], fmt=".")
        phs.append(ph)

        plt.errorbar(fmag[:, nmax1, nmax2 - jj][to_use[:, nmax1, nmax2 - jj]],
                     np.abs(otf[:, nmax1, nmax2 - jj][to_use[:, nmax1, nmax2 - jj]]),
                     yerr=otf_unc[:, nmax1, nmax2 - jj][to_use[:, nmax1, nmax2 - jj]],
                     color=colors[jj - 1], fmt=".")

    plt.legend(phs, labels)

    xlim = ax.get_xlim()
    plt.plot(xlim, [0, 0], 'k')
    plt.plot([fmax_img, fmax_img], ylim, 'k')
    ax.set_xlim(xlim)
    ax.set_ylim(ylim)

    # 1D log scale
    ax = plt.subplot(grid[1, :2])
    plt.title("otf mag (log scale)")
    plt.xlabel("Frequency (1/um)")
    plt.ylabel("otf")

    plt.plot(fmag_interp, otf_ideal, 'k')
    plt.errorbar(fmag[to_use], np.abs(otf[to_use]), yerr=otf_unc[to_use], fmt='.')

    # plot main series peaks
    for jj in range(1, 6):
        plt.errorbar(fmag[:, nmax1, nmax2 + jj][to_use[:, nmax1, nmax2 + jj]],
                     np.abs(otf[:, nmax1, nmax2 + jj][to_use[:, nmax1, nmax2 + jj]]),
                     yerr=otf_unc[:, nmax1, nmax2 + jj][to_use[:, nmax1, nmax2 + jj]],
                     color=colors[jj - 1], fmt=".")

        plt.errorbar(fmag[:, nmax1, nmax2 - jj][to_use[:, nmax1, nmax2 - jj]],
                     np.abs(otf[:, nmax1, nmax2 - jj][to_use[:, nmax1, nmax2 - jj]]),
                     yerr=otf_unc[:, nmax1, nmax2 - jj][to_use[:, nmax1, nmax2 - jj]],
                     color=colors[jj - 1], fmt=".")

    xlim = ax.get_xlim()
    ax.plot([fmax_img, fmax_img], ylim, 'k')
    ax.set_xlim(xlim)
    ax.set_ylim([1e-4, 1.2])

    ax.set_yscale('log')

    # show widefield corrected/not peaks
    ax = plt.subplot(grid[1, 4:])
    ylim = [-0.05, 1.2]
    plt.title("otf mag, widefield corrected/not")
    plt.xlabel("Frequency (1/um)")
    plt.ylabel("otf")

    plt.plot(fmag_interp, otf_ideal, 'k')
    phu = plt.errorbar(fmag[to_use], np.abs(otf[to_use]), yerr=otf_unc[to_use], color="b", fmt='.')

    corrected = np.logical_and(wf_corrected, to_use)
    phc = plt.errorbar(fmag[corrected], np.abs(otf[corrected]), yerr=otf_unc[corrected], color="r", fmt=".")

    xlim = ax.get_xlim()
    plt.plot(xlim, [0, 0], 'k')
    plt.plot([fmax_img, fmax_img], ylim, 'k')
    ax.set_xlim(xlim)
    ax.set_ylim(ylim)

    plt.legend([phu, phc], ["uncorrected peaks", "corrected"])

    # 2D otf
    ax = plt.subplot(grid[0, 2:4])
    plt.title("2D otf (log scale)")
    plt.xlabel("fx (1/um)")
    plt.ylabel("fy (1/um)")
    clims = [1e-3, 1]

    frqs_pos = np.array(frq_vects, copy=True)
    y_is_neg = frq_vects[..., 1] < 0
    frqs_pos[y_is_neg] = -frqs_pos[y_is_neg]

    plt.plot([-fmax_img, fmax_img], [0, 0], 'k')
    plt.scatter(frqs_pos[to_use, 0].ravel(), frqs_pos[to_use, 1].ravel(),
                c=np.log10(np.abs(otf[to_use]).ravel()),
                norm=matplotlib.colors.Normalize(vmin=np.log10(clims[0]), vmax=np.log10(clims[1])))
    cb = plt.colorbar()
    plt.clim(np.log10(clims))

    circ = matplotlib.patches.Circle((0, 0), radius=fmax_img, color='k', fill=0, ls='-')
    ax.add_artist(circ)
    ax.set_xlim([-fmax_img, fmax_img])
    ax.set_ylim([-0.05 * fmax_img, fmax_img])

    # plot phase
    ax = plt.subplot(grid[1, 2:4])
    plt.title("phase")
    plt.xlabel("Frequency (1/um)")
    plt.ylabel("phase")

    ax.plot(fmag[to_use], np.angle(otf[to_use]).ravel(), '.')

    ylims = [-np.pi - 0.1, np.pi + 0.1]
    ax.set_ylim(ylims)

    # plot 2D phase
    ax = plt.subplot(grid[0, 4:])
    plt.title("2D otf phase")
    plt.xlabel("fx (1/um)")
    plt.ylabel("fy (1/um)")
    clims_phase = [-np.pi - 0.1, np.pi + 0.1]

    plt.plot([-fmax_img, fmax_img], [0, 0], 'k')
    plt.scatter(frqs_pos[to_use, 0].ravel(), frqs_pos[to_use, 1].ravel(),
                c=np.angle(otf[to_use]),
                norm=matplotlib.colors.Normalize(vmin=clims_phase[0], vmax=clims_phase[1]))
    cb = plt.colorbar()
    plt.clim(clims_phase)

    circ = matplotlib.patches.Circle((0, 0), radius=fmax_img, color='k', fill=0, ls='-')
    ax.add_artist(circ)
    ax.set_xlim([-fmax_img, fmax_img])
    ax.set_ylim([-0.05 * fmax_img, fmax_img])

    return figh


import numpy as np
import mabd_llcd_class_v1 as AmabdLLCD
import rss_editor_class as anRSSeditor
import matplotlib.pyplot as plt

####################
# Network parameters
numNodes = 8
numCh = 4

####################
# RSS data files
rss_data_f_name = 'data/rss_data/meb/rss_data_2015_10_19_all_2.txt'

####################
# RSS editors
fb_choice = 'fb'
ch_list = [0,1,2,3] # \in 0,1,2,...,C-1

node_list = np.arange(numNodes)+1 # \in 1,2,...,N
my_rss_editor_1 = anRSSeditor.RssEditor(numNodes, numCh, ch_list, node_list, fb_choice)

#################
# MABD parameters
stb_len = 5  # short term buffer length
ltb_len = 20 # long term buffer length
stateb_len = 12 # state buffer length
tau = 0.025   # threshold
num_consec = 2
out_type = 'a'

my_mabd = AmabdLLCD.myMABDClass(my_rss_editor_1, stb_len, ltb_len, stateb_len, tau, num_consec, out_type)

######################
# Loop through data
states_all = []
times_all = []

with open(rss_data_f_name, 'r') as f:
    for line in f:

        my_mabd.observe(line)
        states_all.append(my_mabd.get_state_est().tolist())
        times_all.append(my_mabd.get_time())

states_all = np.array(states_all)
times_all = np.array(times_all)
times_all = times_all - times_all[0]

plt.plot(times_all,states_all[:,0],'r-')
plt.plot(times_all,states_all[:,1],'k--')
plt.plot(times_all,states_all[:,2],'g-.')

# plt.plot(times_all,states_all[:,3],'r-')
# plt.plot(times_all,states_all[:,4],'k--')
# plt.plot(times_all,states_all[:,5],'g-.')
# plt.plot(times_all,states_all[:,6],'m-')
plt.ylim([0,1.5])
plt.grid()
plt.show()


# -*- coding: utf-8 -*-
"""
Created on Sat May  8 09:01:16 2021

@author: jkfra
"""

# Ensure all keys in dictionary list
# Using set() + chain.from_iterable() + get() + list comprehension
from itertools import chain

# initializing list
test_list = [{'frason' : 1,
              'kevin' : 3},
			{'soundarya' : 4,
            'ishika' : 6,
            'alana' : 5},
			{'adnan' : 8}]

# printing original list
print("The original list is : " + str(test_list))

# extracting all keys
all_keys = set(chain.from_iterable(test_list))

# assigning None using get() if key's value is not found
res = [dict((key, sub.get(key, None)) for key in all_keys) for sub in test_list]

# printing result
print("Reformed dictionaries list : " + str(res))


#!/usr/bin/python
# -*- codding: utf-8 -*-
import os
import sys
sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(__file__))))
from common.execute_command import write_one_parameter

# url : https://awscli.amazonaws.com/v2/documentation/api/latest/reference/glue/delete-database.html
if __name__ == '__main__':
    """
	create-database : https://awscli.amazonaws.com/v2/documentation/api/latest/reference/glue/create-database.html
	get-database : https://awscli.amazonaws.com/v2/documentation/api/latest/reference/glue/get-database.html
	get-databases : https://awscli.amazonaws.com/v2/documentation/api/latest/reference/glue/get-databases.html
	update-database : https://awscli.amazonaws.com/v2/documentation/api/latest/reference/glue/update-database.html
    """

    parameter_display_string = """
    # name : The name of the database to delete. For Hive compatibility, this must be all lowercase.
    """
    add_option_dict = {}

    #######################################################################
    # parameter display string
    add_option_dict["parameter_display_string"] = parameter_display_string
    # ex: add_option_dict["no_value_parameter_list"] = "--single-parameter"
    write_one_parameter("glue", "delete-database", "name", add_option_dict)


# -*- coding: utf-8 -*-
from django.contrib import admin

from .models import Author, Topic, Comment

class AuthorAdmin(admin.ModelAdmin):
    list_display = (u'id', 'created', 'modified', 'login', 'username')
    list_filter = ('created', 'modified')
admin.site.register(Author, AuthorAdmin)

class TopicAdmin(admin.ModelAdmin):
    list_display = (
        u'id',
        'created',
        'modified',
        'url',
        'title',
        'text',
        'date',
        'author_url',
        'author',
    )
    list_filter = ('created', 'modified', 'date', 'author')
admin.site.register(Topic, TopicAdmin)

class CommentAdmin(admin.ModelAdmin):
    list_display = (
        u'id',
        'created',
        'modified',
        'date',
        'date_string',
        'url',
        'author_url',
        'author',
    )
    list_filter = ('created', 'modified', 'date', 'author', 'topic')
admin.site.register(Comment, CommentAdmin)


# -*- coding: utf-8 -*-

# @Time    : 2019/12/10
# @Author  : Lattine

# ======================
import six
import sys
import cv2
import lmdb
import torch
import numpy as np
from torch.utils.data import Dataset

class LmdbDataset(Dataset):
    def __init__(self, root, transform=None, height=32):
        self.env = lmdb.open(root, max_readers=1, readonly=True, lock=False, readahead=False, meminit=False)
        if not self.env:
            print(f"cannot create lmdb form {root}")
            sys.exit(0)
        with self.env.begin(write=False) as txn:
            self.n_samples = int(txn.get("total-samples".encode()))
        self.transform = ResizeNormalize(height) if transform is None else transform

    def __len__(self):
        return self.n_samples

    def __getitem__(self, ix):
        assert ix < len(self), "INDEX ERROR"
        with self.env.begin(write=False) as txn:
            image_key = "image-%09d" % ix
            text_key = 'text-%09d' % ix
            label_key = "label-%09d" % ix
            length_key = 'length-%09d' % ix
            try:
                img_buf = txn.get(image_key.encode())
                image_buf = np.fromstring(img_buf, dtype=np.uint8)
                img = cv2.imdecode(image_buf, cv2.IMREAD_GRAYSCALE)
                img = self.transform(img)
                img = img.unsqueeze(0)
            except IOError:
                print(f"raise error for {image_key}")
                return self[ix + 1]

            label = eval(txn.get(label_key.encode()).decode())
            length = eval(txn.get(length_key.encode()).decode())
            label, length = torch.IntTensor(label), torch.IntTensor(length)
            text = txn.get(text_key.encode()).decode()

        return img, label, length, text

class ResizeNormalize:
    def __init__(self, height):
        self.h = height

    def __call__(self, src):
        img = (255 - src) / 255.0  # 归一化
        img = torch.FloatTensor(img)
        return img

class AlignCollate:
    def __init__(self):
        pass

    def __call__(self, batch):
        images, labels, lengths, text = zip(*batch)
        images = torch.stack(images, dim=0)
        labels = torch.stack(labels, dim=0)
        lengths = torch.cat(lengths)

        return images, labels, lengths, text


"""Main WSGI application. Just URL routes to the other modules."""
import importlib

from oauth_dropins.webutil import appengine_info, appengine_config, handlers
import webapp2

routes = []
for module in (
  'activitypub',
  'add_webmention',
  'logs',
  'redirect',
  'render',
  'salmon',
  'superfeedr',
  'webfinger',
  'webmention',
):
  routes += importlib.import_module(module).ROUTES

application = handlers.ndb_context_middleware(
    webapp2.WSGIApplication(routes, debug=appengine_info.DEBUG),
    client=appengine_config.ndb_client)


if __name__ == '__main__':
    import os,sys
    sys.path.append(os.pardir)

    from chapter04.knock30 import iterate_neko
    from collections import defaultdict

    phrases = defaultdict(int)

    for morphs in iterate_neko():
        for m1, m2, m3 in zip(*[morphs[i:] for i in range(3)]):
            if m1.pos == '名詞' and \
                m2.surface == 'の' and \
                m3.pos == '名詞':
                phrase = m1.surface + m2.surface + m3.surface
                phrases[phrase] += 1

    for v, c in phrases.items():
        print(f'{v} ({c} times)')

    print('----------')
    print(f'{len(phrases)} phrases')


import pytest

from enviador_app.enviador_app import Enviador, EmailInvalido

def test_enviador_de_email():
    enviador = Enviador()
    assert enviador is not None

@pytest.mark.parametrize(
    'destinatario',
    ['luciana@coitinho.com', 'gustavo@maia.com']
)
def test_destinatario(destinatario):
    enviador = Enviador()
    resultado = enviador.enviar(
        destinatario,
        'guilherme@gouw.com',
        'spam',
        'Dá um olhada no meu enviador de e-mail.'
    )
    assert destinatario in resultado

@pytest.mark.parametrize(
    'destinatario',
    ['', 'maria.tessarollo']
)
def test_destinatario_invalido(destinatario):
    enviador = Enviador()
    with pytest.raises(EmailInvalido):
        enviador.enviar(
            destinatario,
            'guilherme@gouw.com',
            'spam',
            'Dá um olhada no meu enviador de e-mail.'
        )


#NOTE pip install urllib3
from urllib.parse import urlencode, quote_plus
from urllib.request import Request, urlopen
import xml.etree.ElementTree as ET

class BusArrive:
    def __init__(self, config):
        self.config = config

    def get_bus_dict(self, target_station):
        url = 'http://ws.bus.go.kr/api/rest/stationinfo/getStationByUid'
        query_params = '?' + urlencode({
            quote_plus('ServiceKey') : self.config['STATIONINFO_APIKEY'],
            quote_plus('arsId') : target_station })

        request = Request(url + query_params)
        request.get_method = lambda: 'GET'
        response_body = urlopen(request).read()

        tree = ET.fromstring(response_body)
        bus_list = tree.find('msgBody').findall('itemList')

        bus_come = {}
        for bus in bus_list:
            #NOTE routeType: (1:공항, 2:마을, 3:간선, 4:지선,
            # 5:순환, 6:광역, 7:인천, 8:경기, 9:폐지, 0:공용)
            if (bus.find('arrmsg1').text == '곧 도착'):
                vehicle_id = bus.find('vehId1').text

                bus_come[bus.find('rtNm').text] = (
                        bus.find('routeType').text,
                        self.get_bus_plain_no(vehicle_id)
                    )

        return bus_come

    def get_bus_plain_no(self, vehicle_id):
        url = 'http://ws.bus.go.kr/api/rest/buspos/getBusPosByVehId'
        query_params = '?' + urlencode({
            quote_plus('ServiceKey'): self.config['BUSPOS_APIKEY'],
            quote_plus('vehId') : vehicle_id
        })

        request = Request(url + query_params)
        request.get_method = lambda: 'GET'
        response_body = urlopen(request).read()

        tree = ET.fromstring(response_body)
        bus_list = tree.find('msgBody').findall('itemList')

        for bus in bus_list:
            return bus.find('plainNo').text


from flask import request, abort, Response

import json
import jwt

from .. import exceptions
from .. import models

def auth_token_from_request():
    auth_token = request.headers.get('Authorization')
    if auth_token is None:
        raise exceptions.AuthTokenNotSetError()

    try:
        auth_token_id = models.AuthTokenModel.decode_auth_token(auth_token)
    except jwt.ExpiredSignatureError:
        raise exceptions.AuthTokenExpiredError()
    except jwt.InvalidTokenError:
        raise exceptions.AuthTokenInvalidError()

    auth_token = models.AuthTokenModel.objects.with_id(auth_token_id)
    if not auth_token or auth_token.revoked:
        raise exceptions.AuthTokenInvalidError()

    elif not auth_token.user or not auth_token.user.activated:
        raise exceptions.AuthUserDeactivatedError()

    return auth_token


import statistics
from typing import List, Optional

def main():
    rows = []
    with open('inputs/10.txt') as input_file:
        for line in input_file:
            pbs = [c for c in line.strip()]
            rows.append(pbs)
    t1_score = task_1(rows)
    return t1_score, task_2(rows)

def task_1(rows: List[List[str]]) -> List[str]:
    points = {')': 3, ']': 57, '}': 1197, '>': 25137}
    bad_chars = []
    for r in rows:
        bc = find_corrupted(r)
        if bc is not None:
            bad_chars.append(bc)
    return sum([points[b] for b in bad_chars])

def task_2(rows):
    pairs = {'(': ')', '[': ']', '{': '}', '<': '>'}
    rev_pairs = {y: x for x, y in pairs.items()}
    points = {')': 1, ']': 2, '}': 3, '>': 4}
    scores = []
    for r in rows:
        if find_corrupted(r) is not None:
            continue
        remainder = find_incomplete(r)
        score = 0
        for c in remainder[::-1]:
            score = score * 5
            score += points[pairs[c]]
        scores.append(score)
    return statistics.median(scores)

def find_corrupted(row: List[str]) -> Optional[str]:
    temp_row = []
    pairs = {'(': ')', '[': ']', '{': '}', '<': '>'}
    rev_pairs = {y: x for x, y in pairs.items()}
    for c in row:
        if c in ['(', '[', '{', '<']:
            temp_row.append(c)
        else:
            if not temp_row.pop() == rev_pairs[c]:
                return c
    return None

def find_incomplete(row: List[str]) -> List[str]:
    temp_row = []
    pairs = {'(': ')', '[': ']', '{': '}', '<': '>'}
    rev_pairs = {y: x for x, y in pairs.items()}
    for c in row:
        if c in ['(', '[', '{', '<']:
            temp_row.append(c)
        else:
            if not temp_row.pop() == rev_pairs[c]:
                raise Exception
    return temp_row

if __name__ == '__main__':
    result = main()
    print(result)


#!/usr/bin/env python
#
# Copyright 2009 Facebook
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web

from cuttingstock.GeneticSolver import GeneticSolver

from tornado.options import define, options

define("port", default=8888, help="run on the given port", type=int)

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        items = ["Item 1", "Item 2", "Item 3"]
        self.render("UI/index.html", title="My title", items=items)

class SolutionHandler(tornado.web.RequestHandler):
    def get(self):
        output=[]
        inputDict = {}
        stocksize=int(self.get_argument("max-size", default="0", strip=False))
        for i in range(0,(len(self.request.arguments)/2)):
            inputDict.update({int(self.get_argument("size"+str(i), default="0", strip=False)):int(self.get_argument("qty"+str(i), default="0", strip=False))})
        a=GeneticSolver(inputDict,stocksize)
        chromo = a.getResult()
        i=1
        for gene in chromo.genes:
            res=""
            for key,value in gene.getDict().iteritems():
                if(value>0):
                    res=res+","+str(key)+"*"+str(value)+" "
            output.append(res)
            i+=1
        self.render("UI/sol.html", outp=output,req=inputDict)

def main():
    tornado.options.parse_command_line()
    application = tornado.web.Application([
        (r"/", MainHandler),
        (r'/static/(.*)', tornado.web.StaticFileHandler, {'path': 'UI/static/'}),
        (r"/solution",SolutionHandler)
    ])
    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

if __name__ == "__main__":
    main()


import discord
from discord.ext import commands
from discord.ext.commands import bot
from discord.utils import get
from core import gestion as ge
from DB import SQLite as sql

rolelist = ["Baron du Bastion", "Inquisiteur du Bastion", "BastioBot", "PEGI master", "Groovy", "Joueurs", "Archive", "Nouveau"]

async def addrole(member, role):
    setrole = get(member.guild.roles, name=role)
    if setrole != None:
        await member.add_roles(setrole)
    else:
        await print("Role introuvable")

async def removerole(member, role):
    setrole = get(member.guild.roles, name=role)
    if setrole != None:
        await member.remove_roles(setrole)
    else:
        await print("Role introuvable")

class Roles(commands.Cog):

    def __init__(self, ctx):
        return(None)

    @commands.command(pass_context=True, aliases=['gamecreate'])
    async def rolecreate(self, ctx, game, categorie = None):
        """**[role]** | Permet de créer un nouveau role pour un jeu"""
        # Paramètres:
        # - game: Nom du jeu/role
        # - categorie: Nom du grand salon (combat/societe/tirs/voiture/rpg/sandbox/strategie/divers)
        guild = ctx.guild
        member = ctx.author
        rolesearch = discord.utils.get(member.guild.roles, name=game)
        if ge.permission(ctx, ge.Inquisiteur):
            if rolesearch == None:
                await guild.create_role(name=game)
                desc = "Le jeu '{0}' a été créé".format(game)

                if categorie != None:
                    rolesearch = discord.utils.get(member.guild.roles, name=game)
                    categorie = categorie.lower()

                    if categorie == "combat":
                        channeladd = guild.get_channel(589944955800256515)
                    elif categorie == "societe":
                        channeladd = guild.get_channel(589945591203889152)
                    elif categorie == "tirs":
                        channeladd = guild.get_channel(589946246437797888)
                    elif categorie == "voiture":
                        channeladd = guild.get_channel(589946276540448821)
                    elif categorie == "rpg":
                        channeladd = guild.get_channel(589946305917222916)
                    elif categorie == "sandbox":
                        channeladd = guild.get_channel(589946380416581632)
                    elif categorie == "strategie":
                        channeladd = guild.get_channel(589953946639007764)
                    elif categorie == "divers":
                        channeladd = guild.get_channel(590664052318142474)
                    else:
                        channeladd = guild.get_channel(589942497678196764)# 590664052318142474
                    await channeladd.set_permissions(rolesearch, overwrite=discord.PermissionOverwrite(read_messages=True))
                    desc += "Ajout d'un nouveau jeu dans la catégorie {}: {}".format(channeladd.mention, rolesearch.mention)
                    # channel = guild.get_channel(417449076775321600)
                msg = discord.Embed(title = "Création de jeu", color= 13752280, description = desc)
                await ctx.channel.send(embed = msg)
            else:
                await ctx.channel.send("Le jeu {0} existe déjà".format(game))
        else :
            await ctx.channel.send("Tu ne peux pas exécuter cette commande.")

    @commands.command(pass_context=True, aliases=['gameadd'])
    async def roleadd(self, ctx, role, nom = None):
        """**[role]** | Permet de s'ajouter des roles (Pour les Inquisiteurs, mentionner l'utilisateur cible apres le role pour lui affecter)"""
        if ge.permission(ctx, ge.Joueurs):
            if nom != None:
                if ge.permission(ctx, ge.Inquisiteur):
                    ID = sql.nom_ID(nom)
                    nom = ctx.guild.get_member(ID)
                    nom = nom.name
                else:
                    await ctx.channel.send("Tu peux exécuter cette commande uniquement pour toi.")
                    return
            else:
                ID = ctx.author.id
                nom = ctx.author.name
            user = get(ctx.guild.members, id=ID)
            if user:
                setrole = get(user.guild.roles, name=role)
                if ge.permission(ctx, ge.Inquisiteur) is False:
                    for i in range(0, len(rolelist)):
                        if role == rolelist[i]:
                            await ctx.channel.send("Tu ne peux pas exécuter cette commande avec ce role.")
                            return
                await user.add_roles(setrole)
                desc = "Le role `{0}` a été ajouté à {1}".format(role, nom)
                msg = discord.Embed(title = "Ajout de jeu", color= 13752280, description = desc)
                await ctx.channel.send(embed = msg)
                return
            else:
                await ctx.channel.send("L'utilisateur n'as pas été trouvé.")
        else:
            await ctx.channel.send("Tu ne peux pas exécuter cette commande.")

    @commands.command(pass_context=True, aliases=['gameremove'])
    async def roleremove(self, ctx, role, nom = None):
        """**[role]** | Permet de s'enlever des roles (Pour les Inquisiteurs, mentionner l'utilisateur cible apres le role pour lui enlever)"""
        if ge.permission(ctx, ge.Joueurs):
            if nom != None:
                if ge.permission(ctx, ge.Inquisiteur):
                    ID = sql.nom_ID(nom)
                    nom = ctx.guild.get_member(ID)
                    nom = nom.name
                else:
                    await ctx.channel.send("Tu peux exécuter cette commande uniquement pour toi.")
                    return
            else:
                ID = ctx.author.id
                nom = ctx.author.name
            user = get(ctx.guild.members, id=ID)
            if user:
                setrole = get(user.guild.roles, name=role)
                await user.remove_roles(setrole)
                desc = "Le role `{0}` a été enlevé à {1}".format(role, nom)
                msg = discord.Embed(title = "Retrait de jeu", color=9109504, description = desc)
                await ctx.channel.send(embed = msg)
                return
            else:
                await ctx.channel.send("L'utilisateur n'as pas été trouvé.")
        else:
            await ctx.channel.send("Tu ne peux pas exécuter cette commande.")

    @commands.command(pass_context=True, aliases=['gamelist'])
    async def rolelist(self, ctx):
        """Affiche la liste des rôles disponible"""
        desc = ""
        jsonlist = ctx.guild.roles
        rolelist = []
        gamelist = []
        check = False
        for i in range(0, len(jsonlist)):
            temp = "{}".format(jsonlist[i])
            rolelist.append(temp)
        for i in range(0, len(rolelist)):
            if rolelist[i] == "Joueurs":
                check = False
            if check:
                gamelist.append(rolelist[i])
            if rolelist[i] == "Nouveau":
                check = True
        gamelist.sort()
        for i in range(0, len(gamelist)):
            desc += "{}\n".format(gamelist[i])
        msg = discord.Embed(title = "Liste des rôles disponible", color=35723, description = desc)
        await ctx.channel.send(embed = msg)

def setup(bot):
    bot.add_cog(Roles(bot))
    open("help/cogs.txt", "a").write("Roles\n")


import os
import xlrd
import re
import pyperclip
import requests
from openpyxl import Workbook, load_workbook
from openpyxl.styles import PatternFill
from pathlib import Path
from rich import print

def init():
    print('初始化中，请稍等...')
    version = 1.4
    print('此程序版本：' + str(version))
    try:
        urlgithub = 'https://raw.githubusercontent.com/evilbutcher/Python/master/evanescent/release.json'
        update = requests.get(urlgithub)
        ver = update.json()
        if ver['releases'][0]['version'] > version:
            print('[bold yellow]更新[/bold yellow]啦！从GitHub获取更新详情成功！\n最新版本是：' +
                  str(ver['releases'][0]['version']))
            print('更新内容是：' + ver['releases'][0]['details'])
            print('可前往：https://github.com/evilbutcher/Python 查看Releases\n')
        else:
            print('检测更新完成，暂无更新\n')
    except (Exception):
        urlgitee = 'https://gitee.com/evilbutcher/Python/raw/master/evanescent/release.json'
        try:
            update = requests.get(urlgitee)
            ver = update.json()
            if ver['releases'][0]['version'] > version:
                print('[bold red]更新[/bold red]啦！从Gitee获取更新详情成功！\n最新版本是：' +
                      str(ver['releases'][0]['version']))
                print('更新内容是：' + ver['releases'][0]['details'])
                print('可前往：https://github.com/evilbutcher/Python 查看Releases\n')
            else:
                print('检测更新完成，暂无更新\n')
        except Exception as e:
            print('检测更新失败，原因：')
            print(str(e) + '\n')
    try:
        path = Path('origindata/')
        if path.is_dir() is False:
            os.mkdir(path)
        a = pyperclip.paste()
        if a == 'debugturnon':
            return True
    except Exception as e:
        print('初始化[bold red]失败[/bold red]，原因：' + str(e))

def dealxlsx(path: str, name: str, canprint: bool):
    try:
        workbook = xlrd.open_workbook(path + '/' + name)
        sheet_name = workbook.sheet_names()[0]
        print('\n读取的Excel表名为：' + sheet_name)
        sheet = workbook.sheet_by_index(0)
        allrows = sheet.nrows
        allcols = sheet.ncols - 1
        print('一共有：' + str(allcols) + '列  ' + str(allrows) + '行（第一列时间未计入统计）')
        secend = input('请输入基准点（第几秒）：')
        valueforall = input('请输入一个基准值（自定即可）：')
        startpoint = int(secend)
        startvalue = sheet.cell(startpoint, 0).value
        print('所选取的修改起始点为：' + str(int(startvalue)) + '秒的数据')
        wb = Workbook()  # 引入result.xlsx工作表
        result = wb["Sheet"]
        if result.cell(1, 1).value is None:  # 因为两个库起始index不同，先设置一下第一行
            result.cell(1, 1).value = 0
            if canprint is True:
                print('\n1列1行 写入时间：0秒\n')
        for col in range(1, allcols + 1):  # 获取数据excel每列与基准值的差值
            minus = sheet.cell(startpoint, col).value - float(valueforall)
            print('第' + str(col) + '列截取的起始数据点为：' +
                  str(sheet.cell(startpoint, col).value))
            print('第' + str(col) + '列与基准值的差为：' + str(minus) + '\n')
            vcols = sheet.col_values(col)
            result.cell(1, col + 1).value = float(
                valueforall)  # 因为两个库起始index不同，先设置一下第一行
            if canprint is True:
                print(
                    str(col + 1) + '列1行' + '写入数据：' + str(float(valueforall)) +
                    '\n')
            for num in range(1, len(vcols)):  # 获取数据excel每行的数据，写入index+1的位置
                if result.cell(num + 1, 1).value is None:
                    result.cell(num + 1, 1).value = int(num)
                    if canprint is True:
                        print('1列' + str(num + 1) + '行 写入时间：' + str(int(num)) +
                              '秒' + '\n')
                if num > startpoint:
                    if canprint is True:
                        print(
                            str(col + 1) + '列' + str(num + 1) + '行' + '读取数据：' +
                            str(sheet.cell(num, col).value))
                    if isinstance(sheet.cell(num, col).value, float) is True:
                        result.cell(
                            num + 1,
                            col + 1).value = sheet.cell(num, col).value - minus
                    else:
                        print(
                            str(col) + '列' + str(num + 1) +
                            '行 读取数据[bold red]错误[/bold red]，请检查相应位置，此处选用上一个数值')
                        if isinstance(sheet.cell(num - 1, col).value,
                                      float) is True:
                            result.cell(num + 1, col + 1).value = sheet.cell(
                                num - 1, col).value - minus
                        else:
                            print(
                                str(col) + '列' + str(num + 1) +
                                '行 读取数据出现[bold red]连续错误[/bold red]，请检查数据完整性')
                            return
                    if canprint is True:
                        print(
                            str(col + 1) + '列' + str(num + 1) + '行' + '写入数据：' +
                            str(float(sheet.cell(num, col).value - minus)) +
                            '\n')
                else:
                    if canprint is True:
                        print(
                            str(col + 1) + '列' + str(num + 1) + '行' + '读取数据：' +
                            str(sheet.cell(num, col).value))
                    result.cell(num + 1, col + 1).value = float(valueforall)
                    if canprint is True:
                        print(
                            str(col + 1) + '列' + str(num + 1) + '行' + '写入数据：' +
                            str(float(valueforall)) + '\n')
        wb.save("result.xlsx")
        print('[bold green]数据处理完成[/bold green]')
    except Exception as e:
        print('处理excel[bold red]失败[/bold red]，原因：' + str(e))

def setcolor():
    wb = load_workbook(r'result.xlsx')
    sheetnames = wb.sheetnames
    ws = wb[sheetnames[0]]
    rows = ws.max_row
    columns = ws.max_column
    color = 'FF6666'
    fille = PatternFill('solid', fgColor=color)
    num = int(input('请输入本次实验的平行实验次数：'))
    waittocolor = []
    startnum = 1
    for m in range(0, num):
        startnum = startnum + 1
        waittocolor.append(startnum)
    for i in waittocolor:
        for k in range(i, columns + 1, num * 2):
            for j in range(1, rows + 1):
                ws.cell(j, k).fill = fille
    wb.save(r'result.xlsx')
    print('着色区分完成')

def main():
    try:
        canprint = False
        if init() is True:
            canprint = True
        name = input('请输入要处理的文件名')
        if re.search(r'xlsx|xls', name) is None:
            namewithsuffix4 = name + '.xlsx'
            path = Path('origindata/' + namewithsuffix4)
            if path.is_file() is True:
                dealxlsx('origindata/', namewithsuffix4, canprint)
            else:
                namewithsuffix3 = name + '.xls'
                path = Path('origindata/' + namewithsuffix3)
                if path.is_file() is True:
                    dealxlsx('origindata/', namewithsuffix3, canprint)
        else:
            dealxlsx('origindata/', name, canprint)
        exist = Path('result.xlsx')
        if exist.is_file() is True:
            setcolor()
        input('如有问题请前往 https://github.com/evilbutcher/Python 提出issue，请按任意键退出')
    except Exception as e:
        print('主函数运行[bold red]出现错误[/bold red]，原因：' + str(e))
        input('如有问题请前往 https://github.com/evilbutcher/Python 提出issue，请按任意键退出')

if __name__ == "__main__":
    main()


import discord
from discord.ext import commands
from discord_slash import cog_ext
from discord_slash.utils.manage_commands import create_option

class Fun(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @cog_ext.cog_slash(name="hug", description="everyone needs a hug once in a while <3",
    options=[create_option(
            name="recipient",
            description="Whom do you want to hug?",
            option_type=6, #corresponds to USER
            required=False),
            create_option(
            name="reason",
            description="Why do you want to hug them?",
            option_type=3, #corresponds to STRING
            required=False)
            ])
    async def hug(self, ctx, recipient=None, reason=None):
        mention = recipient.id if recipient else None
        myid = ctx.author_id
        if not reason:
            reason = "no reason, you simply deserve it. yeet"
        if not mention:
            await ctx.send(content="Who do you want to hug?")
        elif mention == myid:
            await ctx.send(content="Does someone need a hug? [*source* <https://www.youtube.com/watch?v=TIMj0s5dvpA>]")
        else:
            await ctx.send("<@{mention}> Everbody needs a hug. It changes your metabolism:\n Reason: {reason}".format(
                mention=mention, reason=reason),
                file=discord.File('./images/hug.gif'))

    @cog_ext.cog_slash(name="arrest", description="for some reason blahajgangers wanted to arrest one another?",
    options=[create_option(
            name="recipient",
            description="Whom do you want to arrest?",
            option_type=6, #corresponds to USER
            required=False),
            create_option(
            name="reason",
            description="Why should they be arrested?",
            option_type=3, #corresponds to STRING
            required=False)
            ])
    async def arrest(self, ctx, recipient=None, reason=None):
        mention = recipient.id if recipient else None
        myid = ctx.author_id
        if not reason:
            reason = "yeet! just for fun :)"
        if not mention:
            await ctx.send(content="Whom should I arrest?")
        elif mention == myid:
            await ctx.send(content="Ha! you can't arrest yourself.")
        else:
            await ctx.send(
                content="<@{mention}>, You're under arrest! \n reason: {reason}".format(
                    mention=mention, reason=reason))

    @cog_ext.cog_slash(name="elmoash", description="gif of ash morphing into elmo")
    async def elmoash(self, ctx):
        await ctx.send(content="https://tenor.com/view/ashwin-rise-elmo-meme-lord-rise-ashwin-meme-lord-rise-gif-22312460")

def setup(bot):
    bot.add_cog(Fun(bot))


import cv2
import numpy as np
import glob
from os.path import join, basename, splitext, isdir
import os
import random
from PIL import Image

#  mask=cv2.imread('lisa-cnn-attack/masks/mask_l1loss_uniform_rectangles.png')[:,:,0]
img_list=[i for i in glob.glob(join('lisa-cnn-attack/optimization_output/l1basedmask_uniformrectangles/noisy_images','*400.png'))]

def _imwrite(dst_file,img):
    return img.save(dst_file)

def _inpaint(img_list, mask, dst_file):
    for im in img_list:
        im_name=splitext(basename(im))[0]
        img=cv2.imread(im)
        inpainted_img = cv2.inpaint(img,mask,3, cv2.INPAINT_TELEA)
        cv2.imwrite(dst_file + im_name + '.png',inpainted_img)

def randomizeMask(k,w, mask_size=32):
    mask_arr=np.zeros(shape=(mask_size,mask_size))
    mask_in=mask_size-w+1
    w_ind_x=list()
    w_ind_y=list()
    for i in xrange(k):
        w_ind_x=w_ind_x+ [random.randint(0,mask_in)]
        w_ind_y=w_ind_y+[random.randint(0,mask_in)]
    for j in zip(w_ind_x,w_ind_y):
        mask_arr[j[0]:j[0]+w,j[1]:j[1]+w]=1
    return mask_arr

def _resizeImg(img_src, img_dst):
    img=cv2.resize(cv2.imread(img_src),(32,32))
    return cv2.imwrite(img_dst,img)

def num_size_window(k_list=[2,3,4,5,6,7,8,9,10], w_list=[4,5,6,7,8,9,10]):
    kw=[]
    for k in k_list:
        for w in w_list:
            kw=kw+[(k,w)]
    print( kw)

# c=0
# for i in kw:
#     dst_folder='inpaint_TELEA'+str(c)
#     if not isdir(join('lisa-cnn-attack', dst_folder)):
#         os.mkdir(join('lisa-cnn-attack', dst_folder))
#     for j in xrange(1000):
#         maskarr=randomizeMask(i[0],i[1])
#         mask=Image.fromarray(np.uint8(255*maskarr))
#         _imwrite(join('lisa-cnn-attack',dst_folder,str(j)+'_mask.png'),mask)
#         mask=cv2.imread(join('lisa-cnn-attack',dst_folder,str(j)+'_mask.png'))[:,:,0]
#         _inpaint(img_list, mask, join('lisa-cnn-attack',dst_folder,str(j)+'_'))
#
#     c=c+1

# img=cv2.imread('/home/xinwwei/Desktop/original_result (4).png')
# print img.shape
# img=cv2.resize(img,(32,32))
# cv2.imwrite('/home/xinwwei/Desktop/resize(4).png',img)
# print img.shape

crop_img=[i for i in glob.glob("./others/crop/" + "*.jpg")]
print(len(crop_img))
for img_src in crop_img:
    im_name = splitext(basename(img_src))[0]
    img_dst="./others/crop/new/" + im_name + " _resized.png"
    _resizeImg(img_src,img_dst)