"""
Notes:

    1) This script will make csv files for each block.
    2) Orients from block_length (number of trials per category),
        and stim_dict.
    3) Assumes dimensional stimuli are called "foo_low" and "foo_high"
        for mapping assignment.
    4) Assumes stimuli are found in ../Stimuli/foo, will write to ../blocks/BlockX.csv

Updates:
    1) Dropped "Dim" from task
    2) randomized category assignment
        writes blocks for e/subj to ../blocks/sub-*/BlockX.csv
        receives single subj arg
        removed "dim" syntax (for syntax - v0.1)

TODO
    1) update to receive list of subj?

Usage: python job_taskSetup.py 1
"""
import os
import sys
import random
import pathlib
from random import randrange
import pandas as pd

def main(subj):
    """
    Set up

    Fix1/2 = fixed mapping
    Cond = conditional mapping

    stim_dict["Block1"]["Fix1"]: "School" = School
        stimuli will be used for fixed mapping in block1.
        Also, stimuli will be located in stim_dir/School
    """

    # set paths
    parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

    stim_dir = os.path.join(parent_dir, "stimuli")
    stim_p = pathlib.Path(stim_dir)
    stim_rel = pathlib.Path(*stim_p.parts[5:])

    block_dir = os.path.join(parent_dir, "blocks")
    if not os.path.exists(block_dir):
        os.makedirs(block_dir)

    """
    Make stim lists per block, for psychopy.

    Will randomize L/R for fixed and dimension mappings (ref coin_toss).
    Conditional mapping is based off preceding trial.
    Dataframe will not start with conditional trial.
    """

    # set block length
    block_length = 60

    # dict of categories
    cat_list = [
        "Dangerous",
        "Healthy",
        "Old",
        "Sad",
        "School",
        "Small",
        "Smell",
        "Soft",
        "Wealth",
    ]

    # make random stim_dict
    cat_rand = random.sample(cat_list, len(cat_list))
    stim_dict = {
        "Block1": {"Fix1": cat_rand[0], "Fix2": cat_rand[1], "Cond": cat_rand[2]},
        "Block2": {"Fix1": cat_rand[3], "Fix2": cat_rand[4], "Cond": cat_rand[5]},
        "Block3": {"Fix1": cat_rand[6], "Fix2": cat_rand[7], "Cond": cat_rand[8]},
    }

    # make individual blocks
    for block in stim_dict:
        # block = "Block1"

        # randomly assign fixed mapping
        coin_toss = randrange(2)
        corr_A = "left" if coin_toss == 1 else "right"
        corr_B = "left" if corr_A == "right" else "right"

        # set up block dictionary
        #   pull random stim of length = block_length
        block_dict = {
            "Fix1": [
                [corr_A] * block_length,
                [
                    os.path.join(stim_rel, stim_dict[block]["Fix1"], x)
                    for x in random.sample(
                        os.listdir(os.path.join(stim_dir, stim_dict[block]["Fix1"])),
                        block_length,
                    )
                ],
            ],
            "Fix2": [
                [corr_B] * block_length,
                [
                    os.path.join(stim_rel, stim_dict[block]["Fix2"], x)
                    for x in random.sample(
                        os.listdir(os.path.join(stim_dir, stim_dict[block]["Fix2"])),
                        block_length,
                    )
                ],
            ],
            "Cond": [
                ["Cond"] * block_length,
                [
                    os.path.join(stim_rel, stim_dict[block]["Cond"], x)
                    for x in random.sample(
                        os.listdir(os.path.join(stim_dir, stim_dict[block]["Cond"])),
                        block_length,
                    )
                ],
            ],
        }

        # make master_dict for pandas df, randomize df,
        #   don't start with cond type
        master_dict = {f"{block}Type": [], f"{block}Stim": [], f"{block}Corr": []}
        for key in block_dict.keys():
            for ind in range(0, block_length):
                master_dict[f"{block}Type"].append(key)
                master_dict[f"{block}Stim"].append(block_dict[key][1][ind])
                master_dict[f"{block}Corr"].append(block_dict[key][0][ind])

        df = pd.DataFrame.from_dict(master_dict)
        df_rand = df.sample(frac=1).reset_index(drop=True)
        while df_rand.at[0, f"{block}Type"] == "Cond":
            df_rand = df.sample(frac=1).reset_index(drop=True)

        # Set conditional response (opposite from previous)
        for ind in range(0, df_rand.shape[0]):
            if df_rand.at[ind, f"{block}Corr"] == "Cond":
                old_val = df_rand.at[ind - 1, f"{block}Corr"]
                df_rand.at[ind, f"{block}Corr"] = (
                    "left" if old_val == "right" else "right"
                )

        # write df_rand to csv
        subj_dir = os.path.join(block_dir, f"sub-{subj}")
        if not os.path.exists(subj_dir):
            os.makedirs(subj_dir)
        df_rand.to_csv(os.path.join(subj_dir, f"{block}.csv"), index=False)

if __name__ == "__main__":
    h_subj = sys.argv[1]
    main(h_subj)


import sys
import numpy as np
import tensorflow as tf
import cv2

import tensorflow.contrib.slim as slim
import tensorflow.contrib.layers as layers
import os
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from PIL import Image

from primesense import openni2
from primesense import _openni2 as c_api

from django_project.Hand_pose_estimation_part.data.importers import DepthImporter
from django_project.Hand_pose_estimation_part.netlib.basemodel import basenet2
from django_project.Hand_pose_estimation_part.util.realtimehandposepipeline import RealtimeHandposePipeline
from django_project.Object_detectin_part.hand_detection_RGBD import detection_results

##===================================Overview======================================================

# The system is composed from 2 main steps  :
#  1-  Hand Detection : to crop the area of interest containing the hand
#  2-  Hand Pose Estimation : to get the (X,Y) in pixels and (Z) in mm coordinates for each hand joint
# 	   using the cropped image, the final output is the araay J_Pixels

# PS : -the function model.run_sess is responsible for all the process
#
# 	   -we can add more functions to the system to exploit J_Pixels' information like getting the lowest
# 	   joint in term of depth and store it in a JSON file to controle the mose by finger mouvment
#
#      - Object detection can be done by training an SSD mobilenet detector and using the same approach
#	   of the RGB-D Hand Detector so that the 3 models can run simultaneously

#=========================Depth parameters========================================================
EXACT_TABLE_CAMERA_DISTANCE = 2000	  # in mm, greater depth values will be replaced by this one
DEPTH_THRESHOLD = 200 # in mm     ,  smaller depth values will be replaced by this one

## depth correction Coefs in case there are some problems

CORRECTION_COEF_1_AFTER_LOADING = 1
DEPTH_CORRECTION = 1
ADD_RANGE_CORRECTION = 0

## A function to rescale depth values from maximum-minimum to 0-255
## RGB-D Hand detector uses RGB(0-255) encoded format instead of 1 depth channel with mm values
min_depth_for_scaling = 0   # changes for each image
max_depth_for_scaling = 1500
def Depth_to_255_scale(entry):
    if entry>max_depth_for_scaling or entry<50:
        return 0
    else :
        return 255-((entry-min_depth_for_scaling)/(max_depth_for_scaling-min_depth_for_scaling)*255)

Depth_to_255_scale = np.vectorize(Depth_to_255_scale)

## A function to remove depth noise (noisy values are zeros)
def remove_noise(entry):
	global m
	mapper_dict = {0:m}   ## noise replaced by maximum depth in every frame

	return mapper_dict[entry] if entry in mapper_dict else entry

remove_noise = np.vectorize(remove_noise)
m = 0

def DepthMapCorrection(depth):
		"""
		Correcting the depth map
		:return: image data of depth image
		"""
		global m,MAXIMUM_DEPTH_RANGE,CORRECTION_COEF_1_AFTER_LOADING,DEPTH_CORRECTION, min_depth_for_scaling

		## Storing maximum depth
		m = np.max(depth)
		## removing noise
		depth = remove_noise(depth)
		##storing minimum depth
		min_depth_for_scaling = np.min(depth)
		## Converting to a numpy array
		imgdata = np.asarray(depth, np.float32)/CORRECTION_COEF_1_AFTER_LOADING*DEPTH_CORRECTION + ADD_RANGE_CORRECTION

		return imgdata

## The hand Pose estimation Model :
class model_setup():
	def __init__(self,dataset,model_path):
		self._dataset=dataset
		self.model_path=model_path
		self.inputs = tf.placeholder(dtype=tf.float32, shape=(None, 96, 96, 1))  ## Image size is fixed
		self.hand_tensor=None
		self.model()
		self.saver = tf.train.Saver(max_to_keep=15)

### the model's configurations
	def __self_dict(self):
		return (14,9,5)

	def __config(self):
		flag=-1
		di = DepthImporter(fx=535.4, fy=flag*539.2, ux=320.1, uy=247.6)
		config = {'fx': di.fx, 'fy': abs(di.fy), 'cube': (250,250, 250), 'im_size': (96, 96)}
		return di, config

	def __crop_cube(self):
		return self.__config()[1]['cube'][0]
	def __joint_num(self):
		return self.__self_dict()[0]

## the model's initialization
	def model(self):
		outdims=self.__self_dict()
		fn = layers.l2_regularizer(1e-5)
		fn0 = tf.no_regularizer
		with slim.arg_scope([slim.conv2d, slim.fully_connected],
							weights_regularizer=fn,
							biases_regularizer=fn0, normalizer_fn=slim.batch_norm):
			with slim.arg_scope([slim.batch_norm],
								is_training=False,
								updates_collections=None,
								decay=0.9,
								center=True,
								scale=True,
								epsilon=1e-5):
				pred_comb_ht, pred_comb_hand, pred_hand, pred_ht = basenet2(self.inputs, kp=1, is_training=False,
																			outdims=outdims)

		self.hand_tensor=pred_hand

### the entire process :

	def sess_run(self,detection_graph=0,detection_sess=0):

		## rtp library, containing some useful functions
		_di,_config=self.__config()

		rtp = RealtimeHandposePipeline(1, config=_config, di=_di, verbose=False, comrefNet=None,maxDepth=EXACT_TABLE_CAMERA_DISTANCE,minDepth=DEPTH_THRESHOLD)
		joint_num=self.__joint_num()  ## 14 joints
		cube_size=self.__crop_cube()  ##  to rescale the cropped hand image

		with tf.Session() as sess:
			init = tf.global_variables_initializer()
			sess.run(init)
			self.saver.restore(sess, self.model_path)

			### Initialize OpenNI with its libraries

			frameRate = 30
			width = 640 		# Width of image
			height = 480		# height of image
			openni2.initialize("django_project\\orbbec-astra\\Redist") #The OpenNI2 Redist folder
			# Open a device
			dev = openni2.Device.open_any()
			# Open two streams: one for color and one for depth
			depth_stream = dev.create_depth_stream()
			depth_stream.start()
			depth_stream.set_video_mode(c_api.OniVideoMode(pixelFormat = c_api.OniPixelFormat.ONI_PIXEL_FORMAT_DEPTH_1_MM, resolutionX = width, resolutionY = height, fps = frameRate))

			color_stream = dev.create_color_stream()
			color_stream.start()
			color_stream.set_video_mode(c_api.OniVideoMode(pixelFormat = c_api.OniPixelFormat.ONI_PIXEL_FORMAT_RGB888, resolutionX = width, resolutionY = height, fps = frameRate))

			# Register both streams so they're aligned
			dev.set_image_registration_mode(c_api.OniImageRegistrationMode.ONI_IMAGE_REGISTRATION_DEPTH_TO_COLOR)
			# Set exposure settings
			# Camera Exposure
			bAutoExposure = Fals
			exposure = 100
			if (color_stream.camera != None):
				color_stream.camera.set_auto_exposure(bAutoExposure)
				color_stream.camera.set_exposure(exposure)

			## ===================================main loop==============================================
			while True:

				## Loading and correcting depth frame
				frame = depth_stream.read_frame()
				frame_data = frame.get_buffer_as_uint16()
				depthPix = np.frombuffer(frame_data, dtype=np.uint16)
				depthPix.shape = (height, width)

				depthPix = DepthMapCorrection(depthPix)

				## ____________________RGB-D based hand detection :____________________________________
				# transform 1 channel depth image to RGB channels
				detection_frame = np.array(Image.fromarray(Depth_to_255_scale(depthPix)).convert('RGB'))

				##Detection :
				processed_image, cropped,[xmin,xmax,ymin,ymax] = detection_results( detection_graph,detection_frame ,detection_sess,score_threshold=0.2)
				cv2.imshow('detection_frame',processed_image)

				depthPix_original = depthPix.copy()
				depthPix = depthPix[xmin : xmax, ymin:ymax]
				cv2.imshow('cropped',cropped)
				## returning cropped depth image :depthPix  (original size 200x200 : change it in the hand detection folder )

				try:
					## loc is the center's coordinates of our bounding box in (pixels,pixels,mm), used to make the center of mass of the hand closer to it instead of the closest object to the camera
					loc_rgbd_detector = [depthPix.shape[0]//2,depthPix.shape[1]//2,depthPix[depthPix.shape[0]//2,depthPix.shape[1]//2]]

					## Countour based Hand detection + image preprocessing + the hand's center of mass com3D
					crop1, M, com3D,bounds = rtp.detect(depthPix,loc_rgbd_detector)
					if com3D[0]==0:
						continue # skipping errors during hand detection using COM and contours

					crop = crop1.reshape(1, crop1.shape[0], crop1.shape[1], 1).astype('float32')

					##____________________________Hand pose estimation______________________________________
					pred_ = sess.run(self.hand_tensor, feed_dict={self.inputs: crop})
					norm_hand = np.reshape(pred_, (joint_num, 3))

					## from normalized and relative to com3D to global coordinates
					pose = norm_hand * cube_size / 2. + com3D

					## Show results
					img,J_pixels = rtp.show3(depthPix_original, pose,self._dataset,(np.float32(xmin), np.float32(ymin)))
					cv2.imshow('frame', img)
					cv2.imshow('crop1', crop1)

					print('com3D :',com3D,' pose[0] :',pose[0],' pixels[0] ' ,J_pixels[0])
				except:
					print('error happened')
					continue
				if cv2.waitKey(1) >= 0:
					break
		openni2.unload()

		cv2.destroyAllWindows()


import pygame
import random
from defs import *

class Bird():
    def __init__(self, gameDisplay): #initialize bird and its features
        self.gameDisplay = gameDisplay
        self.state = BIRD_ALIVE #Bird starts alive
        self.img = pygame.image.load(BIRD_FILENAME) #Load image of bird
        self.rect = self.img.get_rect() #Is used to find the position of bird
        self.speed = 0 #start with 0 speed
        self.time_lived = 0 #start with no time lived (This is for the AI to see if its doing well
        self.set_position(BIRD_START_X, BIRD_START_Y) #Startposition

    def set_position(self, x, y):
        self.rect.centerx = x
        self.rect.centery = y

    def move(self, dt): #When moving
        distance = 0 #empty distance
        new_speed = 0 #empty speed

        distance = (self.speed * dt) + (0.5 * GRAVITY * dt * dt) #s = ut + 0.5at^2
        new_speed = self.speed + (GRAVITY * dt) #v = u + at

        self.rect.centery += distance #Set the position of the bird on the y axis
        self.speed = new_speed #Set speed of the bird

        if self.rect.top < 0: #If the bird goes above the screen
            self.rect.top = 0 #stay in screen
            self.speed = 0 #set speed to 0

    def jump(self):
        self.speed = BIRD_START_SPEED #If jump is used, set speed again

    def draw(self):
        self.gameDisplay.blit(self.img, self.rect) #Draw every frame

    def check_status(self, pipes): #Check if the bird still lives
        if self.rect.bottom > DISPLAY_H: #If it is below the screen
            self.state = BIRD_DEAD
        else: #if not
            self.check_hits(pipes) #check if it hit with the pipes

    def check_hits(self, pipes):
        for p in pipes: #for every pipe in the list
            if p.rect.colliderect(self.rect): #When the bird collides with a pipe
                self.state = BIRD_DEAD
                break

    def update(self, dt, pipes):
        if self.state == BIRD_ALIVE: #if alive, call all the actions below
            self.time_lived += dt
            self.move(dt)
            self.draw()
            self.check_status(pipes)

class BirdCollection():
    def __init__(self, gameDisplay):
        self.gameDisplay = gameDisplay
        self.birds = []
        self.create_new_generation()

    def create_new_generation(self):
        self.birds = []
        for i in range(0, GENERATION_SIZE):
            self.birds.append(Bird(self.gameDisplay))

    def update(self, dt, pipes):
        num_alive = 0
        for b in self.birds:
            if random.randint(0,4) == 1:
                b.jump()
            b.update(dt,pipes)
            if b.state == BIRD_ALIVE:
                num_alive += 1

        return num_alive


import pygame
import sys
from pygame.locals import *
from random import randint

class Player(pygame.sprite.Sprite):
    '''The class that holds the main player, and controls how they jump. nb. The player doens't move left or right, the world moves around them'''
    def __init__(self, start_x, start_y, width, height):

        pygame.sprite.Sprite.__init__(self)

        # Define list of images
        self.images = []
        self.images.append(pygame.transform.scale(
            pygame.image.load(player_image), (width, height)))
        self.images.append(pygame.transform.scale(
            pygame.image.load(player_image2), (width, height)))
        # Create an index for the images
        self.index = 0
        # Initialize to first image
        self.image = self.images[self.index]

        self.rect = self.image.get_rect()
        self.rect.x = start_x
        self.rect.y = start_y
        self.speed_y = 0
        self.base = pygame.Rect(start_x, start_y + height, width, 2)

        self.sound = pygame.mixer.Sound(jump_sound)
        self.sound.set_volume(0.2)

        self.dogsound = pygame.mixer.Sound(dog_sound)
        self.dogsound.set_volume(1.0)

    def move_y(self):
        '''this calculates the y-axis movement for the player in the
        current speed'''
        collided_y = world.collided_get_y(self.base)
        # If upward velocity or not colliding, treat as free
        if self.speed_y <= 0 or collided_y < 0:
            # Move according to speed
            self.rect.y = self.rect.y + self.speed_y
            # Accelerate speed downward
            self.speed_y = self.speed_y + gravity
        # If colliding and not moving upward
        if collided_y >0 and self.speed_y > 0:
            # y position is at the top of the block
            self.rect.bottom = collided_y

        self.base.y = self.rect.y+self.rect.height

    def jump(self, speed):
        '''This sets the player to jump, but it only can if its feet are on the floor'''
        if world.collided_get_y(self.base)>0:
            self.speed_y = speed
            self.index = 1
            self.image = self.images[self.index]
            self.sound.play()

    def update(self):
        ''' This changes the image back to standard if touching ground '''
        if world.collided_get_y(self.base)>0 and self.index >0 :
            self.index = 0
            self.image = self.images[self.index]

    def animate(self, ind):
        self.image = self.images[ind]

class World():
    '''This will hold the platforms and the goal.
    nb. In this game, the world moves left and right rather than the player'''
    def __init__(self, level, block_size, color_platform, color_goals):
        self.platforms = []
        self.goals = []
        self.posn_y = 0
        self.color = color_platform
        self.color_goals = color_goals
        self.block_size = block_size
        self.sound = pygame.mixer.Sound(level_sound)
        self.sound.play()

        for line in level:
            self.posn_x = 0
            for block in line:
                if block == '-':
                    self.platforms.append(pygame.Rect(
                        self.posn_x, self.posn_y,
                        block_size, block_size))
                if block == 'G':
                    self.goals.append(Goals(self.posn_x, self.posn_y))

                self.posn_x = self.posn_x + block_size
            self.posn_y = self.posn_y + block_size

    def move(self, dist):
        '''move the world dist pixels right (a negative dist means left)'''
        for block in self.platforms:
            block.move_ip(dist, 0)

        for block in self.goals:
            block.move_x(dist)

    def collided_get_y(self, player_rect):
        '''get the y value of the platform the player is currently on'''
        return_y = -1
        for block in self.platforms:
            if block.colliderect(player_rect):
                return_y = block.y + 1
        return return_y

    def at_goal(self, player_rect):
        '''return True if the player is currently in contact with the goal. False otherwise'''
        for block in self.goals:
            if block.rect.colliderect(player_rect):
                return True
        return False

    def update(self, screen):
        '''draw all the rectangles onto the screen'''
        for block in self.platforms:
            pygame.draw.rect(screen, self.color, block, 0)
        for block in self.goals:
            self.ball_plain = pygame.sprite.RenderPlain(self.goals)
            self.ball_plain.draw(screen)
            #pygame.draw.rect(screen, self.color_goals, block, 0)

class Doom():
    '''this class holds all the things that can kill the player'''
    def __init__(self, fireball_num, pit_depth, color):
        self.base = pygame.Rect(0, screen_y - pit_depth,
                    screen_x, pit_depth)
        self.color = color
        self.fireballs = []
        for i in range(0, fireball_num):
            self.fireballs.append(Fireball())
        self.fireball_plain = pygame.sprite.RenderPlain(self.fireballs)

        self.sound = pygame.mixer.Sound(explo_sound)
        self.sound.set_volume(0.5)

    def move(self, dist):
        '''move everything right dist pixels (negative dist means left)'''
        for fireball in self.fireballs:
            fireball.move_x(dist)

    def update(self, screen):
        '''move fireballs down, and draw everything on the screen'''
        for fireball in self.fireballs:
            fireball.move_y()
        self.fireball_plain.draw(screen)
        pygame.draw.rect(screen, self.color, self.base, 0)

    def collided(self, player_rect):
        '''check if the player is currently in contact with any of the doom.
        nb. shrink the rectangle for the fireballs to make it fairer'''
        for fireball in self.fireballs:
            if fireball.rect.colliderect(player_rect):
                hit_box = fireball.rect.inflate(
                    -int(fireball_size/2),
                    -int(fireball_size/2))
                if hit_box.colliderect(player_rect):
                    return True
        return self.base.colliderect(player_rect)

class Fireball(pygame.sprite.Sprite):
    '''this class holds the fireballs that fall from the sky'''
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.transform.scale(
            pygame.image.load(fireball_image),
            (fireball_size, fireball_size))
        self.rect = self.image.get_rect()
        self.reset()

    def reset(self):
        '''re-generate the fireball a random distance along the screen and give them a random speed'''
        self.y = 0
        self.speed_y = randint(fireball_low_speed, fireball_high_speed)
        self.x = randint(0, screen_x)
        self.rect.topleft = self.x, self.y

    def move_x(self, dist):
        '''move the fireballs dist pixels to the right
        (negative dist means left)'''
        self.rect.move_ip(dist, 0)
        if self.rect.x < -50 or self.rect.x > screen_x:
            self.reset()

    def move_y(self):
        '''move the fireball the appropriate distance down the screen
        nb. fireballs don't accellerate with gravity, but have a random speed. if the fireball has reached the bottom of the screen,
        regenerate it'''
        self.rect.move_ip(0, self.speed_y)
        if self.rect.y > screen_y:
            self.reset()

    def update(self, screen, colour):
        '''draw the fireball onto the screen'''
        pass

class Goals(pygame.sprite.Sprite):
    '''this class holds the fireballs that fall from the sky'''
    def __init__(self, xpos, ypos):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.transform.scale(
            pygame.image.load(ball_image),
            (ball_size, ball_size))
        self.rect = self.image.get_rect()
        self.rect.topleft = xpos, ypos

    def move_x(self, dist):
        '''move the fireballs dist pixels to the right
        (negative dist means left)'''
        self.rect.move_ip(dist, 0)

    def update(self, screen, colour):
        '''draw the fireball onto the screen'''
        pass

# options
mult = 2
screen_x = 600*mult
screen_y = 400*mult
game_name = "Awesome Raspberrylock size 30, posn_x 7050 posn_y 0"
player_spawn_x = 50
player_spawn_y = 200
player_image = "bruceside.png"
player_image2 = "bruce_turn_small.png"

player_width, player_height = int(30*mult), int(28*mult)
#player_width, player_height = 30*2, 28*2

ball_size = 15*mult
ball_image = "dryer_ball.png"

gravity = 0.8*mult
jump_speed = -10*mult

level=[
    "                    ",
    "                    ",
    "                    ",
    "                    ",
    "                    ",
    "                    ",
    "                    ",
    "                    ",
    "                    ",
    "          -       G ",
    "     - --   ---  -  ",
    " -- -          --   "]
   #"--------------------"

platform_color = (100, 100, 100)
block_size = int(30*mult)
goal_color = (0, 0, 255)
doom_color = (255, 0, 0)
fireball_size = int(20*mult)
fireball_number = 10
fireball_low_speed = 3
fireball_high_speed = 7
fireball_image = "flame.png"

# Sounds
jump_sound = "qubodup-cfork-ccby3-jump.ogg"
level_sound = "ambientmain_0_0.ogg"
explo_sound = "explosion1.ogg"
dog_sound = "dog_sound_1.ogg"

# initialise pygame.mixer
pygame.mixer.pre_init(44100, -16, 8, 2048)
pygame.mixer.init()

# initialise pygame
pygame.init()
window = pygame.display.set_mode((screen_x, screen_y))
pygame.display.set_caption(game_name)
screen = pygame.display.get_surface()

# load level
if len(sys.argv) > 1:
    with open(sys.argv[1]) as f:
        level = f.readlines()

# initialise variables
clock = pygame.time.Clock()
finished = False
player = Player(player_spawn_x, player_spawn_y, player_width, player_height)
player_plain = pygame.sprite.RenderPlain(player)
world = World(level, block_size, platform_color, goal_color)
doom = Doom(fireball_number, 10, doom_color)

# setup the background
background_image = "Catacomb_Entrance_Hall_by_KingCloud_crop.png"
#background_image = "Catacomb_Entrance_Hall_by_KingCloud.jpg"
#background_image = "ex_background.png"
background = pygame.transform.scale(pygame.image.load(background_image),
                                    (screen_x, screen_y)).convert()

bg_1_x = 0
bg_2_x = screen_x

while not finished:
    # blank screen
    screen.fill((0,0,0))
    # check events
    for event in pygame.event.get():
        if event.type == QUIT:
            finished = True

    # check which keys are held
    key_state = pygame.key.get_pressed()
    if key_state[K_LEFT]:
        world.move(2*mult)
        doom.move(2*mult)
        # move background at slower pace
        bg_1_x = bg_1_x + 1
        bg_2_x = bg_2_x + 1
        # if going into negative space, bring screen 2 to -screen_x + amount negative
        if bg_1_x > 0:
            bg_2_x = -screen_x+bg_1_x

    elif key_state[K_RIGHT]:
        world.move(-2*mult)
        doom.move(-2*mult)
        # move background at slower pace
        bg_1_x = bg_1_x - 1
        bg_2_x = bg_2_x - 1

        # if have moved to edge, put screen 1 in front
        if bg_2_x < 0:
            bg_1_x = screen_x+bg_2_x
        # if going from negative to positive space, bring screen 2 back in front minus movement amount
        if bg_1_x < 0:
            bg_2_x = screen_x+bg_1_x

    if key_state[K_SPACE]:
        player.jump(jump_speed)

    # move the player with gravity
    player.move_y()
    # Update the image based on whether jumping or not
    player.update()
    # render the frame
    screen.blit(background, (bg_1_x,0))
    screen.blit(background, (bg_2_x,0))
    player_plain.draw(screen)
    world.update(screen)
    doom.update(screen)

    # update the display
    pygame.display.update()
    # check if the player is dead
    if doom.collided(player.rect):
        doom.sound.play()
        pygame.time.wait(1500)
        print("You Lose!")
        finished = True
    # check if the player has completed the level
    if world.at_goal(player.rect):
        player.animate(1)
        player_plain.draw(screen)
        pygame.display.update()
        player.dogsound.play()
        pygame.time.wait(1000)
        print("Winner!")
        finished = True
    # set the speed in fps
    clock.tick(20)

pygame.quit()


import interpolation
from matplotlib import pyplot as plt
import numpy as np
from load_foil import *

x3_known = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
y3_knwon = [0, 0.001, 0.008, 0.027, 0.064, 0.125, 0.216, 0.343, 0.512, 0.729, 1]
spline_values = interpolation.spline(x3_known, y3_knwon, 11, 0, 3)

## Plot the interpolation of x^3
def x3_interpolation():
    x_abs = np.linspace(0, 1, 100)
    y_ord = []

    for i in range(len(x_abs)):
        y_ord.append(interpolation.splint(x3_known, y3_knwon, spline_values, 11, x_abs[i]))

    plt.plot(x_abs, y_ord)
    plt.show()

## Plot the error curve:
def x3_error():
    x_abs = np.linspace(0, 1, 1000)
    error = []

    for i in range(len(x_abs)):
        error.append(np.linalg.norm(interpolation.splint(x3_known, y3_knwon, spline_values, 11, x_abs[i])-pow(x_abs[i], 3))/np.linalg.norm(pow(x_abs[i], 3)))

    plt.plot(x_abs, error)
    plt.yscale('log')
    plt.grid(True,which="both")
    plt.xlabel(r"x")
    plt.ylabel(r"Error")

    plt.show()

## Plot the error in fuction of the number of known points:
def error_num_points():
    errors = []
    for i in range(5, 100):
        x_tested = np.linspace(0, 1, 10*i, endpoint=False)
        error = []
        x_known = np.linspace(0, 1, i, endpoint=False)
        y_known = [pow(x, 3) for x in x_known]
        spline_values3 = interpolation.spline(x_known, y_known, len(x_known), 0, 3)

        for j in range(len(x_tested)):
            error.append(abs(interpolation.splint(x_known, y_known, spline_values3, len(x_known), x_tested[j])-pow(x_tested[j], 3)))

        errors.append(max(error))

    plt.plot(range(5, 100), errors)
    plt.yscale('log')
    plt.grid(True,which="both")
    plt.xlabel(r"Point number")
    plt.ylabel(r"Error")

    plt.show()


# -*- coding: utf-8 -*-
"""
Resources below '/<api_base>/task'
"""
import logging
import json

from flask import g, request, url_for
from flask_restful import Resource
from . import with_user_or_node, with_user, only_for
from ._schema import TaskSchema, TaskIncludedSchema, TaskResultSchema
from http import HTTPStatus
from flasgger import swag_from
from pathlib import Path

from vantage6.server import db
from vantage6.server import socketio
from vantage6.server.util import (
    bytes_to_base64s,
    base64s_to_bytes,
    log_full_request,
)
from vantage6.server.globals import STRING_ENCODING

module_name = __name__.split('.')[-1]
log = logging.getLogger(module_name)

def setup(api, API_BASE):
    path = "/".join([API_BASE, module_name])
    log.info('Setting up "{}" and subdirectories'.format(path))

    api.add_resource(
        Task,
        path,
        endpoint='task_without_id',
        methods=('GET', 'POST')
    )
    api.add_resource(
        Task,
        path + '/<int:id>',
        endpoint='task_with_id',
        methods=('GET', 'DELETE')
    )
    api.add_resource(
        TaskResult,
        path + '/<int:id>/result',
        endpoint='task_result',
        methods=('GET',)
    )

# ------------------------------------------------------------------------------
# Resources / API's
# ------------------------------------------------------------------------------
class Task(Resource):
    """Resource for /api/task"""

    task_schema = TaskSchema()
    task_result_schema = TaskIncludedSchema()

    @only_for(["user", "node", "container"])
    @swag_from(str(Path(r"swagger/get_task_with_id.yaml")), endpoint='task_with_id')
    @swag_from(str(Path(r"swagger/get_task_without_id.yaml")), endpoint='task_without_id')
    def get(self, id=None):
        task = db.Task.get(id)
        if not task:
            return {"msg": "task id={} is not found"}, HTTPStatus.NOT_FOUND

        s = self.task_result_schema if request.args.get('include') == 'results' else self.task_schema
        return s.dump(task, many=not id).data, HTTPStatus.OK

    @only_for(["user", "container"])
    @swag_from(str(Path(r"swagger/post_task_without_id.yaml")), endpoint='task_without_id')
    def post(self):
        """Create a new Task."""
        # log_full_request(request, log)

        if not request.is_json:
            return {"msg": "No JSON body found..."}, HTTPStatus.BAD_REQUEST

        data = request.get_json()

        collaboration_id = data.get('collaboration_id')
        collaboration = db.Collaboration.get(collaboration_id)

        if not collaboration:
            return {"msg": f"collaboration id={collaboration_id} not found"},\
            HTTPStatus.NOT_FOUND

        organizations_json_list = data.get('organizations')
        org_ids = [org.get("id") for org in organizations_json_list]
        db_ids = collaboration.get_organization_ids()

        # TODO what happens if user's organization does not have a node that
        # is part of a the collaboration
        # if the 'master'-flag is set to true the (master) task is executed on
        # a node in the collaboration from the organization to which the user
        # belongs. If also organization_ids are supplied, then these are ignored.
        if data.get("master", False) and g.user:
            org_ids = [g.user.organization_id]

        # Check that all organization ids are within the collaboration
        # if not all([org_id in db_ids for org_id in org_ids]):
        if not set(org_ids).issubset(db_ids):
            return {"msg": (
                f"At least one of the supplied organizations in not within "
                f"the collaboration"
            )}, HTTPStatus.BAD_REQUEST

        if g.user:
            initiator = g.user.organization
        elif g.container:
            initiator = db.Node.get(g.container["node_id"]).organization
        else:
            # FIXME: Who then? Shouldn't this raise an exception?
            initiator = None

        # Create the new task in the database
        task = db.Task(
            collaboration=collaboration,
            name=data.get('name', ''),
            description=data.get('description', ''),
            image=data.get('image', ''),
            database=data.get('database', ''),
            initiator=initiator
        )

        if g.user:
            if not self.__verify_user_permissions(g.user, task):
                return {"msg": "You lack the permission to do that!"}, HTTPStatus.UNAUTHORIZED

            # Users can only create top-level -tasks (they will not
            # have sub-tasks). Therefore, always create a new run_id.
            # FIXME: I can see no reason why users wouldn't be allowed to create
            #   subtasks? For iterative processes this would actually make a lot
            #   of sense.
            task.run_id = task.next_run_id()
            log.debug(f"New run_id {task.run_id}")

        elif g.container:
            # verify that the container has permissions to create the task
            if not self.__verify_container_permissions(g.container, task):
                return {"msg": "Container-token is not valid"}, HTTPStatus.UNAUTHORIZED

            # Tasks created by containers are always sub-tasks
            task.parent_task_id = g.container["task_id"]
            task.run_id = db.Task.get(g.container["task_id"]).run_id
            log.debug(f"Sub task from parent_task_id={task.parent_task_id}")

        # permissions ok, save to DB
        task.save()

        organizations = [db.Organization.get(id_) for id_ in org_ids]
        log.debug(f"Assigning task to {len(organizations)} nodes.")

        for organization in organizations:
            log.debug(f"Assigning task to '{organization.name}'.")

            # TODO make this cleaner...
            # get organization specific (encrypted) input
            input_ = [org.get("input") for org in organizations_json_list \
                if org.get("id")==organization.id].pop()

            if isinstance(input_, dict):
                input_ = json.dumps(input_).encode(STRING_ENCODING)

            result = db.Result(
                task=task,
                organization=organization,
                input=input_,
            )
            result.save()

        # notify nodes a new task available (only to online nodes)
        socketio.emit(
            'new_task',
            task.id,
            room=f'collaboration_{task.collaboration_id}',
            namespace='/tasks'
        )

        log.info(f"New task created for collaboration '{task.collaboration.name}'")

        if g.type == 'user':
            log.debug(f" created by: '{g.user.username}'")
        else:
            log.debug((f" created by container on node_id={g.container['node_id']}"
                       f" for (master) task_id={g.container['task_id']}"))

        log.debug(f" url: '{url_for('task_with_id', id=task.id)}'")
        log.debug(f" name: '{task.name}'")
        log.debug(f" image: '{task.image}'")

        return self.task_schema.dump(task, many=False)

    def handle_master_task(self):
        """Handle creation of a master task."""
        pass

    def handle_regular_task(self):
        """Handle creation of a regular task."""
        pass

    @staticmethod
    def __verify_user_permissions(user, task: db.Task):
        """Verify that user is permitted to create task"""

        # I have the power!
        if "root" in g.user.roles:
            return True

        # user is within organization that is part of the collaboration
        return g.user.organization_id in task.collaboration.get_organization_ids()

    @staticmethod
    def __verify_container_permissions(container, task):
        """Validates that the container is allowed to create the task."""

        # check that the image is allowed
        # if container["image"] != task.image:
        if not task.image.endswith(container["image"]):
            log.warning((f"Container from node={container['node_id']} "
                f"attempts to post a task using illegal image!?"))
            log.warning(f"  task image: {task.image}")
            log.warning(f"  container image: {container['image']}")
            return False

        # check master task is not completed yet
        if db.Task.get(container["task_id"]).complete:
            log.warning((f"Container from node={container['node_id']} attempts "
                f"to start sub-task for a completed task={container['task_id']}"))
            return False

        # check that node id is indeed part of the collaboration
        if not container["collaboration_id"] == task.collaboration.id:
            log.warning((f"Container attempts to create a task outside "
                f"collaboration_id={container['collaboration_id']} in "
                f"collaboration_id={task.collaboration_id}!"))
            return False

        return True

    @only_for(['user'])
    @swag_from(str(Path(r"swagger/delete_task_with_id.yaml")), endpoint='task_with_id')
    def delete(self, id):
        """Deletes a task"""
        # TODO we might want to delete the corresponding results also?

        task = db.Task.get(id)
        if not task:
            return {"msg": "task id={} not found".format(id)}, HTTPStatus.NOT_FOUND

        task.delete()
        return {"msg": "task id={} successfully deleted".format(id)}, HTTPStatus.OK

class TaskResult(Resource):
    """Resource for /api/task/<int:id>/result"""

    task_result_schema = TaskResultSchema()

    @only_for(['user', 'container'])
    @swag_from(str(Path(r"swagger/get_task_result.yaml")), endpoint='task_result')
    def get(self, id):
        """Return results for task."""
        task = db.Task.get(id)
        if not task:
            return {"msg": "task id={} not found".format(id)}, HTTPStatus.NOT_FOUND

        return self.task_result_schema.dump(task.results, many=True).data, HTTPStatus.OK


import torch
import pytorch_lightning as pl

# A LightningModule ORGANIZES the PyTorch code into the following modules:
# 1. Computations (init)
# 2. Training loop (training_step)
# 3. Validation loop (validation_step)
# 4. Test loop (test_step)
# 5. Optimizers (configure_optimizers)

##############################################################################
model = FlashModel()
trainer = Trainer()
trainer.fit(model)

### NO .cuda() or .to() calls in PL #######################################
# DO NOT do this with PL
x = torch.Tensor(2, 3)
x = x.cuda()
x.to(device)

# INSTEAD DO THIS
x = x               # leave it alone!

# or to init a new tensor fo this ->
new_x = torch.tensor(2, 3)
new_x = new_x.as_type(x)

# NO SAMPLERS for distributed
# DON'T DO THIS
data = MNIST(...)
sampler = DistributedSampler(data)
DataLoader(data, sampler=sampler)

# DO THIS
data = MNIST(...)
DataLoader(data)

# A LightningModule is a torch.nn.Module with added functionality. Use it as such
model = FlashModel.load_from_checkpoint(PATH)
model.freeze()
out = model(x)

###########################################################################################


import click

from scaraplate.rollup import rollup as _rollup

@click.group()
@click.version_option()
def main():
    pass

@main.command()
@click.argument("template_dir", type=click.Path(exists=True, file_okay=False))
@click.argument("target_project_dir", type=click.Path(file_okay=False))
@click.option(
    "--no-input",
    is_flag=True,
    help=(
        "Do not prompt for missing data. Cookiecutter will use "
        "the defaults provided by the `cookiecutter.json` "
        "in the TEMPLATE_DIR."
    ),
)
def rollup(template_dir: str, target_project_dir: str, no_input: bool) -> None:
    """Rollup (apply) the cookiecutter template.

    The template from TEMPLATE_DIR is applied on top of TARGET_PROJECT_DIR.

    TEMPLATE_DIR must be a local path to the location of a git repo with
    the cookiecutter template to apply. It must contain `scaraplate.yaml`
    file in the root. The TEMPLATE_DIR must be in a git repo, because
    some strategies require the commit hash at HEAD and the git remote URL.

    TARGET_PROJECT_DIR should point to the directory where the template
    should be applied. Might not exist -- it will be created then.
    For monorepos this should point to the subproject inside the monorepo.
    """
    _rollup(
        template_dir=template_dir,
        target_project_dir=target_project_dir,
        no_input=no_input,
    )

if __name__ == "__main__":
    main(prog_name="scaraplate")  # pylint: disable=unexpected-keyword-arg


# same code as ModelA.py, writes a csv with the paths used and the number of trucks on each path
from graph_parameter import graph_parameter
import gurobipy
import re
import csv
from ast import literal_eval

# data
graphparameter = graph_parameter()

commodities = graphparameter[0]
nodes = graphparameter[1]
arcs = graphparameter[2]
origin = graphparameter[3]
destination = graphparameter[4]
distance = graphparameter[5]

quantity = {}
for j in commodities:
	quantity[j] = float(commodities[j])

# initialize model
m = gurobipy.Model("m")

# path
x = {}
for a in arcs:
	x[a] = {}
	for k in commodities:
		x[a][k] = m.addVar(name = str((str(a),k)),vtype = gurobipy.GRB.BINARY) # continuous and binary

# trucks
n = {}
for a in arcs:
	n[a] = m.addVar(name = str((str(a))),vtype = gurobipy.GRB.INTEGER) # integer for extra credit problem

# objective
objective = gurobipy.quicksum(distance[a] * n[a] for a in arcs)
m.setObjective(objective, gurobipy.GRB.MINIMIZE)

# source, sink, otherwise
for k in commodities:
	for node in nodes:
		if node == origin[k]:
			m.addConstr(gurobipy.quicksum(x[a][k] for a in arcs.select(node, "*")) - gurobipy.quicksum(x[a][k] for a in arcs.select("*", node)) == 1) # source
		elif node == destination[k]:
			m.addConstr(gurobipy.quicksum(x[a][k] for a in arcs.select(node, "*")) - gurobipy.quicksum(x[a][k] for a in arcs.select("*", node)) == -1) # sink
		else:
			m.addConstr(gurobipy.quicksum(x[a][k] for a in arcs.select(node, "*")) - gurobipy.quicksum(x[a][k] for a in arcs.select("*", node)) == 0) # otherwise

# quantity
for arc in arcs:
	m.addConstr(n[arc] - gurobipy.quicksum(quantity[k] * x[arc][k] for k in commodities) >= 0)

m.update()
m.optimize()

print('Runtime: ' + str(m.Runtime))

# getting the list of arcs and trucks
# finding the paths used and number of trucks
arcTruck = []
for a in arcs:
	if round(n[a].x) > 0:
		arcTruck.append((a, int(round(n[a].x))))
# print(arcTruck)

# writing list to csv to visualize in viz.py
with open("output_arcs.csv", 'w') as file:
	writer = csv.writer(file)
	for path in arcTruck:
		writer.writerow(path)


from reportlab.graphics.shapes import Drawing
from reportlab.graphics.charts.barcharts import VerticalBarChart
from reportlab.graphics.charts.linecharts import HorizontalLineChart
from reportlab.graphics.charts.lineplots import ScatterPlot
from reportlab.graphics.charts.piecharts import Pie
from reportlab.graphics.charts.textlabels import Label
from reportlab.graphics.charts.legends import Legend
import math
from reportlab.graphics.charts.axes import XCategoryAxis, YValueAxis
from reportlab.platypus.doctemplate import SimpleDocTemplate
from reportlab.platypus import Paragraph, Table, Spacer, TableStyle
from reportlab.lib.units import inch
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
from reportlab.lib import colors
from reportlab.platypus import Table
from reportlab.lib.pagesizes import letter, landscape
from genericfunctions import *

def set_chart_size(size):

    if size == 'S':
        drawsizew, drawsizeh = 180, 180
        height = 125
        width = 170
        title_y_offset = 175
        title_x_offset = 102
        delta_y = 20
        chart_font_size = 7
    if size == 'SW':
        drawsizew, drawsizeh = 650, 180
        height = 125
        width = 625
        title_y_offset = 175
        title_x_offset = 338
        delta_y = 25
        chart_font_size = 8
    elif size == 'M':
        drawsizew, drawsizeh = 250, 250
        height = 188
        width = 225
        title_y_offset = 220
        title_x_offset = 138
        delta_y = 25
        chart_font_size = 8
    elif size == 'L':
        drawsizew, drawsizeh = 650, 190
        height = 175
        width = 625
        title_y_offset = 185
        title_x_offset = 338
        delta_y = 25
        chart_font_size = 9
    elif size == 'SB':
        drawsizew, drawsizeh = 180, 220
        height = 125
        width = 210
        title_y_offset = 175
        title_x_offset = 125
        delta_y = 25
        chart_font_size = 7

    return {'drawsizew':drawsizew, 'drawsizeh':drawsizeh, 'height':height, 'width':width,
            'title_y_offset':title_y_offset, 'title_x_offset':title_x_offset, 'delta_y':delta_y,
            'chart_font_size':chart_font_size}

def set_chart_labels(label):

    labeldict = {'Collateralized Bonds': 'Collateralized',
                 'Corporate Bonds': 'Corporate',
                 'Sovereign/Agcy Bonds': 'Govt/Agcy',
                 'Municipal Bonds': 'Municipal',
                 'CO': 'Collateralized',
                 'CR': 'Corporate',
                 'MU': 'Municipal',
                 'SG': 'Govt/Agcy',
                 'TG': 'Govt/Agcy'}

    if label in labeldict:
        return labeldict[str(label)]
    else:
        return label

def set_color(label):

    colordict = {'MBS': colors.HexColor('#2E323C'),
                 'CO': colors.HexColor('#2E323C'),
                 'Collateralized': colors.HexColor('#2E323C'),
                 'Collateralized Bonds': colors.HexColor('#2E323C'),
                 'TG': colors.HexColor('#dadada'),
                 'Govt/Agcy': colors.HexColor('#dadada'),
                 'Sovereign/Agcy': colors.HexColor('#dadada'),
                 'Sovereign/Agcy Bonds': colors.HexColor('#dadada'),
                 'MU': colors.HexColor('#79868D'),
                 'Municipal': colors.HexColor('#79868D'),
                 'Municipal Bonds': colors.HexColor('#79868D'),
                 'CR': colors.HexColor('#6D9DB3'),
                 'Corporate': colors.HexColor('#6D9DB3'),
                 'Corporate Bonds': colors.HexColor('#6D9DB3'),
                 'Cash': colors.HexColor('#867F7F'),
                 'Derivative': colors.HexColor('#191C27'),
                 '10yr': colors.HexColor('#d62728'),
                 '15yr': colors.HexColor('#191C27'),
                 '20yr': colors.HexColor('#dadada'),
                 '30yr': colors.HexColor('#7A6F67'),
                 'Other': colors.HexColor('#6D9DB3'),
                 'Other2': colors.HexColor('#7AA5AD')
                 }

    if label in colordict:
        return colordict[str(label)]
    else:
        return colordict['MBS']

class NiceScale:
    def __init__(self, minv, maxv):
        self.maxTicks = 6
        self.tickSpacing = 0
        self.lst = 10
        self.niceMin = 0
        self.niceMax = 0
        self.minPoint = minv
        self.maxPoint = maxv
        self.calculate()

    def calculate(self):
        self.lst = self.niceNum(self.maxPoint - self.minPoint, False)
        self.tickSpacing = self.niceNum(self.lst / (self.maxTicks - 1), True)
        self.niceMin = math.floor(self.minPoint / self.tickSpacing) * self.tickSpacing
        self.niceMax = math.ceil(self.maxPoint / self.tickSpacing) * self.tickSpacing

    def niceNum(self, lst, rround):
        self.lst = lst
        exponent = 0  # exponent of range */
        fraction = 0  # fractional part of range */
        niceFraction = 0  # nice, rounded fraction */

        if self.lst == 0:
            exponent = 1
        else:
            exponent = math.floor(math.log10(self.lst))
        fraction = self.lst / math.pow(10, exponent)

        if self.lst:
            if fraction < 1.5:
                niceFraction = 1
            elif fraction < 3:
                niceFraction = 2
            elif fraction < 7:
                niceFraction = 5;
            else:
                niceFraction = 10;
        else:
            if fraction <= 1:
                niceFraction = 1
            elif fraction <= 2:
                niceFraction = 2
            elif fraction <= 5:
                niceFraction = 5
            else:
                niceFraction = 10

        return niceFraction * math.pow(10, exponent)

    def setMinMaxPoints(self, minPoint, maxPoint):
        self.minPoint = minPoint
        self.maxPoint = maxPoint
        self.calculate()

    def setMaxTicks(self, maxTicks):
        self.maxTicks = maxTicks
        self.calculate()

def vbar_one_series(size, data, xlabels, chart_title, xaxis_text, axismin, axismax, spacing):

    drawing = Drawing(set_chart_size(size)['drawsizew'], set_chart_size(size)['drawsizeh'])

    bc = VerticalBarChart()
    bc.x = 25
    bc.y = set_chart_size(size)['delta_y']
    bc.height = set_chart_size(size)['height']
    bc.width = set_chart_size(size)['width']
    bc.data = [data]
    bc.valueAxis.valueMin = axismin
    bc.valueAxis.valueMax = axismax
    bc.valueAxis.valueStep = spacing

    bc.valueAxis.labels.fontName = 'Helvetica'
    bc.valueAxis.labels.fontSize = set_chart_size(size)['chart_font_size']
    bc.valueAxis.labelTextFormat = '%0.1f'

    fixed_xlabels = []
    for l in xlabels:
        fixed_xlabels.append(set_chart_labels(l))

    for i in range(len(fixed_xlabels)):
        bc.bars[(0,i)].fillColor = set_color(fixed_xlabels[i])
        bc.bars[(0,i)].strokeColor = set_color(fixed_xlabels[i])

    bc.categoryAxis.labels.boxAnchor = 'c'
    bc.categoryAxis.labelAxisMode = 'low'
    bc.categoryAxis.labels.fontName = 'Helvetica'
    bc.categoryAxis.labels.fontSize = set_chart_size(size)['chart_font_size']
    bc.categoryAxis.tickDown = 0
    bc.categoryAxis.labels.dx = 0
    bc.categoryAxis.labels.dy = -13
    bc.categoryAxis.labels.angle = 0

    bc.labelTextFormat = '%.1f'

    bc.categoryAxis.categoryNames = fixed_xlabels

    bc.barLabels.nudge = 5
    bc.barLabelFormat = '%0.1f'
    bc.barLabels.dx = 0
    bc.barLabels.dy = 0
    bc.barLabels.fontName = 'Helvetica'
    bc.barLabels.fontSize = 7

    xlabel = Label()
    xlabel.setText(xaxis_text)
    xlabel.fontSize = set_chart_size(size)['chart_font_size']
    xlabel.fontName = 'Helvetica'
    xlabel.dx = set_chart_size(size)['title_x_offset']
    xlabel.dy = 3

    title = Label()
    title.setText(chart_title)
    title.fontSize = set_chart_size(size)['chart_font_size']
    title.fontName = 'Helvetica'
    title.dx = set_chart_size(size)['title_x_offset']
    title.dy = set_chart_size(size)['title_y_offset']

    drawing.add(bc)
    drawing.add(xlabel)
    drawing.add(title)

    return drawing

def pie_chart(chart_size, data, labels, chart_title):
    pc = Pie()

    if chart_size == 'S':
        piedraw = Drawing(180, 180)
        pc.x = 35
        pc.y = 30
        pc.height = 115
        pc.width = 115
        pie_title_x_offset = 90
        pie_title_y_offset = 175
        pie_font_size = 7
        pie_label_offset = 1.25
    elif chart_size == 'M':
        piedraw = Drawing(250, 250)
        pc.x = 20
        pc.y = 15
        pc.height = 200
        pc.width = 200
        pie_title_x_offset = 125
        pie_title_y_offset = 245
        pie_font_size = 8
        pie_label_offset = 1.15

    fixed_labels = []
    for l in labels:
        fixed_labels.append(set_chart_labels(l))

    pc.data = data
    data_labels = fixed_labels

    for i in range(len(data_labels)):
        pc.slices[i].fillColor = set_color(data_labels[i])

    pc.labels = []
    for i in range(len(pc.data)):
        pc.labels.append(data_labels[i] + ':' + str('{:.0%}'.format(float(pc.data[i])/sum(pc.data))))

    pc.slices.strokeWidth = 0.5
    pc.slices.fontName = 'Helvetica'
    pc.slices.fontSize = pie_font_size
    pc.sideLabels = 1

    title = Label()
    title.setText(chart_title)
    title.fontSize = pie_font_size
    title.fontName = 'Helvetica'
    title.dx = pie_title_x_offset
    title.dy = pie_title_y_offset

    piedraw.add(pc)
    piedraw.add(title)

    return piedraw

def single_line(data, labels):
    linedraw = Drawing(180, 180)

    lc = HorizontalLineChart()

    lc.x = 20
    lc.y = 50
    lc.height = 100
    lc.width = 175
    lc.data = [data]
    lc.joinedLines = 1

    lc.categoryAxis.categoryNames = labels
    lc.categoryAxis.labels.boxAnchor = 'c'
    lc.categoryAxis.labels.fontName = 'Helvetica'
    lc.categoryAxis.labels.fontSize = 8

    lc.valueAxis.labels.fontName = 'Helvetica'
    lc.valueAxis.labels.fontSize = 8

    lc.valueAxis.valueMin = min(lc.data[0] ) * 1.10
    lc.valueAxis.valueMax = max(lc.data[0]) * 1.10
    lc.valueAxis.valueStep = 1
    lc.valueAxis.labelTextFormat = '%0.1f'

    lc.lines[0].strokeWidth = 1
    lc.lines[0].strokeColor = colors.HexColor('#000035')
    linedraw.add(lc)

    return linedraw

def stacked_bar(data, xlabels, series_names, chart_title, axismin, axismax, spacing):

    drawsizew, drawsizeh = 650, 250
    drawing = Drawing(drawsizew, drawsizeh)
    name_pairs = []

    bc = VerticalBarChart()
    bc.categoryAxis.style = "stacked"
    bc.x = 30
    bc.y = 40
    bc.height = 188
    bc.width = 625

    bc.data = data
    bc.categoryAxis.categoryNames = xlabels
#    bc.valueAxis.labelTextFormat = '%0.1f'
    bc.valueAxis.labels.fontName = 'Helvetica'
    bc.valueAxis.labels.fontSize = 7

    for i in range(len(series_names)):
        bc.bars[i].fillColor = set_color(series_names[i])
        bc.bars[i].strokeColor = set_color(series_names[i])
        name_pairs.append((bc.bars[i].fillColor, series_names[i]))

    bc.categoryAxis.labels.fontName = 'Helvetica'
    bc.categoryAxis.labels.fontSize = 7
    bc.categoryAxis.tickDown = 0
    bc.categoryAxis.labels.dx = 0
    bc.categoryAxis.labels.dy = -18
    bc.categoryAxis.labels.angle = 90
    bc.categoryAxis.labels.boxAnchor = 'c'
    bc.valueAxis.valueMin = axismin
    bc.valueAxis.valueMax = axismax
    bc.valueAxis.valueStep = spacing

    title = Label()
    title.setText(chart_title)
    title.fontSize = 7
    title.fontName = 'Helvetica'
    title.dx = 338
    title.dy = 220

    legend = Legend()
    legend.fontName = 'Helvetica'
    legend.fontSize = 7
    legend.colorNamePairs = name_pairs
    legend.columnMaximum = 1
    legend.x = 185
#    legend.y = 100
    legend.dy = 5
    legend.dx = 5
#    legend.alignment = 'right'

    drawing.add(bc)
    drawing.add(title)
    drawing.add(legend)

    return drawing

def quartile_bar_one_asset(df, dataseries, chart_title):

    drawsizew, drawsizeh = 180, 220
    drawing = Drawing(drawsizew, drawsizeh)

    if dataseries == 1:
        sbarxlabels = clean_quartile_categories(df.columns[:4])
        sbardata = [df.iloc[:, 0].tolist(), df.iloc[:, 1].tolist(),
                    df.iloc[:, 2].tolist(), df.iloc[:, 3].tolist()]
    else:
        sbarxlabels = clean_quartile_categories(df.columns[4:])
        sbardata = [df.iloc[:, 4].tolist(), df.iloc[:, 5].tolist(),
                    df.iloc[:, 6].tolist(), df.iloc[:, 7].tolist()]

    pct2flt = quartile_pct_to_float(sbardata)
    bc = VerticalBarChart()

    bc.x = 20
    bc.y = 30
    bc.height = 125
    bc.width = 210

    graphdata = [i[0] for i in pct2flt]

    bc.data = [graphdata]
    bc.categoryAxis.categoryNames = sbarxlabels
    bc.valueAxis.labels.fontName = 'Helvetica'
    bc.valueAxis.labels.fontSize = 7
    bc.valueAxis.valueMin = 0

    bc.categoryAxis.labels.fontName = 'Helvetica'
    bc.categoryAxis.labels.fontSize = 7
    bc.categoryAxis.tickDown = 0
    bc.categoryAxis.labels.dx = 0
    bc.categoryAxis.labels.dy = -18
    bc.categoryAxis.labels.angle = 0
    bc.categoryAxis.labels.boxAnchor = 'c'

    bc.barLabels.nudge = 5
    bc.barLabelFormat = '%0.1f'
    bc.barLabels.dx = 0
    bc.barLabels.dy = 0
    bc.barLabels.fontName = 'Helvetica'
    bc.barLabels.fontSize = 7

    for i in range(len(sbarxlabels)):
        bc.bars[(0,i)].fillColor = set_color(colors.HexColor('#2E323C'))
        bc.bars[(0,i)].strokeColor = set_color(colors.HexColor('#2E323C'))

    title = Label()
    title.setText(chart_title)
    title.fontSize = 7
    title.fontName = 'Helvetica'
    title.dx = 125
    title.dy = 175

    drawing.add(bc)
    drawing.add(title)

    return drawing

def generic_bar(**kwargs):

    size = kwargs['size']
    graphdata = kwargs['graphdata']
    xlabels = kwargs['xlabels']
    chart_title = kwargs['chart_title']

    drawing = Drawing(set_chart_size(size)['drawsizew'], set_chart_size(size)['drawsizeh'])
    bc = VerticalBarChart()

    bc.x = 20
    bc.y = 30
    bc.height = set_chart_size(size)['height']
    bc.width = set_chart_size(size)['width']

    bc.categoryAxis.categoryNames = xlabels
    bc.valueAxis.labels.fontName = 'Helvetica'
    bc.valueAxis.labels.fontSize = set_chart_size(size)['chart_font_size']
    bc.valueAxis.labelTextFormat = '%.1f'
    if 'sectors' in kwargs:
        bc.data = graphdata
        sectors = kwargs['sectors']
        name_pairs = []
        bc.categoryAxis.style = "stacked"
        for i in range(len(sectors)):
            bc.bars[i].fillColor = set_color(sectors[i])
            bc.bars[i].strokeColor = set_color(sectors[i])
            name_pairs.append((bc.bars[i].fillColor, sectors[i]))

        legend = Legend()
        legend.fontName = 'Helvetica'
        legend.fontSize = set_chart_size(size)['chart_font_size']
        legend.colorNamePairs = name_pairs
        legend.columnMaximum = 1
        legend.x = 10
        #    legend.y = 100
        legend.dy = 5
        legend.dx = 5
        legend.alignment = 'right'
        drawing.add(legend)

    else:
        bc.data = [graphdata]
        datarange = NiceScale(min(graphdata), max(graphdata))

        bc.valueAxis.valueMin = datarange.niceMin
        bc.valueAxis.valueMax = datarange.niceMax
        bc.valueAxis.valueStep = datarange.tickSpacing

        for i in range(len(xlabels)):
            bc.bars[(0, i)].fillColor = set_color(xlabels[i])
            bc.bars[(0, i)].strokeColor = set_color(xlabels[i])

        bc.barLabels.nudge = 5
        bc.barLabelFormat = '%0.1f'
        bc.barLabels.dx = 0
        bc.barLabels.dy = 0
        bc.barLabels.fontName = 'Helvetica'
        bc.barLabels.fontSize = 7

    bc.categoryAxis.labels.fontName = 'Helvetica'
    bc.categoryAxis.labels.fontSize = set_chart_size(size)['chart_font_size']
    bc.categoryAxis.tickDown = 0
    bc.categoryAxis.labels.dx = 0
    bc.categoryAxis.labels.dy = -18
    bc.categoryAxis.labels.angle = 0
    bc.categoryAxis.labels.boxAnchor = 'c'

    title = Label()
    title.setText(chart_title)
    title.fontSize = set_chart_size(size)['chart_font_size']
    title.fontName = 'Helvetica'
    title.dx = set_chart_size(size)['title_x_offset']
    title.dy = set_chart_size(size)['title_y_offset']

    drawing.add(bc)
    drawing.add(title)

    return drawing

def bubble_chart(**kwargs):

    size = kwargs['size']
    graphdata = kwargs['graphdata']
    xylabels = kwargs['xylabels']
    chart_title = kwargs['chart_title']
    sectors = kwargs['sectors']
    sector_pct = kwargs['sector_pct']

    spdraw = Drawing(set_chart_size(size)['drawsizew'], set_chart_size(size)['drawsizeh'])
    sp = ScatterPlot()

    sp.width = set_chart_size(size)['width']
    sp.height = set_chart_size(size)['height']
    sp.x = 20
    sp.y = 30

    sp.data = graphdata

    sp.lineLabels.fontName = 'Helvetica'

    sp.xValueAxis.labels.fontName = 'Helvetica'
    sp.xValueAxis.labelTextFormat = '%0.1f'
    sp.xValueAxis.labels.fontSize = set_chart_size(size)['chart_font_size']
    sp.xValueAxis.avoidBoundFrac = 1

    sp.xValueAxis.visibleGrid = 1
    sp.yValueAxis.labels.fontName = 'Helvetica'
    sp.yValueAxis.labels.fontSize = set_chart_size(size)['chart_font_size']
    sp.yValueAxis.visibleGrid = 1

    title = Label()
    title.fontName = 'Helvetica'
    title.fontSize = set_chart_size(size)['chart_font_size']
    title.dx = set_chart_size(size)['title_x_offset']
    title.dy = set_chart_size(size)['title_y_offset'] + 20
    title._text = chart_title
    title.textAnchor = 'middle'

    name_pairs = []
    for i in range(len(sectors)):
        sp.lines[i].symbol.kind = 'Circle'
        sp.lines[i].symbol.size = 100 * 2 * math.sqrt(sector_pct[sectors[i]] / math.pi)
        sp.lines[i].strokeColor = set_color(sectors[i])
        desc_string = ': (MktVal: ' + '{:.1%}'.format(sector_pct[sectors[i]]) +\
                      ' Yield: ' + '{:.1%}'.format(graphdata[i][0][1] / 100) +\
                      ' Total Return: ' + '{:.1%}'.format(graphdata[i][0][0] / 100) + ')'
        name_pairs.append((sp.lines[i].strokeColor, set_chart_labels(sectors[i]) + desc_string))

    legend = Legend()
    legend.colorNamePairs = name_pairs
    if len(sectors) > 4:
        legend.columnMaximum = 3
    else:
        legend.columnMaximum = 2
    legend.fontName = 'Helvetica'
    legend.fontSize = set_chart_size(size)['chart_font_size']
    legend.x = 20
    legend.y = -10
    # legend.dxTextSpace = 5
    legend.dy = 10
    legend.dx = 10
    legend.alignment = 'right'

    sp.lineLabelFormat = None

    sp.xLabel = xylabels[0]
    sp.y = 30
    sp.yLabel = xylabels[1]
    sp.yValueAxis.labelTextFormat = '%0.1f'
    # sp.yValueAxis.forceZero = 1
    # sp.xValueAxis.forceZero = 1

    spdraw.add(sp)
    spdraw.add(title)
    spdraw.add(legend)

    return spdraw

def make_sector_detail_page(df, portsum, pagetitle, stratvar, chart_title):

    portfolio_matrix_table_title = underlined_title(pagetitle)
    portfolio_matrix = mktval_detail_table(df, portsum, stratvar)

    portfolio_distrib = df.groupby([stratvar])['BaseMarketValue'].sum() / portsum[1]
    portfolio_distrib.dropna(inplace=True)
    portfolio_distrib = portfolio_distrib[portfolio_distrib.values != 0]
    summary_table = mktval_by_duration_summary_table(portfolio_distrib, 'Total Portfolio')
    sector_summary_table = sector_byvar_table(df, portsum, stratvar)

    graph_data = df.groupby([stratvar, 'clean_asset_code'])['BaseMarketValue'].sum() * 100 / portsum[1]
    finl_graph = graph_data.unstack(0, fill_value=0)

    stacked_barcht = generic_bar(size='SW', graphdata=finl_graph.values,
                                 xlabels=finl_graph.columns.astype(str).tolist(), sectors=finl_graph.index,
                                 chart_title=chart_title)

    return portfolio_matrix_table_title, summary_table, sector_summary_table, portfolio_matrix, stacked_barcht


import argparse

import numpy as np
import tensorflow as tf
import tensorflow_hub as hub
import tf_sentencepiece

def main(args):
    # The 16-language multilingual module is the default but feel free
    # to pick others from the list and compare the results.
    # module_url = "https://tfhub.dev/google/universal-sentence-encoder-multilingual/1"
    # export_path = "servables/universal-sentence-encoder-multilingual/00000001"
    module_url = args.module_url
    export_path = args.export_path

    # Set up graph.
    g = tf.Graph()
    with g.as_default():
        text_input = tf.compat.v1.placeholder(dtype=tf.string, shape=[None])
        embed = hub.Module(module_url)
        embeddings = embed(text_input)
        init_op = tf.group([tf.compat.v1.global_variables_initializer(), tf.compat.v1.tables_initializer()])

    g.finalize()

    # Initialize session.
    session = tf.compat.v1.Session(graph=g)
    session.run(init_op)

    print("Exporting trained model to", export_path)
    # Export model
    # tf.compat.v1.saved_model.simple_save(session,
    #                                      export_path,
    #                                      inputs={"text": text_input},
    #                                      outputs={"embeddings": embeddings},
    #                                      legacy_init_op=tf.compat.v1.tables_initializer())

    # Export model
    builder = tf.compat.v1.saved_model.builder.SavedModelBuilder(export_path)

    # Build the signature_def_map.
    tensor_info_text = tf.compat.v1.saved_model.utils.build_tensor_info(text_input)
    tensor_info_encoded = tf.compat.v1.saved_model.utils.build_tensor_info(embeddings)

    prediction_signature = (
        tf.compat.v1.saved_model.signature_def_utils.build_signature_def(
            inputs={
                "text": tensor_info_text
            },
            outputs={
                "embeddings": tensor_info_encoded
            },
            method_name=tf.compat.v1.saved_model.signature_constants.PREDICT_METHOD_NAME))

    builder.add_meta_graph_and_variables(
        session,
        tags=[tf.compat.v1.saved_model.tag_constants.SERVING],
        signature_def_map={
            tf.compat.v1.saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: prediction_signature,
        },
        main_op=tf.compat.v1.tables_initializer(),
        strip_default_attrs=True)

    builder.save()

    # Some texts of different lengths.
    english_sentences = ["dog", "Puppies are nice.", "I enjoy taking long walks along the beach with my dog."]
    italian_sentences = ["cane", "I cuccioli sono carini.", "Mi piace fare lunghe passeggiate lungo la spiaggia con il mio cane."]
    japanese_sentences = ["犬", "子犬はいいです", "私は犬と一緒にビーチを散歩するのが好きです"]

    # Compute embeddings.
    en_result = session.run(embeddings, feed_dict={text_input: english_sentences})
    it_result = session.run(embeddings, feed_dict={text_input: italian_sentences})
    ja_result = session.run(embeddings, feed_dict={text_input: japanese_sentences})

    print(en_result.shape)

    # Compute similarity matrix. Higher score indicates greater similarity.
    similarity_matrix_it = np.inner(en_result, it_result)
    similarity_matrix_ja = np.inner(en_result, ja_result)
    print(similarity_matrix_it)
    print(similarity_matrix_ja)

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--module_url",
        type=str,
        help="TensorFlow Hub module url")
    parser.add_argument(
        "--export_path",
        type=str,
        help="Exported model save path")

    args = parser.parse_args()
    main(args)


#!/usr/bin/env python3
# encoding: utf-8
"""
pysdd-cli
~~~~~~~~~

PySDD command line interface.

:author: Wannes Meert, Arthur Choi
:copyright: Copyright 2019 KU Leuven and Regents of the University of California.
:license: Apache License, Version 2.0, see LICENSE for details.
"""
from pathlib import Path
import sys
import time
import argparse
import logging
from pysdd.sdd import SddManager, Vtree, Fnf, CompilerOptions

logger = logging.getLogger(__name__)

def main(argv=None):
    options, args = getopt(argv)

    if options.cnf_filename is not None:
        print("creating manager...")
        sdd, _ = SddManager.from_cnf_file(bytes(options.cnf_filename))

        root = sdd.root

        # Model Counting
        wmc = root.wmc(log_mode=False)
        wmc.propagate()

        weights = read_weights(bytes(options.cnf_filename))
        print("Weights size: " + str(len(weights)))

        literals = [sdd.literal(i) for i in range(1, sdd.var_count()+1)]

        print("Number of literals: " + str(len(literals)))

        # Set weights for all literals
        for i in range(1, len(literals)+1):
            wmc.set_literal_weight(i, weights[(i-1)*2])  # Positive literal weight
            wmc.set_literal_weight(-i, weights[(i-1)*2+1])  # Negative literal weight

        w = wmc.propagate()

        print("Weighted model count: " + str(w))
        #
        # for i in range(1, sdd.var_count()+1):
        #     print(str(i) + ": " + str(wmc.literal_weight(i)))
        #     print(str(-i) + ": " + str(wmc.literal_weight(-i)))

        # print("Model count: " + str(sdd.model_count(root)))

        # for i in range(1, sdd.var_count() + 1):
        #     print(str(i-1) + ": " + str(wmc.literal_pr(i)))

        # Weighted Model Counting

        wmc.set_literal_weight(literals[29], 0)  # Positive literal weight
        # wmc.set_literal_weight(-literals[29], 0)  # Negative literal weight

        # wmc.set_literal_weight(literals[32], 0)  # Positive literal weight
        wmc.set_literal_weight(-literals[32], 0)  # Negative literal weight
        #
        # wmc.set_literal_weight(literals[40], 0)  # Positive literal weight
        wmc.set_literal_weight(-literals[40], 0)  # Negative literal weight

        # for i in range(1, sdd.var_count()+1):
        #     print(str(i) + ": " + str(wmc.literal_weight(i)))
        #     print(str(-i) + ": " + str(wmc.literal_weight(-i)))

        w = wmc.propagate()

        for i in range(1, sdd.var_count() + 1):
            print(str(i) + ": " + str(wmc.literal_pr(i)))

        print("Weighted model count: " + str(w))

        print("8: " + str(wmc.literal_pr(8)))

def read_weights(nnf_path):
    """
    Format: c weights PW_1 NW_1 ... PW_n NW_n
    :param nnf_path: Path to NNF file
    :return: list of weights
    """
    weight_str = None
    with open(nnf_path, "r") as ifile:
        for line in ifile.readlines():
            if "c weights " in line:
                weight_str = line[10:].strip()
                break
    if weight_str is None:
        return None
    weight_strs = weight_str.split(" ")
    weights = [float(w) for w in weight_strs]
    return weights

def create_wmc(node, weights):
    if weights is None:
        return None
    wmc = node.wmc(False)
    for i in range(len(weights)):
        lit = (i // 2) + 1
        if (i % 2) == 1:
            lit = -lit
        w = weights[i]
        wmc.set_literal_weight(node.manager.literal(lit), w)
    return wmc

class CustomHelpFormatter(argparse.HelpFormatter):

    def _format_text(self, text):
        text = super()._format_text(text)
        if "Copyright" in text:
            a, b = text.split("Copyright")
            text = a + "\n\n" + super()._format_text("Copyright" + b)
        return text

def create_parser():
    def bytes_path(p):
        return bytes(Path(p))

    def bytes_str(s):
        return s.encode()

    epilog = ("Weighted Model Counting is performed if the NNF file containts a line formatted as follows: "
              "\"c weights PW_1 NW_1 ... PW_n NW_n\"."
              "Copyright 2017-2019, Regents of the University of California and KU Leuven")
    parser = argparse.ArgumentParser(description='Sentential Decision Diagram, Compiler',
                                     epilog=epilog,
                                     formatter_class=CustomHelpFormatter)
    input_group = parser.add_mutually_exclusive_group()
    input_group.add_argument('-c', metavar='FILE', type=bytes_path,
                             dest='cnf_filename', help='set input CNF file')
    input_group.add_argument('-d', metavar='FILE', type=bytes_path,
                             dest='dnf_filename', help='set input DNF file')
    input_group.add_argument('-s', metavar='FILE', type=bytes_path,
                             dest='sdd_filename', help='set input SDD file')
    parser.add_argument('-v', metavar='FILE', type=bytes_path,
                        dest='vtree_filename', help='set input VTREE file')

    parser.add_argument('-W', metavar='FILE', type=bytes_path,
                        dest='output_vtree_filename', help='set output VTREE file')
    parser.add_argument('-V', metavar='FILE', type=bytes_path,
                        dest='output_vtree_dot_filename', help='set output VTREE (dot) file')
    parser.add_argument('-R', metavar='FILE', type=bytes_path,
                        dest='output_sdd_filename', help='set output SDD file')
    parser.add_argument('-S', metavar='FILE', type=bytes_path,
                        dest='output_sdd_dot_filename', help='set output SDD (dot) file')

    parser.add_argument('-m', action='store_true',
                        dest='minimize_cardinality', help='minimize the cardinality of compiled sdd')

    parser.add_argument('-t', metavar='TYPE', type=bytes_str, default='balanced',
                        choices=[b'left', b'right', b'vertical', b'balanced', b'random'],
                        dest='initial_vtree_type',
                        help='set initial vtree type (left/right/vertical/balanced/random)')

    parser.add_argument('-r', metavar='K', type=int, default=-1,
                        dest='vtree_search_mode',
                        help='if K>0: invoke vtree search every K clauses. If K=0: disable vtree search. ' +
                             'By default (no -r option), dynamic vtree search is enabled')

    parser.add_argument('-q', action='store_true',
                        dest='post_search', help='perform post-compilation vtree search')

    parser.add_argument('-p', action='store_true',
                        dest='verbose', help='verbose output')

    parser.add_argument('--log_mode', action='store_true',
                        dest='log_mode', help='weights in log')

    return parser

def getopt(argv=None):
    parser = create_parser()
    args = parser.parse_args(argv)

    if args.verbose:
        logger.setLevel(logging.INFO)
    else:
        logger.setLevel(logging.WARNING)
    logger.addHandler(logging.StreamHandler(sys.stdout))

    options = CompilerOptions(cnf_filename=args.cnf_filename,
                              dnf_filename=args.dnf_filename,
                              vtree_filename=args.vtree_filename,
                              sdd_filename=args.sdd_filename,
                              output_vtree_filename=args.output_vtree_filename,
                              output_vtree_dot_filename=args.output_vtree_dot_filename,
                              output_sdd_filename=args.output_sdd_filename,
                              output_sdd_dot_filename=args.output_sdd_dot_filename,
                              initial_vtree_type=args.initial_vtree_type,
                              minimize_cardinality=args.minimize_cardinality,
                              vtree_search_mode=args.vtree_search_mode,
                              post_search=args.post_search,
                              verbose=args.verbose)
    # print(str(options))
    return options, args


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

import torch

from mmpose.core.post_processing import transform_preds

def get_multi_stage_outputs(outputs,
                            outputs_flip,
                            num_joints,
                            with_heatmaps,
                            with_ae,
                            tag_per_joint=True,
                            flip_index=None,
                            project2image=True,
                            size_projected=None):
    """Inference the model to get multi-stage outputs (heatmaps & tags), and
    resize them to base sizes.

    Args:
        outputs (list(torch.Tensor)): Outputs of network
        outputs_flip (list(torch.Tensor)): Flip outputs of network
        num_joints (int): Number of joints
        with_heatmaps (list[bool]): Option to output
            heatmaps for different stages.
        with_ae (list[bool]): Option to output
            ae tags for different stages.
        tag_per_joint (bool): Option to use one tag map per joint.
        flip_index (list[int]): Keypoint flip index.
        project2image (bool): Option to resize to base scale.
        size_projected ([w, h]): Base size of heatmaps.

    Returns:
        tuple: A tuple containing multi-stage outputs.

        - outputs (list(torch.Tensor)): List of simple outputs and
          flip outputs.
        - heatmaps (torch.Tensor): Multi-stage heatmaps that are resized to
          the base size.
        - tags (torch.Tensor): Multi-stage tags that are resized to
          the base size.
    """

    heatmaps_avg = 0
    num_heatmaps = 0
    heatmaps = []
    tags = []

    flip_test = outputs_flip is not None

    # aggregate heatmaps from different stages
    for i, output in enumerate(outputs):
        if i != len(outputs) - 1:
            output = torch.nn.functional.interpolate(
                output,
                size=(outputs[-1].size(2), outputs[-1].size(3)),
                mode='bilinear',
                align_corners=False)

        # staring index of the associative embeddings
        offset_feat = num_joints if with_heatmaps[i] else 0

        if with_heatmaps[i]:
            heatmaps_avg += output[:, :num_joints]
            num_heatmaps += 1

        if with_ae[i]:
            tags.append(output[:, offset_feat:])

    if num_heatmaps > 0:
        heatmaps.append(heatmaps_avg / num_heatmaps)

    if flip_test and flip_index:
        # perform flip testing
        heatmaps_avg = 0
        num_heatmaps = 0

        for i, output in enumerate(outputs_flip):
            if i != len(outputs_flip) - 1:
                output = torch.nn.functional.interpolate(
                    output,
                    size=(outputs_flip[-1].size(2), outputs_flip[-1].size(3)),
                    mode='bilinear',
                    align_corners=False)
            output = torch.flip(output, [3])
            outputs.append(output)

            offset_feat = num_joints if with_heatmaps[i] else 0

            if with_heatmaps[i]:
                heatmaps_avg += output[:, :num_joints][:, flip_index, :, :]
                num_heatmaps += 1

            if with_ae[i]:
                tags.append(output[:, offset_feat:])
                if tag_per_joint:
                    tags[-1] = tags[-1][:, flip_index, :, :]

        heatmaps.append(heatmaps_avg / num_heatmaps)

    if project2image and size_projected:
        heatmaps = [
            torch.nn.functional.interpolate(
                hms,
                size=(size_projected[1], size_projected[0]),
                mode='bilinear',
                align_corners=False) for hms in heatmaps
        ]

        tags = [
            torch.nn.functional.interpolate(
                tms,
                size=(size_projected[1], size_projected[0]),
                mode='bilinear',
                align_corners=False) for tms in tags
        ]

    return outputs, heatmaps, tags

def aggregate_results(scale, aggregated_heatmaps, tags_list, heatmaps, tags,
                      test_scale_factor, project2image, flip_test):
    """Aggregate multi-scale outputs.

    Note:
        batch size: N
        keypoints num : K
        heatmap width: W
        heatmap height: H

    Args:
        scale (int): current scale
        aggregated_heatmaps (torch.Tensor | None): Aggregated heatmaps.
        tags_list (list(torch.Tensor)): Tags list of previous scale.
        heatmaps (List(torch.Tensor[NxKxWxH])): A batch of heatmaps.
        tags (List(torch.Tensor[NxKxWxH])): A batch of tag maps.
        test_scale_factor (List(int)): Multi-scale factor for testing.
        project2image (bool): Option to resize to base scale.
        flip_test (bool): Option to use flip test.

    Return:
        tuple: a tuple containing aggregated results.

        - aggregated_heatmaps (torch.Tensor): Heatmaps with multi scale.
        - tags_list (list(torch.Tensor)): Tag list of multi scale.
    """
    if scale == 1 or len(test_scale_factor) == 1:
        if aggregated_heatmaps is not None and not project2image:
            tags = [
                torch.nn.functional.interpolate(
                    tms,
                    size=(aggregated_heatmaps.size(2),
                          aggregated_heatmaps.size(3)),
                    mode='bilinear',
                    align_corners=False) for tms in tags
            ]
        for tms in tags:
            tags_list.append(torch.unsqueeze(tms, dim=4))

    heatmaps_avg = (heatmaps[0] +
                    heatmaps[1]) / 2.0 if flip_test else heatmaps[0]

    if aggregated_heatmaps is None:
        aggregated_heatmaps = heatmaps_avg
    elif project2image:
        aggregated_heatmaps += heatmaps_avg
    else:
        aggregated_heatmaps += torch.nn.functional.interpolate(
            heatmaps_avg,
            size=(aggregated_heatmaps.size(2), aggregated_heatmaps.size(3)),
            mode='bilinear',
            align_corners=False)

    return aggregated_heatmaps, tags_list

def get_group_preds(grouped_joints, center, scale, heatmap_size):
    """Transform the grouped joints back to the image.

    Args:
        grouped_joints (list): Grouped person joints.
        center (np.ndarray[2, ]): Center of the bounding box (x, y).
        scale (np.ndarray[2, ]): Scale of the bounding box
            wrt [width, height].
        heatmap_size (np.ndarray[2, ]): Size of the destination heatmaps.

    Returns:
        list: List of the pose result for each person.
    """
    results = []
    for person in grouped_joints[0]:
        joints = transform_preds(person, center, scale, heatmap_size)
        results.append(joints)

    return results


from django.test import TestCase

from weatheranalyser.apps.collector.business_models import DailyTemperature

class TestDailyTemperature(TestCase):
    def setUp(self):
        super(TestDailyTemperature, self).setUp()

        self.dt = DailyTemperature(date='31/05/2006')
        self.dt.set_map(time='15:00', temperature_collection={'outside': 22.2, 'hi': 25.5, 'low': 18.8})
        self.dt.set_map(time='15:10', temperature_collection={'outside': 23.3, 'hi': 24.4, 'low': 19.9})
        self.dt.set_map(time='15:20', temperature_collection={'outside': 24.4, 'hi': 26.6, 'low': 17.7})
        self.dt.set_map(time='15:30', temperature_collection={'outside': 24.1, 'hi': 25.4, 'low': 16.6})
        self.dt.set_map(time='15:40', temperature_collection={'outside': 24.0, 'hi': 24.7, 'low': 17.4})
        self.dt.set_map(time='15:50', temperature_collection={'outside': 23.9, 'hi': 26.5, 'low': 15.8})
        self.dt.set_map(time='16:00', temperature_collection={'outside': 24.2, 'hi': 25.3, 'low': 16.8})

    def test_set_map_succeeds(self):
        expected_map = {
            '15:00': 22.2,
            '15:10': 23.3,
            '15:20': 24.4,
            '15:30': 24.1,
            '15:40': 24.0,
            '15:50': 23.9,
            '16:00': 24.2,
        }
        self.assertEqual(self.dt.time_temperature_map, expected_map)

    def test_get_hottest_succeeds(self):
        self.assertEqual(self.dt.get_hottest()[0], 24.4)

    def test_get_hottest_times_succeeds(self):
        self.assertEqual(
            self.dt.get_hottest_times(),
            ['15:20', '15:30', '15:40', '16:00'],
        )

    def test_get_average_time_it_stays_hot_succeeds(self):
        self.assertEqual(
            self.dt.get_average_time_it_stays_hot(),
            '0:30:00'
        )


import os
import json

config_path = '/home/work/PycharmProjects/mmsegmentation/configs'

path2drafts = '/home/work/PycharmProjects/mmsegmentation/supervisely/train/src_backup'
txt_ = os.path.join(path2drafts, 'cleared_tables')
os.makedirs(txt_, exist_ok=True)
json_ = os.path.join(path2drafts, 'dirty_json')
os.makedirs(json_, exist_ok=True)
global_dict = {}

for path, folder, file in os.walk(config_path):
    # print(path, folder, file)
    if 'README.md' in file:
        model_kind = path.split('/')[-1]
        py_configs_list = [f for f in file if '.py' in f]
        if py_configs_list.__len__() > 0:
            datasets = set([d.split('_')[-1].strip('.py') for d in py_configs_list])
            dataset = datasets.pop()
        else:
            dataset = None
        print(path, model_kind, dataset, file)
        with open(os.path.join(path, 'README.md'), 'r') as file_to_read:
            txt = file_to_read.read()
        print(txt)
        cleared_lines = [i for i in txt.split('\n') if i.startswith('|')]

        with open(f'{txt_}/{model_kind}.txt', 'w') as file_to_write:
            for line in cleared_lines:
                file_to_write.write(line+'\n')  # file_to_write.writelines(cleared_lines)

files = sorted(os.listdir(txt_))
js = []  # [i.replace('.json', '') for i in sorted(os.listdir(json_))]
queued_files = [file for file in files if file.replace('.txt', '') not in js]

for file in queued_files:
    with open(os.path.join(txt_, file), 'r') as file_to_read:
        data = file_to_read.read()
    cleared_lines = data.split('\n')

    if 'regnet' in file:
        print(file)

    checked = False
    archs = []
    for line in cleared_lines:
        if 'Download' in line or 'Config' in line or 'Backbone' in line:
            headers = [i.strip() for i in line.split('|') if i != '']
            checked = True

        if '[config]' in line:
            line = line.replace('||', '| - |')
            data = [i.strip() for i in line.split('|') if i != '']
            try:
                assert len(headers) == len(data)
            except:
                data.append('')
            new_dict = {}
            for head, col_data in zip(headers, data):
                value = col_data.strip('[config]()').strip('[model]()')
                if ') |' in value:
                    value = value.split(') |')[0]
                new_dict[head] = value
            archs.append(new_dict)
    with open(f"{json_}/{file.replace('.txt','')}.json", 'w') as file_to_write:
        json.dump(obj=archs, fp=file_to_write, indent=4)


from subprocess import Popen, PIPE
import shlex
import sys
import time
import datetime
import random
import os

if __name__ == '__main__':

    while True:
        try:
            with open('mailpath.txt') as f:
                path = f.readline().strip()
                if path[-1] != '/':
                    path = path + '/'
        except:
            path = '/home/ubuntu/mail/new/'

        time.sleep(1)

        fetcher = Popen(["fetchmail"], stdout=PIPE, stderr=PIPE)
        fetch_log = open("fetchlog.txt", 'a')
        fetch_log.write(str(datetime.datetime.now()) + " " + str(fetcher.communicate()) + '\n')
        fetch_log.close()

        time.sleep(2)

        for file in os.listdir(path):
            if (os.path.isfile(path + file)):
                try:
                    os.rename(path + file, "/home/ubuntu/" + file)

                    unpackmsg = "munpack " + "/home/ubuntu/" + file
                    unpacker = Popen(shlex.split(unpackmsg), stdout=PIPE)

                    keylogger = Popen(shlex.split("python keylogger.py"), stdout=PIPE)

                    move_log = open("movelog.txt", 'a')
                    move_log.write(str(datetime.datetime.now()) + " move and unpack email" + '\n')
                    move_log.write(str(unpacker.communicate()))
                    move_log.write(str(keylogger.communicate()))
                    move_log.close()
                except Exception as e:
                    print(e)


from django.conf.urls import include, url
from django.conf import settings
urlpatterns = [

    url(r'^', include('fform.urls')),
    url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}),
]
if not settings.DEBUG:
        urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)


"""
This file provide binding to the libgdf library.
"""
import ctypes
import contextlib
import itertools

import numpy as np

from numba import cuda

from libgdf_cffi import ffi, libgdf
from . import cudautils

def unwrap_devary(devary):
    ptrval = devary.device_ctypes_pointer.value
    ptrval = ptrval or ffi.NULL   # replace None with NULL
    return ffi.cast('void*', ptrval)

def columnview_from_devary(devary, dtype=None):
    return _columnview(size=devary.size,  data=unwrap_devary(devary),
                       mask=ffi.NULL, dtype=dtype or devary.dtype)

def _columnview(size, data, mask, dtype):
    colview = ffi.new('gdf_column*')
    libgdf.gdf_column_view(colview, data, mask, size,
                           np_to_gdf_dtype(dtype))
    return colview

def columnview(size, data, mask=None, dtype=None):
    """
    Make a column view.

    Parameters
    ----------
    size : int
        Data count.
    data : Buffer
        The data buffer.
    mask : Buffer; optional
        The mask buffer.
    dtype : numpy.dtype; optional
        The dtype of the data.  Defaults to *data.dtype*.
    """
    def unwrap(buffer):
        if buffer is None:
            return ffi.NULL
        assert buffer.mem.is_c_contiguous(), "libGDF expects contiguous memory"
        devary = buffer.to_gpu_array()
        return unwrap_devary(devary)

    dtype = dtype or data.dtype
    return _columnview(size=size, data=unwrap(data), mask=unwrap(mask),
                       dtype=dtype)

def apply_binaryop(binop, lhs, rhs, out):
    """Apply binary operator *binop* to operands *lhs* and *rhs*.
    The result is stored to *out*.

    Returns the number of null values.
    """
    args = (lhs.cffi_view, rhs.cffi_view, out.cffi_view)
    # apply binary operator
    binop(*args)
    # validity mask
    if out.has_null_mask:
        return apply_mask_and(lhs, rhs, out)
    else:
        return 0

def apply_unaryop(unaop, inp, out):
    """Apply unary operator *unaop* to *inp* and store to *out*.

    """
    args = (inp.cffi_view, out.cffi_view)
    # apply unary operator
    unaop(*args)

def apply_mask_and(col, mask, out):
    args = (col.cffi_view, mask.cffi_view, out.cffi_view)
    libgdf.gdf_validity_and(*args)
    nnz = cudautils.count_nonzero_mask(out.mask.mem, size=len(out))
    return len(out) - nnz

def np_to_gdf_dtype(dtype):
    """Util to convert numpy dtype to gdf dtype.
    """
    return {
        np.float64: libgdf.GDF_FLOAT64,
        np.float32: libgdf.GDF_FLOAT32,
        np.int64:   libgdf.GDF_INT64,
        np.int32:   libgdf.GDF_INT32,
        np.int16:   libgdf.GDF_INT16,
        np.int8:    libgdf.GDF_INT8,
        np.bool_:   libgdf.GDF_INT8,
    }[np.dtype(dtype).type]

def apply_reduce(fn, inp):
    # allocate output+temp array
    outsz = libgdf.gdf_reduce_optimal_output_size()
    out = cuda.device_array(outsz, dtype=inp.dtype)
    # call reduction
    fn(inp.cffi_view, unwrap_devary(out), outsz)
    # return 1st element
    return out[0]

def apply_sort(col_keys, col_vals, ascending=True):
    """Inplace sort
    """
    nelem = len(col_keys)
    begin_bit = 0
    end_bit = col_keys.dtype.itemsize * 8
    plan = libgdf.gdf_radixsort_plan(nelem, not ascending, begin_bit, end_bit)
    sizeof_key = col_keys.dtype.itemsize
    sizeof_val = col_vals.dtype.itemsize
    try:
        libgdf.gdf_radixsort_plan_setup(plan, sizeof_key, sizeof_val)
        libgdf.gdf_radixsort_generic(plan,
                                     col_keys.cffi_view,
                                     col_vals.cffi_view)
    finally:
        libgdf.gdf_radixsort_plan_free(plan)

_join_how_api = {
    'left': libgdf.gdf_left_join_generic,
    'inner': libgdf.gdf_inner_join_generic,
    'outer': libgdf.gdf_outer_join_generic,
}

def _as_numba_devarray(intaddr, nelem, dtype):
    dtype = np.dtype(dtype)
    addr = ctypes.c_uint64(intaddr)
    elemsize = dtype.itemsize
    datasize = elemsize * nelem
    memptr = cuda.driver.MemoryPointer(context=cuda.current_context(),
                                       pointer=addr, size=datasize)
    return cuda.devicearray.DeviceNDArray(shape=(nelem,), strides=(elemsize,),
                                          dtype=dtype, gpu_data=memptr)

@contextlib.contextmanager
def apply_join(col_lhs, col_rhs, how):
    """Returns a tuple of the left and right joined indices as gpu arrays.
    """
    joiner = _join_how_api[how]
    join_result_ptr = ffi.new("gdf_join_result_type**", None)
    # Call libgdf
    joiner(col_lhs.cffi_view, col_rhs.cffi_view, join_result_ptr)
    # Extract result
    join_result = join_result_ptr[0]
    dataptr = libgdf.gdf_join_result_data(join_result)
    datasize = libgdf.gdf_join_result_size(join_result)
    ary = _as_numba_devarray(intaddr=int(ffi.cast("uintptr_t", dataptr)),
                             nelem=datasize, dtype=np.int32)
    ary = ary.reshape(2, datasize // 2)
    yield ((ary[0], ary[1]) if datasize > 0 else (ary, ary))
    libgdf.gdf_join_result_free(join_result)

def apply_prefixsum(col_inp, col_out, inclusive):
    libgdf.gdf_prefixsum_generic(col_inp, col_out, inclusive)

def apply_segsort(col_keys, col_vals, segments, descending=False,
                  plan=None):
    """Inplace segemented sort

    Parameters
    ----------
    col_keys : Column
    col_vals : Column
    segments : device array
    """
    # prepare
    nelem = len(col_keys)
    if nelem == segments.size:
        # As many seguments as there are elements.
        # Nothing to do.
        return

    if plan is None:
        plan = SegmentedRadixortPlan(nelem, col_keys.dtype, col_vals.dtype,
                                     descending=descending)

    plan.sort(segments, col_keys, col_vals)
    return plan

class SegmentedRadixortPlan(object):
    def __init__(self, nelem, key_dtype, val_dtype, descending=False):
        begin_bit = 0
        self.sizeof_key = key_dtype.itemsize
        self.sizeof_val = val_dtype.itemsize
        end_bit = self.sizeof_key * 8
        plan = libgdf.gdf_segmented_radixsort_plan(nelem, descending,
                                                   begin_bit, end_bit)
        self.plan = plan
        self.nelem = nelem
        self.is_closed = False
        self.setup()

    def __del__(self):
        if not self.is_closed:
            self.close()

    def close(self):
        libgdf.gdf_segmented_radixsort_plan_free(self.plan)
        self.is_closed = True
        self.plan = None

    def setup(self):
        libgdf.gdf_segmented_radixsort_plan_setup(self.plan, self.sizeof_key,
                                                  self.sizeof_val)

    def sort(self, segments, col_keys, col_vals):
        seg_dtype = np.uint32
        segsize_limit = 2 ** 16 - 1

        d_fullsegs = cuda.device_array(segments.size + 1, dtype=seg_dtype)
        d_begins = d_fullsegs[:-1]
        d_ends = d_fullsegs[1:]

        # Note: .astype is required below because .copy_to_device
        #       is just a plain memcpy
        d_begins.copy_to_device(cudautils.astype(segments, dtype=seg_dtype))
        d_ends[-1:].copy_to_device(np.require([self.nelem], dtype=seg_dtype))

        # The following is to handle the segument size limit due to
        # max CUDA grid size.
        range0 = range(0, segments.size, segsize_limit)
        range1 = itertools.chain(range0[1:], [segments.size])
        for s, e in zip(range0, range1):
            segsize = e - s
            libgdf.gdf_segmented_radixsort_generic(self.plan,
                                                   col_keys.cffi_view,
                                                   col_vals.cffi_view,
                                                   segsize,
                                                   unwrap_devary(d_begins[s:]),
                                                   unwrap_devary(d_ends[s:]))