from http.client import FOUND
from turtle import title
from bottle import get, post, run, request, response
import sqlite3
from urllib.parse import unquote

db = sqlite3.connect("theathers.sqlite")

@get('/ping')
def get_ping():
    return("pong")

@post('/reset')
def post_reset():
    c = db.cursor()
    print("Resetting Database")
    c.executescript(
        """
        PRAGMA foreign_keys=OFF;

        DROP TABLE IF EXISTS theaters;
        DROP TABLE if EXISTS screenings;
        DROP TABLE IF EXISTS movies;
        DROP TABLE IF EXISTS tickets;
        DROP TABLE IF EXISTS customers;

        PRAGMA foreign_keys=ON;

        CREATE TABLE theaters(
            theater_name    TEXT,
            capacity        INT,
            PRIMARY KEY (theater_name)
        );

        CREATE TABLE screenings(
            screening_id    TEXT DEFAULT (lower(hex(randomblob(16)))),
            starting_date      DATE,
            starting_time      TIME,
            theater_name    TEXT,
            imdb_key        TEXT,
            FOREIGN KEY (theater_name) REFERENCES theaters(theater_name),
            FOREIGN KEY (imdb_key) REFERENCES movies(imdb_key),
            PRIMARY KEY (screening_id)
        );

        CREATE TABLE movies(
            imdb_key        TEXT,
            title           TEXT,
            production_year INT,
            running_time    INT,
            PRIMARY KEY (imdb_key)
        );

        CREATE TABLE tickets(
            ticket_id       TEXT DEFAULT (lower(hex(randomblob(16)))),
            screening_id    TEXT,
            username        TEXT,
            FOREIGN KEY (screening_id) REFERENCES screenings(screening_id),
            FOREIGN KEY (username) REFERENCES customers(username),
            PRIMARY KEY (ticket_id)
        );

        CREATE TABLE customers(
            username            TEXT,
            customer_name       TEXT,
            customer_password   TEXT,
            PRIMARY KEY (username)
        );

        INSERT
        INTO theaters(theater_name,capacity)
        VALUES
        ('Kino','10'),
        ('Regal','16'),
        ('Skandia','100');

        """
    )
    print("Database Reset")

@post('/users')
def post_addUser():
    user = request.json
    c = db.cursor()
    try:
        c.execute(
            """
            INSERT
            INTO customers(username,customer_name,customer_password)
            VALUES (?,?,?)
            RETURNING username
            """,
            [user['username'],user['fullName'],user['pwd']]
        )
        found = c.fetchone()
        if not found:
            response.status = 500
            return "Something went wrong"
            print("shit")
        else:
            response.status = 201
            username, = found
            return f"/users/{username}"
    except sqlite3.IntegrityError:
        response.status = 400
        return ""

@post('/movies')
def post_addUser():
    movie = request.json
    c = db.cursor()
    try:
        c.execute(
            """
            INSERT
            INTO movies(imdb_key,title,production_year)
            VALUES (?,?,?)
            RETURNING imdb_key
            """,
            [movie['imdbKey'],movie['title'],movie['year']]
        )
        found = c.fetchone()
        if not found:
            response.status = 500
            return "Something went wrong"
            print("shit")
        else:
            response.status = 201
            imdbKey, = found
            return f"/movies/{imdbKey}"
    except sqlite3.IntegrityError:
        response.status = 400
        return ""

@get('/movies')
def get_movies():
    query = """
        SELECT   imdb_key, title, production_year
        FROM     movies
        WHERE    1 = 1
        """
    params = []
    if request.query.title:
        query += " AND title = ?"
        params.append(unquote(request.query.title))
    if request.query.year:
        query += " AND production_year = ?"
        params.append(request.query.year)
    c = db.cursor()
    c.execute(query,params)
    found = [{"imdbKey": imdb_key, "title": title, "year": production_year}
         for imdb_key, title, production_year in c]
    response.status = 200
    return {"data": found}

@get('/movies/<imdbKey>')
def get_movies(imdbKey):
    c = db.cursor()
    c.execute(
        """
        SELECT imdb_key, title,production_year
        FROM movies
        Where imdb_key = ?
        """,
        [imdbKey]
    )
    found = [{"imdbKey":imdb_key, "title":title,"year":production_year}
        for imdb_key,title,production_year in c]
    response.status = 200
    return{"data":found}

@post('/performances')
def post_addUser():
    screening = request.json
    c = db.cursor()
    try:
        c.execute(
            """
            INSERT
            INTO screenings(imdb_key,theater_name, starting_date, starting_time)
            VALUES (?,?,?,?)
            RETURNING screening_id
            """,
            [screening['imdbKey'],screening['theater'],screening['date'],screening['time']]
        )
        found = c.fetchone()
        if not found:
            response.status = 500
            return "Something went wrong"
            print("shit")
        else:
            response.status = 201
            screening_id, = found
            return f"/performances/{screening_id}"
    except sqlite3.IntegrityError:
        response.status = 400
        return "No such movie or theater"
    db.commit()

@get('/performances')
def get_performances():
    query = """
        SELECT   screening_id, starting_date, starting_time, title, production_year, theater_name
        FROM     movies
        JOIN screenings
        USING (imdb_key)
        JOIN theaters
        USING (theater_name)
        """
    c = db.cursor()
    c.execute(query)

    found = []
    for row in c:
        screening_id = row[0]
        starting_date = row[1]
        starting_time = row[2]
        title = row[3]
        production_year = row[4]
        theater_name = row[5]
        c2 = db.cursor()
        c2.execute(
            """
            SELECT capacity
            FROM theaters
            WHERE theater_name = ?
            """, [theater_name]
            )
        capacity = c2.fetchone()[0]
        c2.execute(
            """
            SELECT count(screening_id)
            FROM tickets
            WHERE screening_id = ?

            """,[screening_id]
            )
        no_tickets = c2.fetchone()[0]
        d = dict()
        d['performanceId'] = screening_id
        d['date'] = starting_date
        d['startTime'] = starting_time
        d['title'] = title
        d['year'] = production_year
        d['theater'] = theater_name
        d['remainingSeats'] = (capacity - no_tickets)
        found.append(d)

    response.status = 200
    return {"data": found}

@post('/tickets')
def post_tickets():
    try :
        ticket = request.json
        c2 = db.cursor()
        c2.execute(
            """
            SELECT capacity,screening_id
            FROM screenings
            JOIN  theaters
            USING (theater_name)
            WHERE screening_id = ?
            """, [ticket["performanceId"]]
            )
        capacity = c2.fetchone()[0]

        c2.execute(
            """
            SELECT count(screening_id)
            FROM tickets
            WHERE screening_id = ?

            """,[ticket["performanceId"]]
            )
        no_tickets = c2.fetchone()[0]

        if ((capacity - no_tickets)  == 0):
            response.status = 400
            return "No tickets left"
        c2.execute(
            """
            SELECT username
            FROM customers
            WHERE username = ? AND customer_password = ?
            """,[ticket["username"],ticket["pwd"]]
            )
        if c2.fetchone()[0] == None:
            response.status = 401
            return "Wrong user credentials"
        c2.execute(
            """
            INSERT INTO tickets(screening_id,username)
            VALUES (?,?)
            RETURNING ticket_id
            """,[ticket["performanceId"],ticket["username"]]
            )
        ticket_id = c2.fetchone()[0]
        response.status = 201
        return f"/tickets/{ticket_id}"

    except sqlite3.IntegrityError:
        response.status = 400
        return "Error"

@get('/users/<username>/tickets')
def getTickets(username):
    c2 = db.cursor()
    c2.execute(
        """
        WITH nbr_ticket(screening_id, nbr_tickets) AS (
            SELECT screening_id,count() AS nbr_tickets
            FROM tickets
            WHERE username = ?
            GROUP BY screening_id )
        SELECT starting_date,starting_time,theater_name,title,production_year,nbr_tickets
        FROM screenings
        JOIN movies
        USING (imdb_key)
        JOIN nbr_ticket
        USING (screening_id)
        """,[username]
        )

    found = [{"date":starting_date, "startTime":starting_time,"theater":theater_name,"title":title,"year":production_year,"nbrOfTickets":nbr_tickets}
        for starting_date,starting_time,theater_name,title,production_year,nbr_tickets in c2]
    response.status = 201
    return {"data": found}

run(host='localhost', port=7007)


import os
import numpy as np
from PIL import Image
import pandas as pd

def csv_feeder():
    for f in os.listdir('./img'):
        if f.endswith('.jpg'):
            fln = f.split('j', 1)[0]
            final = img_lbl_to_dataframe('./img/' + f, float(fln[0:len(fln) - 1]))
            print(final)
            with open("./input/dataset.csv", 'a') as file:
                final.to_csv(file, header=False)

def img_lbl_to_dataframe(img, label):
    image = Image.open(img)
    image = image.resize((25, 25), Image.NEAREST)
    image.load()
    img_data = np.asarray(image, dtype="uint8")
    img_data = img_data.mean(axis=2)

    img_dframe = pd.DataFrame(img_data)
    # print(img_dframe)
    img_dframe = pd.DataFrame(img_dframe.values.reshape(1, -1))
    # print(img_dframe)
    img_dframe.insert(0, 'label', label)

    return img_dframe


import copy

from tempest.lib.services.compute import services_client
from tempest.tests.lib import fake_auth_provider
from tempest.tests.lib.services.compute import base

class TestServicesClient(base.BaseComputeServiceTest):

    FAKE_SERVICES = {
        "services":
        [{
            "status": "enabled",
            "binary": "nova-conductor",
            "zone": "internal",
            "state": "up",
            "updated_at": "2015-08-19T06:50:55.000000",
            "host": "controller",
            "disabled_reason": None,
            "id": 1
        }]
    }

    FAKE_SERVICE = {
        "service":
        {
            "status": "enabled",
            "binary": "nova-conductor",
            "host": "controller"
        }
    }

    def setUp(self):
        super(TestServicesClient, self).setUp()
        fake_auth = fake_auth_provider.FakeAuthProvider()
        self.client = services_client.ServicesClient(
            fake_auth, 'compute', 'regionOne')

    def test_list_services_with_str_body(self):
        self.check_service_client_function(
            self.client.list_services,
            'tempest.lib.common.rest_client.RestClient.get',
            self.FAKE_SERVICES)

    def test_list_services_with_bytes_body(self):
        self.check_service_client_function(
            self.client.list_services,
            'tempest.lib.common.rest_client.RestClient.get',
            self.FAKE_SERVICES, to_utf=True)

    def _test_enable_service(self, bytes_body=False):
        self.check_service_client_function(
            self.client.enable_service,
            'tempest.lib.common.rest_client.RestClient.put',
            self.FAKE_SERVICE,
            bytes_body,
            host_name="nova-conductor", binary="controller")

    def test_enable_service_with_str_body(self):
        self._test_enable_service()

    def test_enable_service_with_bytes_body(self):
        self._test_enable_service(bytes_body=True)

    def _test_disable_service(self, bytes_body=False):
        fake_service = copy.deepcopy(self.FAKE_SERVICE)
        fake_service["service"]["status"] = "disable"

        self.check_service_client_function(
            self.client.disable_service,
            'tempest.lib.common.rest_client.RestClient.put',
            fake_service,
            bytes_body,
            host_name="nova-conductor", binary="controller")

    def test_disable_service_with_str_body(self):
        self._test_disable_service()

    def test_disable_service_with_bytes_body(self):
        self._test_disable_service(bytes_body=True)


import random, os, re, sys, time, gzip, vcf, pysam, copy
import numpy as np
import argparse, pathlib
import _pickle as cPickle
import tables
import glob, bisect, time
import pandas as pd
from scipy.stats import mannwhitneyu
from tables import open_file

def get_masked_base_count(mask_fh, chrom, chromStart, chromEnd):
	region_mask = mask_fh.getNode("/mask/%s" % chrom)[chromStart:chromEnd].sum(1)
	return np.count_nonzero(region_mask)

def vst_intCN(l_pop1CN, l_pop2CN):

	int_pop1CN = np.rint(pop1_genos)
	int_pop2CN = np.rint(pop2_genos)
	int_totalCN = np.append(int_pop1CN, int_pop2CN)

	V_total = np.var(int_totalCN)

	var_int_pop1CN = np.var(int_pop1CN)
	w_pop1 = float(len(int_pop1CN)) / len(int_totalCN)

	var_int_pop2CN = np.var(int_pop2CN)
	w_pop2 = float(len(int_pop2CN)) / len(int_totalCN)

	vst = (V_total - (var_int_pop1CN * w_pop1 + var_int_pop2CN * w_pop2)) / V_total

	if np.isnan(vst):
		vst = 0.0

	return vst

if __name__ == "__main__":
	parser = argparse.ArgumentParser()
	parser.add_argument("--fileVST")
	parser.add_argument("--removeINV", default=True)
	parser.add_argument("--removeVariantBySingleCaller", default=True)
	parser.add_argument("--mask_track", default="/net/eichler/vol7/home/psudmant/genomes/mask_tracks/HG19-noWM-pad36",
						help="HDF5 mask track for reference genome")
	args = parser.parse_args()

	mask_fh = open_file(args.mask_track, mode="r")

	with open(args.fileVST) as f_vst:
		for line in f_vst:
			line = line.strip().split()

			# remove any inversion variant
			if args.removeINV:
				if "INV" in line[3]:
					continue

			# remove any variant called by a single caller
			if args.removeVariantBySingleCaller:
				l_callers = line[8].split(",")[:-1]
				if len(l_callers) == 1 & "dCGH" not in l_callers :
					continue

			# summarizing the VST file
			chrom, chromStart, chromEnd = [line[0], int(line[1]) , int(line[2])]
			len_locus = chromEnd - chromStart

			# get proportion of masked bases
			mask_count = get_masked_base_count(mask_fh, "chr%s" % chrom, chromStart, chromEnd)
			mask_pct = (mask_count / (chromEnd - chromStart))

			pop1_genos = [float(x) for x in line[6].split(",")[:-1]]
			pop2_genos = [float(x) for x in line[7].split(",")[:-1]]

			pop1_geno_median = np.median(np.array(pop1_genos))
			pop2_geno_median = np.median(np.array(pop2_genos))
			diff_geno_median = pop1_geno_median - pop2_geno_median

			try:
				uStat, uPval = mannwhitneyu(np.rint(pop1_genos), np.rint(pop2_genos))
			except ValueError:
				uPval = 1.0

			vst_integerCN = vst_intCN(pop1_genos, pop2_genos)

			line[0] = "chr" + line[0]
			tmp_output = ['%s' % len_locus , '%s' % mask_count , '%.4f' % mask_pct, '%.4f' % pop1_geno_median, '%.4f' % pop2_geno_median, '%.4f' % diff_geno_median, str(uPval), str(vst_integerCN)]
			line.extend(tmp_output)
			print('\t'.join(line))


# Adpated from https://github.com/moderngl/moderngl/blob/master/examples/simple_camera.py

from pathlib import Path
import numpy as np
from pyrr import Matrix44, Quaternion, Vector3, vector

import moderngl
import moderngl_window as mglw

import site

site.addsitedir(Path(__file__).parent.parent.as_posix())

from geoproc.mesh_loader import iter_binary_stl_mesh_triangles

STL_MESH_FILEPATH = Path(__file__).parent.parent / "tests/suzanne.stl"

class Example(mglw.WindowConfig):
    gl_version = (3, 3)
    title = "Python Geometry Processing"
    window_size = (1280, 720)
    aspect_ratio = 16 / 9
    resizable = True
    samples = 8

class Camera:
    def __init__(self, ratio):
        self._zoom_step = 0.1
        self._move_vertically = 0.1
        self._move_horizontally = 0.1
        self._rotate_horizontally = 0.2
        self._rotate_vertically = 0.1

        self._field_of_view_degrees = 60.0
        self._z_near = 0.1
        self._z_far = 100
        self._ratio = ratio
        self.build_projection()

        self._camera_position = Vector3([0.0, -10.0, 0.0])
        self._camera_front = Vector3([0.0, 1.0, 0.0])
        self._camera_up = Vector3([0.0, 0.0, 1.0])
        self._cameras_target = self._camera_position + self._camera_front
        self.build_look_at()

    def zoom_in(self):
        self._field_of_view_degrees = self._field_of_view_degrees - self._zoom_step
        self.build_projection()

    def zoom_out(self):
        self._field_of_view_degrees = self._field_of_view_degrees + self._zoom_step
        self.build_projection()

    def move_forward(self):
        self._camera_position = self._camera_position + self._camera_front * self._move_horizontally
        self.build_look_at()

    def move_backwards(self):
        self._camera_position = self._camera_position - self._camera_front * self._move_horizontally
        self.build_look_at()

    def strafe_left(self):
        self._camera_position = (
            self._camera_position - vector.normalize(self._camera_front ^ self._camera_up) * self._move_horizontally
        )
        self.build_look_at()

    def strafe_right(self):
        self._camera_position = (
            self._camera_position + vector.normalize(self._camera_front ^ self._camera_up) * self._move_horizontally
        )
        self.build_look_at()

    def strafe_up(self):
        self._camera_position = self._camera_position + self._camera_up * self._move_vertically
        self.build_look_at()

    def strafe_down(self):
        self._camera_position = self._camera_position - self._camera_up * self._move_vertically
        self.build_look_at()

    def rotate_left_right(self, value: float):
        rotation = Quaternion.from_axis_rotation(self._camera_up, -2 * float(value) * np.pi / 180)
        self._camera_front = rotation * self._camera_front
        self.build_look_at()

    def rotate_up_down(self, value: float):
        rotation = Quaternion.from_axis_rotation(
            vector.normalize(self._camera_front ^ self._camera_up), -2 * float(value) * np.pi / 180
        )
        self._camera_front = rotation * self._camera_front
        self.build_look_at()

    def build_look_at(self):
        self._cameras_target = self._camera_position + self._camera_front
        self.mat_lookat = Matrix44.look_at(self._camera_position, self._cameras_target, self._camera_up)

    def build_projection(self):
        self.mat_projection = Matrix44.perspective_projection(
            self._field_of_view_degrees, self._ratio, self._z_near, self._z_far
        )

class PerspectiveProjection(Example):
    gl_version = (3, 3)

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.prog = self.ctx.program(
            vertex_shader="""
                #version 330

                uniform mat4 model_view_projection;

                in vec3 in_vert;
                in vec3 normal;

                out vec3 nout;

                void main() {
                    gl_Position = model_view_projection * vec4(in_vert, 1.0);
                    nout = normal;
                }
            """,
            fragment_shader="""
                #version 330

                in vec3 nout;
                out vec4 f_color;

                void main() {
                    f_color = vec4(0.1, 0.1, 0.1, 1.0);
                    f_color *= 10.0 * clamp(dot(nout, vec3(1.0, 1.0, 1.0)), 0.0, 1.0);
                }
            """,
        )

        verts = []
        normals = []

        for tri in iter_binary_stl_mesh_triangles(STL_MESH_FILEPATH):
            tri_verts = [Vector3([*vpos]) for vpos in tri]
            e0 = tri_verts[1] - tri_verts[0]
            e1 = tri_verts[2] - tri_verts[0]
            normal = e0.cross(e1).normalized

            for v in tri_verts:
                verts.append(v)
                normals.append(normal)

        verts_np = np.array(verts)
        normals_np = np.array(normals)

        self.camera = Camera(self.aspect_ratio)
        self.model_view_projection_matrix_program_input = self.prog["model_view_projection"]
        self.vbo = self.ctx.buffer(verts_np.astype("f4"))
        self.normals = self.ctx.buffer(normals_np.astype("f4"))
        self.vao = self.ctx.vertex_array(self.prog, [(self.vbo, "3f", "in_vert"), (self.normals, "3f", "normal")])

        self.states = {
            self.wnd.keys.W: False,
            self.wnd.keys.S: False,
            self.wnd.keys.UP: False,
            self.wnd.keys.DOWN: False,
            self.wnd.keys.A: False,
            self.wnd.keys.D: False,
            self.wnd.keys.Q: False,
            self.wnd.keys.E: False,
            self.wnd.keys.Z: False,
            self.wnd.keys.X: False,
        }

    def mouse_drag_event(self, x: int, y: int, dx: int, dy: int):
        self.camera.rotate_left_right(dx * 0.05)
        self.camera.rotate_up_down(dy * 0.05)

    def move_camera(self):
        if self.states.get(self.wnd.keys.W):
            self.camera.move_forward()

        if self.states.get(self.wnd.keys.S):
            self.camera.move_backwards()

        if self.states.get(self.wnd.keys.UP):
            self.camera.strafe_up()

        if self.states.get(self.wnd.keys.DOWN):
            self.camera.strafe_down()

        if self.states.get(self.wnd.keys.A):
            self.camera.strafe_left()

        if self.states.get(self.wnd.keys.D):
            self.camera.strafe_right()

        if self.states.get(self.wnd.keys.Z):
            self.camera.zoom_in()

        if self.states.get(self.wnd.keys.X):
            self.camera.zoom_out()

    def key_event(self, key, action, modifiers):
        if key not in self.states:
            print(key, action)
            return

        if action == self.wnd.keys.ACTION_PRESS:
            self.states[key] = True
        else:
            self.states[key] = False

    def render(self, time, frame_time):
        self.move_camera()

        self.ctx.clear(1.0, 1.0, 1.0)
        self.ctx.enable(moderngl.DEPTH_TEST)  # type: ignore

        self.model_view_projection_matrix_program_input.write((self.camera.mat_projection * self.camera.mat_lookat).astype("f4"))  # type: ignore
        self.vao.render(moderngl.TRIANGLES)  # type: ignore

if __name__ == "__main__":
    PerspectiveProjection.run()


def calculate_objective_value(flows, distances, assignments):
    value = 0
    number_of_facilities = len(flows)

    for i in range(number_of_facilities):
        for j in range(number_of_facilities):
            value += flows[i][j] * distances[assignments[i]][assignments[j]]

    return value

def calculate_value_swap(assignments, facility1, facility2, flows, distances):
    number_of_facilities = len(flows)
    location1 = assignments[facility1]
    location2 = assignments[facility2]

    delta = flows[facility1][facility1] * (distances[location2][location2] - distances[location1][location1]) + \
        flows[facility1][facility2] * (distances[location2][location1] - distances[location1][location2]) + \
        flows[facility2][facility1] * (distances[location1][location2] - distances[location2][location1]) + \
        flows[facility2][facility2] * (distances[location1][location1] - distances[location2][location2])

    for facility in range(number_of_facilities):
        if facility != facility1 and facility != facility2:
            location = assignments[facility]
            delta += flows[facility][facility1] * (distances[location][location2] - distances[location][location1]) + \
                flows[facility][facility2] * (distances[location][location1] - distances[location][location2]) + \
                flows[facility1][facility] * (distances[location2][location] - distances[location1][location]) + \
                flows[facility2][facility] * (distances[location1][location] - distances[location2][location])

    return delta


import os
import uuid

from django.core.management import call_command
from django.core.management.base import BaseCommand
from django.conf import settings

class Command(BaseCommand):

    def handle(self, *args, **kwargs):
        try:
            default_path = os.environ['LOCALSHOP_HOME']
        except KeyError:
            default_path = os.path.expanduser('~/.localshop')

        if not os.path.exists(default_path):
            os.mkdir(default_path)

        config_path = os.path.join(default_path, 'localshop.conf.py')
        if not os.path.exists(config_path):
            default_params = {
                'SECRET_KEY': uuid.uuid4()
            }

            with open(config_path, 'w') as fh:
                fh.write("""
SECRET_KEY = '%(SECRET_KEY)s'

                """ % default_params)

        call_command('syncdb', database='default', interactive=False)
        call_command('migrate', database='default', interactive=False)
        call_command('createsuperuser', database='default', interactive=True)


from __future__ import print_function

import sys
import logging
import traceback
import lambda_uploader

from os import getcwd, path, getenv
from lambda_uploader import package, config, uploader

LOG = logging.getLogger(__name__)

NAMESPACE = 'rax_jira'
CHECK = '\xe2\x9c\x85'
INTERROBANG = '\xe2\x81\x89\xef\xb8\x8f'
RED_X = '\xe2\x9d\x8c'
LAMBDA = '\xce\xbb'

# Used for stdout for shell
def _print(txt):
    # Windows Powershell doesn't support Unicode
    if sys.platform == 'win32' or sys.platform == 'cygwin':
        print(txt)
    else:
        # Add the lambda symbol
        print("%s %s" % (LAMBDA, txt))

def _execute(args):
    pth = path.abspath(args.function_dir)

    cfg = config.Config(pth, args.config, role=args.role)

    if args.no_virtualenv:
        # specified flag to omit entirely
        venv = False
    elif args.virtualenv:
        # specified a custom virtualenv
        venv = args.virtualenv
    else:
        # build and include virtualenv, the default
        venv = None

    _print('Building Package')
    pkg = package.build_package(pth, cfg.requirements,
                                venv, cfg.ignore)

    if not args.no_clean:
        pkg.clean_workspace()

    if not args.no_upload:
        # Set publish if flagged to do so
        if args.publish:
            cfg.set_publish()

        create_alias = False
        # Set alias if the arg is passed
        if args.alias is not None:
            cfg.set_alias(args.alias, args.alias_description)
            create_alias = True

        _print('Uploading Package')
        upldr = uploader.PackageUploader(cfg, args.profile)
        upldr.upload(pkg)
        # If the alias was set create it
        if create_alias:
            upldr.alias()

        pkg.clean_zipfile()

    _print('Fin')

def main(arv=None):
    """lambda-uploader command line interface."""
    import argparse

    parser = argparse.ArgumentParser(
            version=('version %s' % lambda_uploader.__version__),
            description='Simple way to create and upload python lambda jobs')

    parser.add_argument('--no-upload', dest='no_upload',
                        action='store_const', help='dont upload the zipfile',
                        const=True)
    parser.add_argument('--no-clean', dest='no_clean',
                        action='store_const',
                        help='dont cleanup the temporary workspace',
                        const=True)
    parser.add_argument('--publish', '-p', dest='publish',
                        action='store_const',
                        help='publish an upload to an immutable version',
                        const=True)
    parser.add_argument('--virtualenv', '-e',
                        help='use specified virtualenv instead of making one',
                        default=None)
    parser.add_argument('--no-virtualenv', dest='no_virtualenv',
                        action='store_const',
                        help='do not create or include a virtualenv at all',
                        const=True)
    parser.add_argument('--role', dest='role',
                        default=getenv('LAMBDA_UPLOADER_ROLE'),
                        help=('IAM role to assign the lambda function, '
                              'can be set with $LAMBDA_UPLOADER_ROLE'))
    parser.add_argument('--profile', dest='profile',
                        help='specify AWS cli profile')
    alias_help = 'alias for published version (WILL SET THE PUBLISH FLAG)'
    parser.add_argument('--alias', '-a', dest='alias',
                        default=None, help=alias_help)
    parser.add_argument('--alias-description', '-m', dest='alias_description',
                        default=None, help='alias description')
    parser.add_argument('--config', help='Overrides lambda.json',
                        default=None)
    parser.add_argument('function_dir', default=getcwd(), nargs='?',
                        help='lambda function directory')

    verbose = parser.add_mutually_exclusive_group()
    verbose.add_argument('-V', dest='loglevel', action='store_const',
                         const=logging.INFO,
                         help="Set log-level to INFO.")
    verbose.add_argument('-VV', dest='loglevel', action='store_const',
                         const=logging.DEBUG,
                         help="Set log-level to DEBUG.")
    parser.set_defaults(loglevel=logging.WARNING)

    args = parser.parse_args()

    logging.basicConfig(level=args.loglevel)
    try:
        _execute(args)
    except Exception:
        print('%s Unexpected error. Please report this traceback.'
              % INTERROBANG, file=sys.stderr)

        traceback.print_exc()
        sys.stderr.flush()
        sys.exit(1)


import csv
import os

from dataclasses import dataclass
from signal_emulator.controller import BaseCollection, BaseItem
from copy import copy
from pathlib import Path
from typing import Optional
from signal_emulator.utilities.utility_functions import list_to_csv
from datetime import date

@dataclass(eq=False)
class PhaseToSaturnTurn:
    signal_emulator: object
    controller_key: str
    phase_ref: str
    turn: int
    saturn_a_node: int
    saturn_b_node: int
    saturn_c_node: int

    def get_key(self):
        return self.controller_key, self.phase_ref, self.saturn_b_node, self.turn

class PhaseToSaturnTurns(BaseCollection):
    ITEM_CLASS = PhaseToSaturnTurn
    TABLE_NAME = "phase_to_saturn_turns"
    WRITE_TO_DATABASE = True

    def __init__(self, signal_emulator, saturn_lookup_file=None):
        super().__init__(item_data=[], signal_emulator=signal_emulator)
        self.signal_emulator = signal_emulator
        if saturn_lookup_file:
            self.load_from_saturn_lookup_file(saturn_lookup_file)

    def load_from_saturn_lookup_file(self, saturn_lookup_file):
        if os.path.exists(saturn_lookup_file):
            self.init_from_saturn_file(saturn_lookup_file)
        else:
            self.signal_emulator.logger.warning(
                f"SATURN lookup file: {saturn_lookup_file} does not exist"
            )

    def init_from_saturn_file(self, saturn_lookup_file):
        with open(saturn_lookup_file, "r") as csvfile:
            csvreader = csv.DictReader(csvfile)
            for row in csvreader:
                self.add_item(row, signal_emulator=self.signal_emulator)

    def get_saturn_b_node(self, controller_number):
        for key, value in self.signal_emulator.phase_to_saturn_turns.data.items():
            if int(key[0].split("/")[1]) == controller_number:
                return value.saturn_b_node
        return ()

class SaturnCollection(BaseCollection):
    OUTPUT_VERSON = "v1"
    OUTPUT_HEADER = "* LoHAN P6 RGS Printout" + " " + OUTPUT_VERSON + "\n* " + str(date.today()) + "\n\n"
    COLUMNS = {}
    SATURN_TABLE_NAME = None
    # List of field lengths for a SATURN type-1 record
    SATURN_TYPE1_FIELD_LENS = [5, 5, 5, 5, 5, 5, 5, 5, 5]

    def __init__(self, item_data, signal_emulator, output_directory):
        super().__init__(item_data=item_data)
        self.signal_emulator = signal_emulator
        self.output_directory = output_directory

    def export_to_rgs_files(self, time_periods=None):
        if time_periods is None:
            time_periods = self.signal_emulator.time_periods.get_all()
        for time_period in time_periods:
            self.export_to_rgs_file(time_period)

    def export_to_rgs_file(self, time_period, output_path=None):
        if not output_path:
            output_path = os.path.join(
                self.output_directory,
                f"LoHAMP6_SignalGroupData_{self.OUTPUT_VERSON}_{time_period.name}.rgs",
            )
        Path(output_path).parent.mkdir(exist_ok=True, parents=True)
        with open(output_path, "w") as rgs_file:
            # Print the SATURN file header
            rgs_file.write(self.OUTPUT_HEADER)

            # Get a list of all distinct controllers for time period
            controllers = []
            for item in self:
                if item.time_period_id == time_period.name:
                    if item.signal_controller_number not in controllers:
                        controllers.append(item.signal_controller_number)

            # Iterate all distinct controllers for time period
            for controller_number in controllers:
                # Identify the cycle time of the current controller
                cycle_time = self._get_cycle_time(controller_number, time_period.name)
                # Get all distinct node-b's for the current controller and iterate (each will have it's own SATURN rec-1)
                node_bs = self._get_controller_saturn_nodes(controller_number)
                for node_b in node_bs:
                    # Iterate through cycle period second-by-second
                    cycle_seconds_phases = []
                    for t in range(0, cycle_time):
                        # For each second, check if a phase is set for current t
                        # If phase is set, add it to list for current second
                        phases_in_second = self._get_phases_in_second(
                            controller_number, node_b, time_period, t
                        )
                        cycle_seconds_phases.append(phases_in_second)

                    # Adjust list where phases wrap-around from end to start
                    cycle_seconds_phases = self._post_process_cycle_seconds_phases(
                        cycle_seconds_phases
                    )

                    # To store phases assoicated with previous second
                    last_phases_in_second = []
                    # To store last non-intergreen phases
                    last_non_intergreen = []
                    # To store list of phases being constructed to add to SATURN type-3 record
                    rec_3_list = []
                    # Stage duration
                    stage_duration = 0
                    # The initial intergreen (if present), summed to final intergreen
                    initial_intergreen = None
                    # Last intergreen, ready to add to next SATURN type-3 record
                    intergreen = 0

                    # Loop through all phases per second
                    for i, phases_in_second in enumerate(cycle_seconds_phases):
                        # Determine if a new SATURN type-3 record should be built
                        if (
                            # Current second's phases are different from previous second
                            phases_in_second != last_phases_in_second
                            # and we have passed at least one second with phases set
                            and last_non_intergreen != []
                            # and we are not currently in an intergreen (need to reach next phase to determine full intergreen period)
                            and phases_in_second != []
                            # or it is the last second
                        ) or i == len(cycle_seconds_phases) - 1:
                            if i == len(cycle_seconds_phases) - 1:
                                # If it is the last record, add the initial pre-phase intergreen time
                                intergreen += (
                                    initial_intergreen
                                    if initial_intergreen is not None
                                    else 0
                                )
                                # If we finish on an intergreen, add an extra second as it hasn't yet been counted
                                intergreen += 1 if phases_in_second == [] else 0
                                # If we finish on a stage, add an extra second as it hasn't yet been counted
                                if phases_in_second != []:
                                    stage_duration += 1
                            # Append attributes to list of controllers SATURN type-3 record
                            if rec_3_list != [] and rec_3_list[-1][1] != 0:
                                # Test if previous stage had matching phases with non-zero intergreen (to mark previous intergreen negative)
                                if self._test_stages_negative_intergreen(
                                    rec_3_list[-1], last_non_intergreen
                                ):
                                    rec_3_list[-1][1] = 0 - rec_3_list[-1][1]
                                # Test if only a single stage (e.g zebra crossing), so mark current intergreen negative
                                if self._test_zebra_negative_intergreen(
                                    cycle_seconds_phases
                                ):
                                    intergreen = 0 - intergreen
                            rec_3_list.append(
                                [stage_duration, intergreen, last_non_intergreen]
                            )

                            # Reset stage duration and intergreen counters after identifying a new record
                            stage_duration = 0
                            intergreen = 0

                        # Keep track of the last second's phases
                        last_phases_in_second = phases_in_second

                        # Keep track of the last non-intergreen record and counters (we write this when the current record changes)
                        if phases_in_second != []:
                            last_non_intergreen = phases_in_second
                            # Stage duration counter can be increased
                            stage_duration += 1
                            if initial_intergreen is None:
                                # Store first intergreen to use on last phase
                                initial_intergreen = intergreen
                                intergreen = 0

                        if phases_in_second == []:
                            # Intergreen counter can be incremented
                            intergreen += 1

                    # Print SATURN header
                    rgs_file.write(
                        "* LoHAM P6 Signal. UTC:" + str(controller_number) + "\n"
                    )

                    # Process SATURN lines
                    saturn_rec1 = self._format_saturn_line(
                        [
                            node_b,
                            "",
                            3,
                            len(rec_3_list),
                            initial_intergreen if initial_intergreen is not None else 0,
                            cycle_time,
                        ],
                        self.SATURN_TYPE1_FIELD_LENS,
                    )

                    # Print SATURN type-1 record
                    rgs_file.write(saturn_rec1 + "\n")
                    # Print SATURN type-3 records
                    for stage in rec_3_list:
                        saturn_type3_field_lens = [5, 5, 5, 5, 5]
                        for n in range(0, len(stage[2]) * 2):
                            saturn_type3_field_lens.append(5)
                        rgs_file.write(
                            self._break_saturn_string(
                                self._format_saturn_line(
                                    ["", "", stage[0], stage[1], len(stage[2]) * 2]
                                    + [
                                        item for sublist in stage[2] for item in sublist
                                    ],
                                    saturn_type3_field_lens,
                                ),
                                75,
                                25,
                            )
                            + "\n"
                        )
                    rgs_file.write("\n")

        self.signal_emulator.logger.info(
            f"SATURN {self.SATURN_TABLE_NAME} output to net file: {output_path}"
        )

    # Test if a negative intergreen should be applied due to matching phases between stages and non-zero intergreen
    def _test_stages_negative_intergreen(self, prev_rec, nodes_list_b):
        nodes_list_a = prev_rec[2]
        # If previous intergreen was non-zero
        if prev_rec[1] != 0:
            # Test if there is a matching pair of nodes between last and current stage
            for pair in nodes_list_a:
                if pair in nodes_list_b:
                    return True

    # Test for single stage (eg Zebra crossing) where a negative intergreen should be applied
    def _test_zebra_negative_intergreen(self, cycle_seconds_phases):
        unique_lists = []
        for lst in cycle_seconds_phases:
            if lst and lst not in unique_lists:
                unique_lists.append(lst)

        distinct_stages = len(unique_lists)
        if distinct_stages == 1:
            return True
        else:
            return False

    # Break a sting to match SATURN max line length restrictions
    def _break_saturn_string(self, input_str, max_len, margin_len):
        lines = []
        current_line = ""
        for char in input_str:
            if len(current_line) >= max_len:
                lines.append(current_line)
                current_line = " " * margin_len
            current_line += char
        lines.append(current_line)
        return "\n".join(lines)

    # Append fields to SATURN string, right-aligned within field widths
    def _format_saturn_line(self, fields, field_len):
        formatted_saturn_line = ""
        for i in range(len(fields)):
            formatted_saturn_line += str(fields[i]).rjust(field_len[i])
        return formatted_saturn_line

    # Retrieve the VISUM calculated controller time period
    def _get_cycle_time(self, controller_number, time_period):
        for key, value in self.signal_emulator.visum_signal_controllers.data.items():
            if key[0] == controller_number and key[1] == time_period:
                return value.cycle_time

    # Test if a a given phase name/controller/node-b exists in the SATURN node mapping
    def _test_in_database(self, controller_number, node_b, phase_name):
        saturn_in_phase = []
        for key in self.signal_emulator.phase_to_saturn_turns.data.keys():
            if (
                int(key[0].split("/")[1]) == controller_number
                and key[2] == node_b
                and key[1] == phase_name
            ):
                record = self.signal_emulator.phase_to_saturn_turns.data[key]
                saturn_in_phase.append([record.saturn_a_node, record.saturn_c_node])
        if saturn_in_phase == []:
            return None
        else:
            return saturn_in_phase

    # Get mapped distinct SATURN b-nodes for a given controller
    def _get_controller_saturn_nodes(self, controller_number):
        nodes = []
        for key in self.signal_emulator.phase_to_saturn_turns.data.keys():
            if int(key[0].split("/")[1]) == controller_number:
                record = self.signal_emulator.phase_to_saturn_turns.data[key]
                if record.saturn_b_node not in nodes:
                    nodes.append(record.saturn_b_node)
        return nodes

    # Identify what SATURN phases occur and exist for a given second of a controller/b-node time period
    def _get_phases_in_second(self, controller_number, node_b, time_period, t):
        phases_in_second = []
        for item in self:
            if (
                item.time_period_id == time_period.name
                and item.signal_controller_number == controller_number
                and (
                    (
                        item.green_time_start < item.green_time_end
                        and item.green_time_start <= t
                        and item.green_time_end > t
                    )
                    or (
                        item.green_time_start > item.green_time_end
                        and (item.green_time_start <= t or item.green_time_end > t)
                    )
                )
            ):
                is_in_database = self._test_in_database(
                    controller_number, node_b, item.phase_name
                )
                if is_in_database is not None:
                    phases_in_second += is_in_database
        return phases_in_second

    # Resolve issues relating to the layout of phases within the stages cycle time
    def _post_process_cycle_seconds_phases(self, cycle_seconds_phases):
        # If a phase has a start_time > start_time, it will wrap around, resolve this
        while (
            cycle_seconds_phases[0] != []
            and cycle_seconds_phases[0] == cycle_seconds_phases[-1]
            and any(x != cycle_seconds_phases[0] for x in cycle_seconds_phases)
        ):
            element = cycle_seconds_phases.pop(0)
            cycle_seconds_phases.append(element)
        return cycle_seconds_phases

@dataclass(eq=False)
class SaturnSignalGroup(BaseItem):
    signal_controller_number: int
    phase_number: int
    phase_name: str
    green_time_start: int
    green_time_end: int
    time_period_id: str

    def get_key(self):
        return self.signal_controller_number, self.phase_name, self.time_period_id

class SaturnSignalGroups(SaturnCollection):
    ITEM_CLASS = SaturnSignalGroup
    TABLE_NAME = "saturn_signal_groups"
    WRITE_TO_DATABASE = False

    COLUMNS = {
        "SCNO": "signal_controller_number",
        "NO": "phase_number",
        "NAME": "phase_name",
        "GTSTART": "green_time_start",
        "GTEND": "green_time_end",
    }
    SATURN_TABLE_NAME = "SIGNALGROUP"

    def __init__(self, item_data, signal_emulator, output_directory):
        super().__init__(
            item_data=item_data,
            signal_emulator=signal_emulator,
            output_directory=output_directory,
        )
        self.signal_emulator = signal_emulator

    def add_from_phase_timing(self, phase_timing):
        saturn_signal_group = SaturnSignalGroup(
            signal_controller_number=phase_timing.controller.site_number_int,
            phase_number=phase_timing.signal_group_number,
            phase_name=phase_timing.visum_phase_name,
            green_time_start=phase_timing.start_time,
            green_time_end=phase_timing.end_time,
            time_period_id=phase_timing.time_period_id,
        )
        self.data[saturn_signal_group.get_key()] = saturn_signal_group


# Initial code taken from
# https://www.tutorialspoint.com/extract-hyperlinks-from-pdf-in-python

# Import necessary packages
import PyPDF2
import re

# Open The File in the Command
file = open("Toward_Causal_Representation_Learning.pdf", 'rb')
readPDF = PyPDF2.PdfFileReader(file)
def find_urls(string):
   #Find all the String that matches with the pattern
   # string = remove_control_chars(string)
   regex = r"(https?://\S+)"
   urls = re.findall(regex,string)
   return urls
# Iterating over all the pages of File
for page_no in range(readPDF.numPages):
   page=readPDF.getPage(page_no)
   #Extract the text from the page
   text = page.extractText()

   # Print all URL
   urls = find_urls(text)
   for u in urls:
       # the reference include the "[reference-no]" at the end of the url
       # create a substring up to the [ char to deal with this
       pos = u.find("[")
       if pos != -1:
           u = u[:pos]
       print("[{}][{}]".format(page_no, u))

# CLost the file
file.close()


from django.conf.urls import url,include
from . import views
from django.conf import settings
from django.conf.urls.static import static

urlpatterns=[

    url(r'^$', views.index,name='index'),
    url(r'^$', views.homepage,name='home'),
    url(r'^profiles/(?P<username>[-_\w.]+)$', views.profile,name='profiles'),
    url(r'^profiles/post/$', views.post,name='uploadpost'),
    url(r'^profiles/edit/(?P<username>[-_\w.]+)$', views.update_profile,name='editprofile'),
    url(r'^profiles/comment/(\d+)$', views.comment, name="comment"),
    url(r'^profiles/upvote/(\d+)$', views.upvote_posts, name="upvote_post"),

]

if settings.DEBUG:
    urlpatterns+= static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)


#Print hello world

#print ('Hello world')

#Creating a variable to store first and last name

first_name = "Abdul"
last_name = "Al-Basith"
age = 26

#string concatenation
full_name = first_name + " " + last_name

#print (first_name)
#print (full_name)

#Use format string to print

#print ("Hello, my name is " + first_name + " and I am " + str(age) + " years old")

#format string - Easy way to format a lot of string with variables in it

#print(f"Hello, my name is {first_name} and I am {age} years old")

#create variables to store the names of all  your classmates
#print all the names in the following message

'''
name1 = "Justin"
name2 ="Harrison"
name3 = "Abdul"
name4 = "Long"
name5 = "Griffen"
name6 = "Thanujan"
name7 = "Amelia"
print (f"The members of my cohort are {name1}, {name2}, {name3}, {name4}, {name5}, {name6}, and {name7}, and they are all awesome!")
'''

member_list = ["Justin","Harrison","Abdul","Long","Griffen", "Thanujan", "Amelia", "Claudia", "Nima"]

print (f"The members of my cohort are {', '.join(member_list)} and they are all awesome!")


import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torch.distributions.categorical import Categorical
import numpy as np
from buffer import ReplayMemory
torch.autograd.set_detect_anomaly(True)

def to_tensor(vec):
    if not torch.is_tensor(vec):
        vec = torch.FloatTensor(vec)
    if vec.dim() <= 1:
        vec = vec.reshape([1, -1])
    return vec

class Actor(nn.Module):
    def __init__(self, state_space, action_space):
        super(Actor, self).__init__()
        self.actor = nn.Sequential(
            nn.Linear(state_space, 64),
            nn.ReLU(),
            nn.Linear(64, 64),
            nn.ReLU(),
            nn.Linear(64, action_space),
            nn.Softmax(dim=1)
        )

    def forward(self, state):
        return self.actor(state)

class Critic(nn.Module):
    def __init__(self, state_space, action_space):
        super(Critic, self).__init__()
        self.critic = nn.Sequential(
            nn.Linear(state_space + 1, 64),
            nn.ReLU(),
            nn.Linear(64, 64),
            nn.ReLU(),
            nn.Linear(64, 1)
        )

    def forward(self, state, action):
        return self.critic(torch.cat([state, action], dim=1))

class SAC(nn.Module):
    def __init__(self, state_space, action_space, lr_actor=0.0001, lr_critic=0.0005,
                 gamma=0.99, alpha=0.5, update_interval=200, EPS_START=0.5, EPS_END=0.05, EPS_DECAY=200):
        super(SAC, self).__init__()

        self.state_space = state_space
        self.action_space = action_space
        self.gamma = gamma
        self.alpha = alpha
        self.BATCH_SIZE=300
        self.update_interval = update_interval
        self.EPS_START = EPS_START
        self.EPS_END = EPS_END
        self.EPS_DECAY = EPS_DECAY
        self.buffer=ReplayMemory(10000)

        self.actor = Actor(state_space, action_space)
        self.actor_target = Actor(state_space, action_space)

        self.critic1 = Critic(state_space, action_space)
        self.critic1_target = Critic(state_space, action_space)

        self.critic2 = Critic(state_space, action_space)
        self.critic2_target = Critic(state_space, action_space)

        self.update_target()

        # self.optimizer = optim.Adam([
        #     {'params': self.actor.parameters(), 'lr': lr_actor},
        #     {'params': self.critic1.parameters(), 'lr': lr_critic},
        #     {'params': self.critic2.parameters(), 'lr': lr_critic}
        # ])
        self.actor_optimizer = optim.Adam(self.actor.parameters(), lr_actor)
        self.critic_optimizer1 = optim.Adam(self.critic1.parameters(), lr_critic)
        self.critic_optimizer2 = optim.Adam(self.critic2.parameters(), lr_critic)

        self.steps = 0

    def update_target(self):
        self.actor_target.load_state_dict(self.actor.state_dict())
        self.critic1_target.load_state_dict(self.critic1.state_dict())
        self.critic2_target.load_state_dict(self.critic2.state_dict())

    def select_action(self, state,eval=False):
        """select action give a state

        Args:
            state (tensor): current state
        Returns:
            tensor,bool: action,exploration or not,action_prob
        """
        state = torch.from_numpy(state.detach().numpy()).float()
        with torch.no_grad():
            action_prob = self.actor(state)
        c = Categorical(action_prob)
        action = c.sample()
        action_max=np.argmax(action_prob)
        E=1
        if action.item()==action_max.item():
            E=0

        if eval:
            return action_max,0,1
        return action.unsqueeze(0),E, action_prob[:,action.item()].item()

    def update(self):
        if len(self.buffer) < self.BATCH_SIZE:
            return
        transitions = self.buffer.sample(self.BATCH_SIZE)
        batch = self.buffer.Transition(*zip(*transitions))

        state_next = torch.cat(batch.next_state)
        state = torch.cat(batch.state)
        action = torch.cat(batch.action)
        reward = torch.cat(batch.reward)
        done = torch.cat(batch.terminated)
        old_action_prob=torch.cat(batch.action_prob)

        loss = 0.
        # update critic
        action_probs_next = self.actor_target(state_next)
        # action_probs_next = torch.cat([action_probs_next, 1 - action_probs_next], dim=1)
        dist = Categorical(action_probs_next)
        action_next = dist.sample()
        log_prob_next = dist.log_prob(action_next)
        # log_prob_next = torch.log(action_probs_next)
        Q_next = torch.minimum(self.critic1_target(state_next, action_next.unsqueeze(-1)),
                               self.critic2_target(state_next, action_next.unsqueeze(-1)))
        Q_target = reward + self.gamma * (1 - done) * (Q_next.squeeze() - self.alpha * log_prob_next)
        Q1 = self.critic1(state, action)
        Q2 = self.critic2(state, action)
        critic_loss = F.mse_loss(Q1.squeeze(), Q_target.detach()) + F.mse_loss(Q2.squeeze(), Q_target.detach())
        self.critic1.zero_grad()
        self.critic2.zero_grad()
        critic_loss.backward()
        nn.utils.clip_grad_norm_(self.critic1.parameters(), 0.3)
        nn.utils.clip_grad_norm_(self.critic2.parameters(), 0.3)
        self.critic_optimizer1.step()
        self.critic_optimizer2.step()

        # update actor
        action_probs = self.actor(state)
        # action_probs = torch.cat([action_probs, 1 - action_probs], dim=1)
        dist = Categorical(action_probs)
        action_cur = dist.sample()
        Q1 = self.critic1(state, action_cur.unsqueeze(-1))
        Q2 = self.critic2(state, action_cur.unsqueeze(-1))
        min_Q = torch.minimum(Q1, Q2)
        actor_loss = -torch.mean(min_Q - self.alpha * dist.log_prob(action_cur))

        self.actor_optimizer.zero_grad()
        actor_loss.backward()
        nn.utils.clip_grad_norm_(self.actor.parameters(), 0.1)
        self.actor_optimizer.step()

        return actor_loss + critic_loss


# _*_ coding.utf-8 _*_
# 开发人员 : leehm
# 开发时间 : 2020/7/5 12:08
# 文件名称 : 42.py
# 开发工具 : PyCharm
s1 = input()
s = s1.split()
a = int(s[0])
b = int(s[1])
while not a == b:
    if a>b:
        a = int(a/2)
    else:
        b = int(b/2)
print(a)


class Solution:
    def canPartition(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        # 首先计算nums的和
        sum = 0
        for num in nums:
            sum += num
        if sum % 2 == 1:
            return False
        C = sum / 2

        memo = [0] * (C + 1)
        # 首先将第一行进行初始化
        for j in range(C + 1):
            memo[j] = (nums[0] == j)
        # 之后依次计算每个物品
        for i in range(1, len(nums)):
            # 依次考虑所有背包容量的情况
            for j in range(C, nums[i] - 1, -1):
                memo[j] = memo[j] or memo[j - nums[i]]
        return memo[C]

src/leetcode_oj/416. Partition Equal Subset Su/test.py


"""
This module handles reconstruction of phase and intensity images from raw
holograms using "the convolution approach": see Section 3.3 of Schnars & Juptner
(2002) Meas. Sci. Technol. 13 R85-R101 [1]_.

Aberration corrections from Colomb et al., Appl Opt. 2006 Feb 10;45(5):851-63
are applied [2]_.

    .. [1] http://x-ray.ucsd.edu/mediawiki/images/d/df/Digital_recording_numerical_reconstruction.pdf
    .. [2] http://www.ncbi.nlm.nih.gov/pubmed/16512526

"""
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

from collections import Sized, deque, defaultdict

import warnings

from multiprocessing import Pool
from functools import partial

from .vis import save_scaled_image

import h5py
import numpy as np
from numpy.compat import integer_types

from scipy.ndimage import gaussian_filter, maximum_filter
from scipy.signal import tukey

from skimage.restoration import unwrap_phase as skimage_unwrap_phase
from skimage.io import imread
from skimage.feature import blob_doh

from astropy.utils.exceptions import AstropyUserWarning
from astropy.convolution import convolve_fft, MexicanHat2DKernel

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import ImageGrid

import time

# Try importing optional dependency PyFFTW for Fourier transforms.
# Numpy's fft_intel package might also be preferable
# If the import fails, import scipy's FFT module instead
try:
    from pyfftw.interfaces.scipy_fftpack import fft2, ifft2
except ImportError:
    try:
        from np.fft_intel import fft2, ifft2
    except ImportError:
        from scipy.fftpack import fft2, ifft2

__all__ = ['Hologram', 'ReconstructedWave', 'unwrap_phase']
RANDOM_SEED = 42
TWO_TO_N = [2**i for i in range(13)]

def rebin_image(a, binning_factor):
    # Courtesy of J.F. Sebastian: http://stackoverflow.com/a/8090605
    if binning_factor == 1:
        return a

    new_shape = (a.shape[0]/binning_factor, a.shape[1]/binning_factor)
    sh = (new_shape[0], a.shape[0]//new_shape[0], new_shape[1],
          a.shape[1]//new_shape[1])
    return a.reshape(map(int, sh)).mean(-1).mean(1)

def fftshift(x, additional_shift=None, axes=None):
    """
    Shift the zero-frequency component to the center of the spectrum, or with
    some additional offset from the center.

    This is a more generic fork of `~numpy.fft.fftshift`, which doesn't support
    additional shifts.

    Parameters
    ----------
    x : array_like
        Input array.
    additional_shift : list of length ``M``
        Desired additional shifts in ``x`` and ``y`` directions respectively
    axes : int or shape tuple, optional
        Axes over which to shift.  Default is None, which shifts all axes.

    Returns
    -------
    y : `~numpy.ndarray`
        The shifted array.
    """
    tmp = np.asarray(x)
    ndim = len(tmp.shape)
    if axes is None:
        axes = list(range(ndim))
    elif isinstance(axes, integer_types):
        axes = (axes,)

    # If no additional shift is supplied, reproduce `numpy.fft.fftshift` result
    if additional_shift is None:
        additional_shift = [0, 0]

    y = tmp
    for k, extra_shift in zip(axes, additional_shift):
        n = tmp.shape[k]
        if (n+1)//2 - extra_shift < n:
            p2 = (n+1)//2 - extra_shift
        else:
            p2 = abs(extra_shift) - (n+1)//2
        mylist = np.concatenate((np.arange(p2, n), np.arange(0, p2)))
        y = np.take(y, mylist, k)
    return y

def arrshift(x, shift, axes=None):
    """
    Shift array by ``shift`` along ``axes``.

    Parameters
    ----------
    x : array_like
        Input array.
    shift : list of length ``M``
        Desired additional shifts along respective axes
    axes : int or shape tuple, optional
        Axes over which to shift.  Default is None, which shifts all axes.

    Returns
    -------
    y : `~numpy.ndarray`
        The shifted array.
    """
    y = np.asarray(x)
    ndim = len(y.shape)
    if axes is None:
        axes = list(range(ndim))
    elif isinstance(axes, integer_types):
        axes = (axes,)

    for j, k in zip(axes, shift):
        n = y.shape[j];
        y = np.roll(y, (n+1)//2 - (-1)*k, axis=j)

    return y

def _load_hologram(hologram_path):
    """
    Load a hologram from path ``hologram_path`` using scikit-image and numpy.
    """
    im = np.array(imread(hologram_path), dtype=np.float64)
    # Some TIF images are saved as 3D arrays (one slice per color)
    if im.ndim == 3:
        warnings.warn('Image at {} is not grayscale. Only considering the first slice.'.format(hologram_path), UserWarning)
        return im[:,:,0]
    return im

def _find_peak_centroid(image, wavelength=405e-9, gaussian_width=10):
    """
    Smooth the image, find centroid of peak in the image.
    """
    wavelength = np.atleast_1d(wavelength).reshape((1,1,-1))
    F = gaussian_filter(image, gaussian_width) # Filter with a gaussian
    M = maximum_filter(F,3) # Get 8-neighbor maxima
    tfm = M==F # Maxima location TF array
    m = F[tfm] # Maxima
    idx = m.argsort()[::-1] # Sort the maxima, get the sorted indices in descending order
    x, y = np.nonzero(tfm) # Maxima locations
    # Grab top 2*#wavelengths + 1 peaks
    x = x[idx[0:(2*wavelength.shape[2]+1)]]
    y = y[idx[0:(2*wavelength.shape[2]+1)]]
    rsq = (x-image.shape[0]/2)**2 + (y-image.shape[1]/2)**2
    dist = np.sort(rsq)[1:] # Sort distances in ascending order
    idx = np.argsort(rsq)[1:] # Get sorted indices
    order = wavelength.reshape(-1).argsort()
    peaks = np.zeros([wavelength.shape[2],2])
    for o in order:
        i1 = idx[2*o]
        i2 = idx[2*o + 1]
        y1 = y[i1]
        y2 = y[i2]
        i = i1
        if y1 < y2:
            i = i2
        peaks[o,:] = [x[i], y[i]]

    return peaks

def _crop_image(image, crop_fraction):
    """
    Crop an image by a factor of ``crop_fraction``.
    """
    if crop_fraction == 0:
        return image

    crop_length = int(image.shape[0] * crop_fraction)

    if crop_length not in TWO_TO_N:
        message = ("Final dimensions after crop should be a power of 2^N. "
                   "Crop fraction of {0} yields dimensions ({1}, {1})"
                   .format(crop_fraction, crop_length))
        warnings.warn(message, CropEfficiencyWarning)

    cropped_image = image[crop_length//2:crop_length//2 + crop_length,
                          crop_length//2:crop_length//2 + crop_length]
    return cropped_image

def _crop_to_square(image):
    """
    Ensure that hologram is square.
    """
    sh = image.shape
    if sh[0] != sh[1]:
        square_image = image[:min(sh), :min(sh)]
    else:
        square_image = image

    return square_image

class CropEfficiencyWarning(AstropyUserWarning):
    pass

class MaskSizeWarning(AstropyUserWarning):
    pass

class UpdateError(Exception):
    pass

class SizeError(Exception):
    pass

class Hologram(object):
    """
    Container for holograms and methods to reconstruct them.
    """
    def __init__(self, hologram, crop_fraction=None, wavelength=405e-9,
                 rebin_factor=1, dx=3.45e-6, dy=3.45e-6):
        """
        Parameters
        ----------
        hologram : `~numpy.ndarray`
            Input hologram. If the hologram was taken with multiple wavelengths,
            the array should be a stack of single-wavelength hologram along axis 2.
        crop_fraction : float
            Fraction of the image to crop for analysis
        wavelength : float [meters] or iterable
            Wavelength of laser. Multiple wavelengths can be given as well.
        rebin_factor : int
            Rebin the image by factor ``rebin_factor``. Must be an even integer.
        dx : float [meters]
            Pixel width in x-direction (unbinned)
        dy : float [meters]
            Pixel width in y-direction (unbinned)

        Notes
        -----
        Non-square holograms will be cropped to a square with the dimensions of
        the smallest dimension. TODO: Why are we not zero-filling out to the next
        power of 2 instead of cropping?
        """
        wavelength = np.atleast_1d(wavelength).reshape((1,1,-1))

        self.crop_fraction = crop_fraction
        self.rebin_factor = rebin_factor

        hologram = np.asarray(hologram, dtype = np.float)
        if hologram.ndim != 2:
            raise ValueError('hologram dimensions ({}) are invalid. Holograms should be 2D image'.format(hologram.shape))
        # Rebin the hologram
        square_hologram = _crop_to_square(hologram)
        binned_hologram = rebin_image(square_hologram, self.rebin_factor)

        # Crop the hologram by factor crop_factor, centered on original center
        if crop_fraction is not None:
            self.hologram = _crop_image(binned_hologram, crop_fraction)
        else:
            self.hologram = binned_hologram

        self.n = self.hologram.shape[0]
        self.wavelength = wavelength
        self.wavenumber = 2*np.pi/self.wavelength
        self._spectral_peak = None
        self._chromatic_shift = None
        self.dx = dx*rebin_factor
        self.dy = dy*rebin_factor
        self.mgrid = np.mgrid[0:self.n, 0:self.n]
        self.random_seed = RANDOM_SEED
        self.apodization_window_function = None
        self._ft_hologram = None;

    @property
    def ft_hologram(self, apodize=True):
        """
        `~numpy.ndarray` of the self.hologram FFT
        """
        if self._ft_hologram is None:
            if apodize==True:
                apodized_hologram = self.apodize(self.hologram)
                self._ft_hologram = fftshift(fft2(apodized_hologram))
            else:
                self._ft_hologram = fftshift(fft2(self.hologram))

        return self._ft_hologram

    @property
    def spectral_peak(self):
        if self._spectral_peak is None:
            # Guess 'em
            self.update_spectral_peak(self.fourier_peak_centroid())

        return self._spectral_peak

    @property
    def chromatic_shift(self):
        if self._chromatic_shift is None:
            self._chromatic_shift = np.zeros_like(self.wavelength);
            # Ideally we'd actually calculate the chromatic shift
        return self._chromatic_shift

    @classmethod
    def from_tif(cls, hologram_path, **kwargs):
        """
        Load a hologram from a TIF file.

        This class method takes the path to the TIF file as the first argument.
        All other arguments are the same as `~shampoo.Hologram`.

        Parameters
        ----------
        hologram_path : str
            Path to the hologram to load
        """
        hologram = _load_hologram(hologram_path)
        return cls(hologram, **kwargs)

    def reconstruct(self, propagation_distance, spectral_peak=None, fourier_mask=None, chromatic_shift=None):
        """
        Reconstruct the hologram at all ``propagation_distance`` for all ``self.wavelength``.

        Parameters
        ----------
        propagation_distances : float or iterable of float
            Propagation distance(s) to reconstruct
        spectral_peak : `~numpy.ndarray`
            Centroid of spectral peak for wavelength in power spectrum of hologram FT
            (len(self.wavelength) x 2)
        fourier_mask : array_like or None, optional
            Fourier-domain mask. If None (default), a mask is determined from the position of the
            main spectral peak. If array_like, the array will be cast to boolean.

        Returns
        -------
        reconstructed : ReconstructedWave
            Container object for the reconstructed wave.
        """

        propagation_distance = np.atleast_1d(propagation_distance)

        # Determine location of spectral peak
        # Did we specify a centroid? OK, use it.
        if spectral_peak is not None:
            self.update_spectral_peak(spectral_peak)

        if chromatic_shift is not None:
            self.update_chromatic_shift(chromatic_shift)

        # Ignore Fourier masks that are of incorrect shape
        if fourier_mask is not None and (np.prod(fourier_mask.shape) !=
           np.prod(self.hologram.shape)*np.prod(self.wavelength.shape)*np.prod(propagation_distance.shape)):
            fourier_mask = None
            message = ("Fourier mask dimensions don't match hologram dimensions. Ignoring.")
            warnings.warn(message, MaskSizeWarning)

        if propagation_distance.size > 1:
            wave =  self._reconstruct_multithread(propagation_distance, fourier_mask = fourier_mask)
        else:
            wave = self._reconstruct(propagation_distance, fourier_mask)
            wave = np.expand_dims(wave, axis = 2)   # single prop. distance will have the wrong shape

        # TODO: unwrap phase here
        return ReconstructedWave(reconstructed_wave = wave, fourier_mask = fourier_mask,
                                 wavelength = self.wavelength, depths = propagation_distance)

    def _reconstruct(self, propagation_distance, fourier_mask=None):
        """
        Reconstruct the wave at a single ``propagation_distance`` for a single ``wavelength``.

        Parameters
        ----------
        propagation_distance : float
            Propagation distance [m]
        spectral_peak : integer pair [x,y]
            Centroid of spectral peak for wavelength in power spectrum of hologram FT
        fourier_mask : array_like or None, optional
            Fourier-domain mask. If None (default), a mask is determined from the position of the
            main spectral peak.

        Returns
        -------
        reconstructed_wave : `~numpy.ndarray` ndim 3
            The reconstructed wave as an array of dimensions (X, Y, wavelengths)
        """
        x_peak, y_peak = self.spectral_peak

        # Calculate mask radius. TODO: Update 250 to an automated guess based on input values.
        if self.rebin_factor != 1:
            mask_radius = 150./self.rebin_factor
        elif self.crop_fraction is not None and self.crop_fraction != 0:
            mask_radius = 150.*self.crop_fraction
        else:
            mask_radius = 150.

        # Either use a Fourier-domain mask based on coords of spectral peak,
        # or a user-specified mask
        if fourier_mask is None:
            mask = self.real_image_mask(x_peak, y_peak, mask_radius)
        else:
            mask = np.asarray(fourier_mask, dtype=np.bool)
        mask = np.atleast_3d(mask)

        # Calculate Fourier transform of impulse response function
        G = self.fourier_trans_of_impulse_resp_func(np.atleast_1d([propagation_distance]*
                                self.wavelength.size).reshape((1,1,-1))-self.chromatic_shift)

        # Now calculate digital phase mask. First center the spectral peak for each channel
        x_peak, y_peak = x_peak.reshape(-1), y_peak.reshape(-1)
        shifted_ft_hologram = np.empty_like(np.atleast_3d(mask),dtype=np.complex128)
        for channel in range(self.wavelength.size):
            shifted_ft_hologram[:,:,channel] = arrshift(self.ft_hologram * mask[:,:,channel],
                                                        [-x_peak[channel],
                                                         -y_peak[channel]],
                                                        axes = (0,1))

        # Apodize the result
        psi = self.apodize(shifted_ft_hologram * G)
        digital_phase_mask = self.get_digital_phase_mask(psi)

        # Reconstruct the image
        # fftshift is independent of channel
        psi = np.empty_like(np.atleast_3d(shifted_ft_hologram))

        for channel in range(psi.shape[2]):
            psi[:,:,channel] = arrshift(fftshift(fft2(self.apodize(self.hologram) * digital_phase_mask[:,:,channel],
                                        axes = (0,1))) *
                                        mask[:,:,channel],
                                        [-x_peak[channel],
                                         -y_peak[channel]],
                                        axes = (0,1))
        psi *= G

        return fftshift(ifft2(psi, axes = (0,1)), axes = (0,1))

    def get_digital_phase_mask(self, psi):
        """
        Calculate the digital phase mask (i.e. reference wave), as in Colomb et
        al. 2006, Eqn. 26 [1]_.
        Fit for a second order polynomial, numerical parametric lens with least
        squares to remove tilt, spherical aberration.
        .. [1] http://www.ncbi.nlm.nih.gov/pubmed/16512526
        Parameters
        ----------
        psi : `~numpy.ndarray`
            The product of the Fourier transform of the hologram and the Fourier
            transform of impulse response function
        Returns
        -------
        phase_mask : `~numpy.ndarray`
            Digital phase mask, used for correcting phase aberrations.
        """
        inverse_psi = fftshift(ifft2(psi, axes = (0 ,1)), axes = (0, 1))

        unwrapped_phase_image = np.atleast_3d(unwrap_phase(inverse_psi))/2/self.wavenumber
        smooth_phase_image = gaussian_filter(unwrapped_phase_image, [50, 50, 0]) # do not filter along axis 2

        high = np.percentile(unwrapped_phase_image, 99)
        low = np.percentile(unwrapped_phase_image, 1)

        smooth_phase_image[high < unwrapped_phase_image] = high
        smooth_phase_image[low > unwrapped_phase_image] = low

        # Fit the smoothed phase image with a 2nd order polynomial surface with
        # mixed terms using least-squares.
        # This is iterated over all wavelength channels separately
        # TODO: can this be done on the smooth_phase_image along axis 2 instead
        # of direct iteration?
        smooth_phase_image = smooth_phase_image
        channels = np.split(smooth_phase_image, smooth_phase_image.shape[2], axis = 2)
        fits = list()

        # Need to flip mgrid indices for this least squares solution
        y, x = self.mgrid - self.n/2
        x, y = np.squeeze(x), np.squeeze(y)

        for channel in channels:
            v = np.array([np.ones(len(x[0, :])), x[0, :], y[:, 0], x[0, :]**2,
                        x[0, :] * y[:, 0], y[:, 0]**2])
            coefficients = np.linalg.lstsq(v.T, np.squeeze(channel))[0]
            fits.append(np.dot(v.T, coefficients))

        field_curvature_mask = np.stack(fits, axis = 2)
        digital_phase_mask = np.exp(-1j*self.wavenumber * field_curvature_mask)

        return digital_phase_mask

    def apodize(self, array, alpha=0.075):
        """
        Force the magnitude of an array to go to zero at the boundaries.
        Parameters
        ----------
        array : `~numpy.ndarray`
            Array to apodize
        alpha : float between zero and one
            Alpha parameter for the Tukey window function. For best results,
            keep between 0.075 and 0.2.
        Returns
        -------
        apodized_arr : `~numpy.ndarray`
            Apodized array
        """
        if self.apodization_window_function is None:
            x, y = self.mgrid
            n = len(x[0])
            tukey_window = tukey(n, alpha)
            self.apodization_window_function = np.atleast_3d(tukey_window[:, np.newaxis] * tukey_window)

        # In the most general case, array might represent a multi-wavelength hologram
        apodized_array = np.squeeze(np.atleast_3d(array) * self.apodization_window_function)
        return apodized_array

    def fourier_trans_of_impulse_resp_func(self, propagation_distance):
        """
        Calculate the Fourier transform of impulse response function, sometimes
        represented as ``G`` in the literature.
        For reference, see Eqn 3.22 of Schnars & Juptner (2002) Meas. Sci.
        Technol. 13 R85-R101 [1]_,
        .. [1] http://x-ray.ucsd.edu/mediawiki/images/d/df/Digital_recording_numerical_reconstruction.pdf
        Parameters
        ----------
        propagation_distance : float
            Propagation distance [m]
        Returns
        -------
        G : `~numpy.ndarray`
            Fourier transform of impulse response function
        """
        x, y = self.mgrid - self.n/2
        x, y = np.atleast_3d(x), np.atleast_3d(y)
        propagation_distance = np.atleast_3d(propagation_distance)
        first_term = (self.wavelength**2 * (x + self.n**2 * self.dx**2 /
                      (2.0 * propagation_distance * self.wavelength))**2 /
                      (self.n**2 * self.dx**2))
        second_term = (self.wavelength**2 * (y + self.n**2 * self.dy**2 /
                       (2.0 * propagation_distance * self.wavelength))**2 /
                       (self.n**2 * self.dy**2))
        G = np.exp(-1j * self.wavenumber * propagation_distance *
                   np.sqrt(1.0 - first_term - second_term))
        return G

    def real_image_mask(self, center_x, center_y, radius):
        """
        Calculate the Fourier-space mask to isolate the real image

        Parameters
        ----------
        center_x : `~numpy.ndarray`
            ``x`` centroid [pixels] of real image in Fourier space for each
            image in a stack.
        center_y : `~numpy.ndarray`
            ``y`` centroid [pixels] of real image in Fourier space for each
            image in a stack.
        radius : float
            Radial width of mask [pixels] to apply to the real image in Fourier
            space

        Returns
        -------
        mask : `~numpy.ndarray`
            Binary-valued mask centered on the real-image peak in the Fourier
            transform of the hologram.
        """
        center_x, center_y = np.reshape(center_x, (1, 1, -1)), np.reshape(center_y, (1, 1, -1))
        x, y = self.mgrid
        x, y = x[:,:,None], y[:,:,None]
        x_shift = x-center_x
        y_shift = y-center_y
        mask = np.zeros_like(np.atleast_3d(x_shift), dtype = np.bool)
        mask[(x_shift)**2 + (y_shift)**2 < radius**2] = True

        # exclude corners
        #buffer = 20
        #if self.crop_fraction is not None:
        #    buffer = buffer*self.crop_fraction
        #mask[((x_shift)**2 + (y_shift)**2) < buffer**2] = 0.0

        return mask

    def fourier_peak_centroid(self, gaussian_width=10):
        """
        Calculate the centroid of the signal spike in Fourier space near the
        frequencies of the real image.

        Parameters
        ----------
        fourier_arr : `~numpy.ndarray`
            Fourier-transform of the hologram
        margin_factor : int
            Fraction of the length of the Fourier-transform of the hologram
            to ignore near the edges, where spurious peaks occur there.

        Returns
        -------
        pixel : `~numpy.ndarray`
            Pixel at the centroid of the spike in Fourier transform of the
            hologram near the real image.
        """

        return _find_peak_centroid(np.abs(self.ft_hologram), self.wavelength, gaussian_width)

    def _reconstruct_multithread(self, propagation_distances, fourier_mask=None):
        """
        Reconstruct phase or intensity for multiple distances, for one hologram.
        Parameters
        ----------
        propagation_distances : `~numpy.ndarray` or list
            Propagation distances to reconstruct
        threads : int
            Number of threads to use via `~multiprocessing`
        fourier_mask : array_like or None, optional
            Fourier-domain mask. If None (default), a mask is determined from the position of the main
            spectral peak. If array_like, the array will be cast to boolean.
        Returns
        -------
        wave_cube : `~numpy.ndarray`, ndim 4
        """
        cube = np.empty(shape = self.hologram.shape + (self.wavelength.size, len(propagation_distances)),
                        dtype = np.complex)
        with Pool(None) as pool:
            slices = pool.map( partial(self._reconstruct, fourier_mask = fourier_mask), propagation_distances)

        cube = np.stack(slices, axis = 3)
        return np.swapaxes(cube, 2, 3)

    def update_spectral_peak(self, spectral_peak):
        """
        Update spectral peak centroid values.

        Parameters
        ----------
        spectral_peak : `~numpy.ndarray`
            Centroid of spectral peak for wavelength in power spectrum of hologram FT
            (len(self.wavelength) x 2)
        """

        spectral_peak = np.atleast_2d(spectral_peak)

        if spectral_peak.shape[1] != 2 or spectral_peak.shape[0] != self.wavelength.shape[2]:
            message = ("Spectral peak array must be of shape {0} by 2. "
                       "{0} is the number of wavelengths."
                       .format(self.wavelength.shape[2]))
            raise UpdateError(message)

        spectral_peak = spectral_peak.astype(int)

        self._spectral_peak = spectral_peak.swapaxes(0,1)

    def update_chromatic_shift(self,chromatic_shift):
        """
        Update chromatic shift values for changed depth of focus for different wavelengths.

        Parameters
        ----------
        spectral_peak : `~numpy.ndarray`
            1xN_wavelength list of depth of focus changes
        """
        chromatic_shift = np.atleast_1d(chromatic_shift).reshape((1,1,-1))
        if chromatic_shift.shape[2] != self.wavelength.shape[2]:
            message = ("Chromatic shift must be of length {0} (number of wavelengths)."
                        .format(self.wavelength.shape[2]))
            raise UpdateError(message)

        self._chromatic_shift = chromatic_shift

def unwrap_phase(reconstructed_wave, wavelength=None):
    if wavelength is not None and wavelength.size == 3:
        return _unwrap_phase_multiwavelength(reconstructed_wave, wavelength.reshape(-1))
    else:
        return _unwrap_phase(reconstructed_wave)

def _unwrap_phase(reconstructed_wave, seed=RANDOM_SEED):
    """
    2D phase unwrap a complex reconstructed wave.
    Essentially a wrapper around the `~skimage.restoration.unwrap_phase`
    function.
    Parameters
    ----------
    reconstructed_wave : `~numpy.ndarray`
        Complex reconstructed wave
    seed : float (optional)
        Random seed, optional.
    Returns
    -------
    `~numpy.ndarray`
        Unwrapped phase image
    """
    phase = 2 * np.arctan(reconstructed_wave.imag / reconstructed_wave.real)

    # No channel, no need for shenanigans
    if phase.ndim < 3:
        return skimage_unwrap_phase(phase, seed=seed)

    # Each wavelength channel must be done separately
    unwrapped = np.empty_like(reconstructed_wave)
    unwrapped_channels = list()
    for phase_channel in np.dsplit(phase, phase.shape[2]):
        unwrapped_channels.append( skimage_unwrap_phase(np.squeeze(phase_channel),seed=seed) )
    return np.dstack(unwrapped_channels)

def _unwrap_phase_multiwavelength(reconstructed_wave, wavelength):
    """
    Perform multi-wavelength phase unwrapping.

    For reference, see N. Warnasooriya and M. K. Kim, Opt. Express 15, 9239-9247 (2007)

    .. [3] https://www.osapublishing.org/oe/fulltext.cfm?uri=oe-15-15-9239&id=139880

    Parameters
    ----------
    reconstructed_wave : `~numpy.ndarray`
        Complex reconstructed wave

    Returns
    -------
    `~numpy.ndarray`
        Unwrapped phase image
    """

    # TODO: Add 2-wavelength phase unwrapping.

    # Due to previous implementation
    # We must have the dimensions be (X,Y, wavelengths, Z) in this function
    reconstructed_wave = np.swapaxes(reconstructed_wave, 2, 3)

    # Get the phase maps
    # np.arctan2 returns in the range (-pi,pi) so we shift to (0, 2*pi)
    phase = np.squeeze(np.arctan2(reconstructed_wave.imag, reconstructed_wave.real) + np.pi)

    # Get the beat wavelengths
    w1,w2,w3 = tuple(wavelength)

    lambda_13 = w1*w3/np.abs(w1-w3)
    lambda_23 =w1*w2/np.abs(w1-w2)
    lambda_1323 = lambda_13*lambda_23/np.abs(lambda_13-lambda_23)

    # Get the coarse maps
    coarse_13 = phase[:,:,0,:]-phase[:,:,2,:]
    coarse_23 = phase[:,:,1,:]-phase[:,:,2,:]
    coarse_13[coarse_13<0] = coarse_13[coarse_13<0] + 2*np.pi
    coarse_23[coarse_23<0] = coarse_23[coarse_23<0] + 2*np.pi
    coarse_1323 = coarse_13 - coarse_23
    coarse_1323[coarse_1323<0] = coarse_1323[coarse_1323<0] + 2*np.pi

    # Get the surface profiles
    z_13 = lambda_13*coarse_13/(2*np.pi)
    z_23 = lambda_23*coarse_23/(2*np.pi)
    z_1323 = lambda_1323*coarse_1323/(2*np.pi)

    # Get the integer surface profile for maximum beat wavelength
    z_a = np.rint(z_1323/lambda_13)*lambda_13
    z_b = z_a + z_13
    z_c = z_1323 - z_b
    z_d = z_c
    z_d[z_c[:] > lambda_13/2] = z_c[z_c[:] > lambda_13/2] + lambda_13.reshape(-1)
    z_d[z_c[:] < -lambda_13/2] = z_c[z_c[:] < -lambda_13/2] - lambda_13.reshape(-1)

    # Get surface profiles for individual wavelength
    z = np.expand_dims(wavelength, axis = 3)*phase/(2*np.pi)
    #for channel in range(z.shape[2]):
    #    z[:,:,channel] = wavelength[:,:,channel]*phase[:,:,channel]/(2*np.pi)
    z_e = np.empty_like(z)
    for channel in range(z_e.shape[2]):
        z_e[:,:,channel] = np.rint(z_d/wavelength[channel])*wavelength[channel]
    z_f = z_e+z
    z_g = np.empty_like(z_f)
    for channel in range(z_g.shape[2]):
        z_g[:,:,channel] = z_d-z_f[:,:,channel]
    for channel in range(z_g.shape[2]):
        z_f_curr = z_f[:,:,channel]
        z_g_curr = z_g[:,:,channel]
        z_g_curr[z_f_curr[:] > wavelength[channel]/2] = z_f_curr[z_f_curr[:] > wavelength[channel]/2] + wavelength[channel]
        z_g_curr[z_f_curr[:] < -wavelength[channel]/2] = z_f_curr[z_f_curr[:] < -wavelength[channel]/2] - wavelength[channel]
        z_g[:,:,channel] = z_g_curr

    return np.swapaxes(z_g*2*np.pi/np.expand_dims(wavelength, axis = 3), 2, 3)    # Back to (X, Y, Z, wavelengths)

class ReconstructedWave(object):
    """
    Container for reconstructed waves and their intensity and phase
    arrays.
    """
    def __init__(self, reconstructed_wave, fourier_mask, wavelength, depths):
        """
        Parameters
        ----------
        reconstructed_wave : array_like, complex
            Reconstructed wave. Last axis is wavelength channel.
        fourier_mask : array_like
            Reconstruction Fourier mask, in 2- or 3- dimensions.
        wavelength : float or array_like
            Wavelength(s) of the reconstructed wave.
        depths : array_like
            Reconstruction depths, corresponding to each slice of `reconstructed_wave` along
            axis 2.
        """
        self.reconstructed_wave = reconstructed_wave
        self.depths = np.atleast_1d(depths)
        self._intensity_image = None
        self._phase_image = None
        self.fourier_mask = np.asarray(fourier_mask, dtype = np.bool)
        self.wavelength = np.atleast_1d(wavelength)
        self.random_seed = RANDOM_SEED

    @property
    def intensity(self):
        """
        `~numpy.ndarray` of the reconstructed intensity
        """
        if self._intensity_image is None:
            self._intensity_image = np.abs(self.reconstructed_wave)

        return self._intensity_image

    @property
    def phase(self):
        """
        `~numpy.ndarray` of the reconstructed, unwrapped phase.

        Returns the unwrapped phase using `~skimage.restoration.unwrap_phase`.
        """
        if self._phase_image is None:
            self._phase_image = unwrap_phase(self.reconstructed_wave, self.wavelength)

        return self._phase_image


def linha(tam=42):
    return '-' * tam

def cabecalho(txt):
    print(linha())
    print(txt.center(42))
    print(linha())

def leiaint(msg):
    while True:
        try:
            n = int(input(msg))
        except (ValueError, TypeError, KeyboardInterrupt):
            print('\n\033[31mERRO: Por favor, digite um número  válido.\033[m')
        else:
            return n

def menu(nome, op):
    cabecalho(nome)
    for idx, item in enumerate(op):
        print(f'\033[33m[{idx+1}]\033[m \033[34m{item}.\033[m')
    print(linha())
    opc = leiaint('\033[32mSua opção: \033[m')
    return opc


# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    """
        :type head: ListNode
        :type x: int
        :rtype: ListNode
        """
    def partition(self, head, x):
        dummy = ListNode(0)
        dummy.next = head
        head = dummy
        pre  = None

        while head.next != None:
            if head.next.val < x and pre != None:
                tmp = head.next
                head.next = head.next.next
                tmp.next = pre.next
                pre.next = tmp
                pre = tmp
                continue
            elif head.next.val >= x and pre == None:
                pre = head
            head = head.next

        return dummy.next


# if sense hat emulator is missing on the pi, install it:
# $ sudo apt install sense-emu-tools
import logging
from typing import Callable
from sense_emu import SenseHat
import threading
import atexit
import time

class TamperAlert:
    def __init__(self, change_percent: float = 0.1, tick: float = 0.01, movement_check_interval: float = 1):
        self.sense = SenseHat()
        # amount of change to be considered movement
        self.change_percent = change_percent
        self.tick = tick  # sampling interval
        self.movement_check_interval = movement_check_interval
        self.orientation = self.sense.get_orientation()
        self._moved_event = threading.Event()
        TamperAlert._stop_event = threading.Event()
        self._moved_thread = threading.Thread(
            target=self._run, name=f'Moved-{threading.active_count()+1}', daemon=True)
        self._moved_thread.start()

    @property
    def when_moved(self) -> Callable[[], None]:
        raise NotImplementedError

    @when_moved.setter
    def when_moved(self, callback: Callable[[], None]):
        if callback:
            self._when_moved = callback
            self._moved_event.set()

    def _run(self):
        self._moved_event.wait()  # wait until callback is set
        tick_counter = 0
        change_counter = 0
        while not TamperAlert._stop_event.is_set():
            tick_counter += 1
            orientation = self.sense.get_orientation()
            if self._changed(orientation['pitch'], self.orientation['pitch']) \
                    or self._changed(orientation['roll'], self.orientation['roll']) \
                    or self._changed(orientation['yaw'], self.orientation['yaw']):
                change_counter += 1
                if change_counter * 2 >= tick_counter:  # changed at least 50% of time
                    change_counter = 0
                    try:
                        self._when_moved()
                    except Exception as e:
                        logging.error(f'Callback failed: {e}')
            if tick_counter >= self.movement_check_interval // self.tick:
                self.orientation = orientation  # new baseline
                tick_counter = 0
                change_counter = 0
            time.sleep(self.tick)

    def _changed(self, value: float, baseline: float) -> bool:
        return abs((value-baseline)/baseline) >= self.change_percent if baseline else False

    @staticmethod
    @atexit.register
    def _stop_threads():
        if hasattr(TamperAlert, '_stop_event'):
            TamperAlert._stop_event.set()


class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """

        for idx, val in enumerate(nums):
            res = target - val
            if res in nums[idx + 1:]:
                return [idx, nums[idx + 1:].index(res) + (idx + 1)]

# class Solution:
#     def twoSum(self, nums: List[int], target: int) -> List[int]:
#         hashMap = {}
#         for i in range(len(nums)):
#             hashMap[i] = nums[i]

#         result = []
#         visited = []
#         values = list(hashMap.values())
#         for x in range(len(hashMap)):
#             visited.append(x)
#             res = target - hashMap[x]
#             if res in values[x+1:]:
#                 result.append(x)
#                 result.append(values[x+1:].index(res+x+1))
#                 if len(list(set(result))) ==2:
#                     break

#         #         if value == res:
#         #             result.append(x)
#         #             result.extend(key)
#         return result


from xivo_dao.resources.register_iax import dao as register_iax_dao
from xivo_dao.resources.trunk import dao as trunk_dao

from .resource import TrunkRegisterAssociationIAX
from .service import build_service_iax

class Plugin:
    def load(self, dependencies):
        api = dependencies['api']
        self.load_iax(api)

    def load_iax(self, api):
        service = build_service_iax()

        api.add_resource(
            TrunkRegisterAssociationIAX,
            '/trunks/<int:trunk_id>/registers/iax/<int:register_id>',
            endpoint='trunk_register_iax',
            resource_class_args=(service, trunk_dao, register_iax_dao),
        )


import os
import sys
from setuptools import setup, find_packages

def fpath(name):
    return os.path.join(os.path.dirname(__file__), name)

def read(fname):
    return open(fpath(fname)).read()

def desc():
    return read('README.rst')

setup(
    name='Flask-BabelPkg',
    version='0.9.7',
    url='http://github.com/dpgaspar/flask-babelPkg',
    license='BSD',
    author='Daniel Gaspar',
    author_email='danielvazgaspar@gmail.com',
    description='Adds i18n/l10n support to Flask applications and extensions',
    long_description=desc(),
    packages=['flask_babelpkg'],
    zip_safe=False,
    platforms='any',
    install_requires=[
        'Flask',
        'Babel>=1.0',
        'speaklater>=1.2',
        'Jinja2>=2.5'
    ],
    classifiers=[
        'Development Status :: 4 - Beta',
        'Environment :: Web Environment',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: BSD License',
        'Operating System :: OS Independent',
        'Programming Language :: Python',
        'Programming Language :: Python :: 3',
        'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
        'Topic :: Software Development :: Libraries :: Python Modules'
    ]
)


from enum import IntEnum
from typing import List, Sequence

import numpy as np
import vtk
from vtkmodules.vtkCommonDataModel import vtkImageData
from vtkmodules.vtkFiltersCore import vtkMarchingCubes

from common import convert

class Operator(IntEnum):
    UNION = 0
    INTERSECTION = 1
    ADDITION = 2

def rebuild(volumes: Sequence[np.ndarray], labels: List[int], operator: Operator, template_image, iso_value: float):
    if not volumes or not labels:
        return []

    shape = volumes[0].shape
    assert all(v.shape == shape for v in volumes)

    if operator == Operator.UNION:
        numpy_type = np.bool
        reduction_op = np.bitwise_or.reduce
        vtk_type = vtk.VTK_UNSIGNED_CHAR
    elif operator == Operator.INTERSECTION:
        numpy_type = np.bool
        reduction_op = np.bitwise_and.reduce
        vtk_type = vtk.VTK_UNSIGNED_CHAR
    elif operator == Operator.ADDITION:
        numpy_type = np.ubyte
        reduction_op = np.sum
        vtk_type = vtk.VTK_UNSIGNED_CHAR
    else:
        raise RuntimeError('Unknown volume operator')

    source = np.stack(volumes, axis=-1)
    fes = []
    for label in labels:
        result = reduction_op(source == label, axis=3, dtype=numpy_type)
        image = vtkImageData()
        image.CopyStructure(template_image)
        image.GetPointData().SetScalars(convert(result, dtype=vtk_type))
        fe = vtkMarchingCubes() # vtkDiscreteFlyingEdges3D()
        fe.SetNumberOfContours(1)
        if operator == Operator.ADDITION:
            fe.SetValue(0, iso_value)
        else:
            fe.SetValue(0, 1)

        fe.SetInputDataObject(0, image)
        image.Modified()
        fes.append(fe)

    return fes