import rospy
import numpy
import random
from gym import spaces
from openai_ros.robot_envs import turtlebot2_joy_env
from gym.envs.registration import register
from geometry_msgs.msg import Point
from openai_ros.task_envs.task_commons import LoadYamlFileParamsTest
from openai_ros.openai_ros_common import ROSLauncher
from scipy.spatial.transform import Rotation as R
import os
from gazebo_msgs.srv import SpawnModel, DeleteModel
from geometry_msgs.msg import Pose
import tensorflow as tf
from gazebo_msgs.msg import ModelState
from gazebo_msgs.srv import SetModelState
from gazebo_msgs.srv import GetModelState
import time
from math import atan2

'''
with Manually preprocessed U and lidar readings
'''
class TurtleBot2HumanModelEnv(turtlebot2_joy_env.TurtleBot2Env):
    def __init__(self):
        """
        This Task Env is designed for having the TurtleBot2 in some kind of maze.
        It will learn how to move around the maze without crashing.
        """

        # This is the path where the simulation files, the Task and the Robot gits will be downloaded if not there
        ros_ws_abspath = rospy.get_param("/turtlebot2/ros_ws_abspath", None)
        assert ros_ws_abspath is not None, "You forgot to set ros_ws_abspath in your yaml file of your main RL script. Set ros_ws_abspath: \'YOUR/SIM_WS/PATH\'"
        assert os.path.exists(ros_ws_abspath), "The Simulation ROS Workspace path " + ros_ws_abspath + \
                                               " DOESNT exist, execute: mkdir -p " + ros_ws_abspath + \
                                               "/src;cd " + ros_ws_abspath + ";catkin_make"

        ROSLauncher(rospackage_name="turtlebot_gazebo",
                    launch_file_name="start_goal_world.launch",
                    ros_ws_abspath=ros_ws_abspath)

        # Load Params from the desired Yaml file
        LoadYamlFileParamsTest(rospackage_name="openai_ros",
                               rel_path_from_package_to_file="src/openai_ros/task_envs/turtlebot2/config",
                               yaml_file_name="turtlebot2_goal_continuous_humanmodel.yaml")

        # Here we will add any init functions prior to starting the MyRobotEnv
        super(TurtleBot2HumanModelEnv, self).__init__(ros_ws_abspath)

        # Only variable needed to be set here

        high = numpy.array([1,1,1,1])
        low = numpy.array([-1,-1,-1,-1])

        #high = numpy.array([0,1,1,1])
        #low = numpy.array([0,-1,-1,-1])

        self.action_space = spaces.Box(low, high)

        # We set the reward range, which is not compulsory but here we do it.
        self.reward_range = (-numpy.inf, numpy.inf)

        self.success = True
        self.beta = 0
        #self.beta = 1
        #number_observations = rospy.get_param('/turtlebot2/n_observations')
        """
        We set the Observation space for the 6 observations
        cube_observations = [
            round(current_disk_roll_vel, 0),
            round(y_distance, 1),
            round(roll, 1),
            round(pitch, 1),
            round(y_linear_speed,1),
            round(yaw, 1),
        ]
        """

        # Actions and Observations

        self.init_linear_forward_speed = rospy.get_param('/turtlebot2/init_linear_forward_speed')
        self.init_linear_turn_speed = rospy.get_param('/turtlebot2/init_linear_turn_speed')

        self.new_ranges = 180
        self.min_range = rospy.get_param('/turtlebot2/min_range')
        self.max_laser_value = rospy.get_param('/turtlebot2/max_laser_value')
        self.min_laser_value = rospy.get_param('/turtlebot2/min_laser_value')

        # Get Desired Point to Get
        self.desired_point = Point()
        self.desired_point.x = rospy.get_param("/turtlebot2/desired_pose/x")
        self.desired_point.y = rospy.get_param("/turtlebot2/desired_pose/y")
        self.desired_point.z = rospy.get_param("/turtlebot2/desired_pose/z")

        self.state_msg = ModelState()
        self.state_msg.model_name = 'mobile_base'
        self.state_msg.pose.position.x = 0
        self.state_msg.pose.position.y = 0
        self.state_msg.pose.position.z = 0
        self.state_msg.pose.orientation.x = 0
        self.state_msg.pose.orientation.y = 0
        self.state_msg.pose.orientation.z = 0
        self.state_msg.pose.orientation.w = 0
        # We create two arrays based on the binary values that will be assigned
        # In the discretization method.
        laser_scan = self.get_laser_scan()
        #print("lidar data:", laser_scan)
        rospy.logdebug("laser_scan len===>" + str(len(laser_scan.ranges)))

        #high = numpy.array([0.5,1,1,1,1,1,6,3.14])#,numpy.array([12,6,3.14,1,3.14,0.5,1]),6*numpy.ones([self.new_ranges]),numpy.array([12,6,3.14,1,3.14,0.5,1]),6*numpy.ones([self.new_ranges])))

        high = numpy.hstack((numpy.array([0.5,1,0.5,1]),6*numpy.ones([self.new_ranges])))
        #high = numpy.hstack((numpy.array([0,1,0.5,1]),6*numpy.ones([self.new_ranges])))

        #high = numpy.hstack((numpy.array([1,1]),numpy.ones([self.new_ranges]),numpy.array([1,1]),numpy.ones([self.new_ranges]),numpy.array([1,1]),numpy.ones([self.new_ranges])))
        #low = numpy.array([-0.5,-1,-1,-1,-1,-1, 0,-3.14])#,numpy.array([-1,-1*6,-1*3.14,-1,-3.14,-0.5,-1]),numpy.zeros([self.new_ranges]),numpy.array([-1,-1*6,-1*3.14,-1,-3.14,-0.5,-1]),numpy.zeros([self.new_ranges])))

        low = numpy.hstack((numpy.array([-0.5,-1,-0.5,-1]),numpy.zeros([self.new_ranges])))

        #low = numpy.hstack((numpy.array([0,-1,-0.5,-1]),numpy.zeros([self.new_ranges])))

        #low = numpy.hstack((numpy.array([-1,-1]),numpy.zeros([self.new_ranges]),numpy.array([1,1]),numpy.ones([self.new_ranges]),numpy.array([1,1]),numpy.ones([self.new_ranges])))
        # We only use two integers
        self.observation_space = spaces.Box(low, high)

        rospy.logdebug("ACTION SPACES TYPE===>"+str(self.action_space))
        rospy.logdebug("OBSERVATION SPACES TYPE===>"+str(self.observation_space))

        # Rewards
        self.forwards_reward = rospy.get_param("/turtlebot2/forwards_reward")
        self.turn_reward = rospy.get_param("/turtlebot2/turn_reward")
        self.end_episode_points = rospy.get_param("/turtlebot2/end_episode_points")

        self.cumulated_steps = 0.0

        ############################## goal ##############################################
        self.goal_position = Pose()
        self.f = open('/home/i2rlab/shahil_files/shahil_RL_ws_new/src/turtlebot/turtlebot_gazebo/worlds/goal/model.sdf','r')
        self.sdff = self.f.read()

        ############################## Obstacle ##########################################
        self.angle=numpy.linspace(-179,179,180)/180*numpy.pi
        self.cos = numpy.cos(self.angle)
        self.sin = numpy.sin(self.angle)
        ############################## Human Model ######################################
        config = tf.ConfigProto(gpu_options=tf.GPUOptions(allow_growth=True))
        self.sess = tf.Session(config=config)
        self.S1 = tf.placeholder(tf.float32, [None, 5], 'S1')
        #self.S2 = tf.placeholder(tf.float32, [None, 198, 1], 'S2')
        self.S2 = tf.placeholder(tf.float32, [None, 180], 'S2')
        self.keep_prob = tf.placeholder(tf.float32)
        self.a_predict = self.build_c(self.S1,self.S2,self.keep_prob)
        self.loader()
        self.goal_space()
        self.time_start = 0
        #self.xy = numpy.array([-8.1,-7.0])

    def loader(self):
        loader= tf.train.Saver()
        loader.restore(self.sess,tf.train.latest_checkpoint('Human_model_3'))

    def build_c(self,S1,S2,keep_prob):
        '''net1 = tf.layers.dense(S2, 256, activation=tf.nn.relu, name='net1', trainable=True, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        net2 = tf.layers.dense(net1, 512, activation=tf.nn.relu, name='net2', trainable=True, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        net3 = tf.layers.dense(net2, 512, activation=tf.nn.relu, name='net3', trainable=True, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        net4 = tf.layers.dense(net3, 256, activation=tf.nn.relu, name='net4', trainable=True, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        net5 = tf.layers.dense(net4, 128, activation=tf.nn.relu, name='net5', trainable=True, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        net6 = tf.layers.dense(net5, 32,trainable=True,activation=tf.nn.relu, name='net6')
        #net5_input = tf.concat([S1, net4], 1)

        net7 = tf.layers.dense(S1, 256, activation=tf.nn.relu, name='net7', trainable=True, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        #drop_out5 = tf.nn.dropout(net5, keep_prob)
        net8 = tf.layers.dense(net7,512, activation=tf.nn.relu,name='net8',trainable=True, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        net9 = tf.layers.dense(net8,512, activation=tf.nn.relu,name='net9',trainable=True, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        #drop_out6 = tf.nn.dropout(net6, keep_prob)
        net10 = tf.layers.dense(net9,32, activation=tf.nn.relu,name='net10',trainable=True, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        #drop_out7 = tf.nn.dropout(net7, keep_prob)

        net11_input = tf.concat([net10, net6], 1)
        net11 = tf.layers.dense(net11_input, 256, activation=tf.nn.relu, name='net11', trainable=True, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        net12 = tf.layers.dense(net11, 128, activation=tf.nn.relu, name='net12', trainable=True, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        #net13 = tf.layers.dense(net12, 2,trainable=True,activation=tf.nn.relu, name='net13')

        a = tf.layers.dense(net12,2,trainable=True,activation=tf.tanh)
        return tf.multiply(a, [0.5,1], name='scaled_a')'''

        net1 = tf.layers.dense(S2, 256, activation=tf.nn.relu, name='net1', trainable=True, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        net2 = tf.layers.dense(net1, 512, activation=tf.nn.relu, name='net2', trainable=True, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        net3 = tf.layers.dense(net2, 512, activation=tf.nn.relu, name='net3', trainable=True, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        net4 = tf.layers.dense(net3, 256, activation=tf.nn.relu, name='net4', trainable=True, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        net5 = tf.layers.dense(net4, 128, activation=tf.nn.relu, name='net5', trainable=True, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        net6 = tf.layers.dense(net5, 64,trainable=True,activation=tf.nn.relu, name='net6')
        #net5_input = tf.concat([S1, net4], 1)

        net7 = tf.layers.dense(S1, 256, activation=tf.nn.relu, name='net7', trainable=True, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        #drop_out5 = tf.nn.dropout(net5, keep_prob)
        net8 = tf.layers.dense(net7,256, activation=tf.nn.relu,name='net8',trainable=True, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        #drop_out6 = tf.nn.dropout(net6, keep_prob)
        net9 = tf.layers.dense(net8,32, activation=tf.nn.relu,name='net9',trainable=True, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        #drop_out7 = tf.nn.dropout(net7, keep_prob)

        net10_input = tf.concat([net9, net6], 1)
        net10 = tf.layers.dense(net10_input, 256, activation=tf.nn.relu, name='net10', trainable=True, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        net11 = tf.layers.dense(net10, 128, activation=tf.nn.relu, name='net11', trainable=True, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        #net13 = tf.layers.dense(net12, 2,trainable=True,activation=tf.nn.relu, name='net13')

        a = tf.layers.dense(net11,2,trainable=True,activation=tf.tanh)
        return tf.multiply(a, [0.5,1], name='scaled_a')

    def choose_action(self,s):
        bs1 = s[:, :5]
        #bs2 = numpy.hstack((s[:, 5:],s[:, 5:23])).reshape([-1,198,1])
        #bs2 = s[:,5:].reshape([-1,198,1])
        a = self.sess.run(self.a_predict, {self.S1:s[:,:5],self.S2:s[:,5:],self.keep_prob:1})
        print("original a:",a)
        #return a
        return a[0]
        ################################################################################

    def _set_init_pose(self):
        """Sets the Robot in its init pose
        """
        self.move_base( self.init_linear_forward_speed,
                        self.init_linear_turn_speed,
                        epsilon=0.05,
                        update_rate=10)

        return True

    def _init_env_variables(self):
        """
        Inits variables needed to be initialised each time we reset at the start
        of an episode.
        :return:
        """
        # For Info Purposes
        self.cumulated_reward = 0.0
        # Set to false Done, because its calculated asyncronously
        self._episode_done = False
        self._outofrange = False
        #self.desired_point.x = random.uniform(1,10)
        #self.desired_point.y = random.uniform(-5,5)

        try:
            self.deleteModel()
        except:
            pass
        self.respawnModel()
        #self.get_statemsg()
        self.moveto()
        #time.sleep(2)
        #self.obstaclemoveto()
        odometry = self.get_odom()
        self.previous_distance_from_des_point = self.get_distance_from_desired_point(odometry.pose.pose.position)
        self.prev_position = [-1]
        self.prev_u_gtg = -1
        self.last_action = -1
        self.u_h=numpy.array([0,0])

    def _set_action(self, ratio):
        """
        """
        ratio=list(ratio)
        rospy.logdebug("Start Set Action ==>"+str(ratio))
        joy = self.get_joy()

        #print("ratio:",ratio)
        #if joy.linear.x==0 and joy.angular.z==0:          #Condition to get input from human agent
        linear_speed=self.joy_linear
        angular_speed=self.joy_angular

        #linear_speed = self.joy_linear
        #angular_speed = self.joy_angular

        #linear_speed = ratio[1]*self.a_ao[0,0]+ratio[2]*self.a_c[0,0]+ratio[3]*self.a_cc[0,0]
        #angular_speed = ratio[1]*self.a_ao[1,0]+ratio[2]*self.a_c[1,0]+ratio[3]*self.a_cc[1,0]

        '''lidar = numpy.array(self.get_laser_scan().ranges)
        n = numpy.argmin(lidar)
        ao_critical_angle = 20

        odometry = self.get_odom()
        x_position = odometry.pose.pose.position.x
        y_position = odometry.pose.pose.position.y
        base_orientation_quat = odometry.pose.pose.orientation
        base_roll, base_pitch, base_yaw = self.get_orientation_euler(base_orientation_quat)

        xdiff = self.desired_point.x - x_position
        ydiff = self.desired_point.y - y_position

        angle_to_goal = atan2(ydiff,xdiff)
        angle_to_obs = 2*n
        print('angle to obs:',angle_to_obs)

        obs_dist = lidar[n]'''
        '''if abs(angle_to_goal - base_yaw) > 0.5:
            linear_speed = 0.0
            angular_speed = 0.5
        else:
            if obs_dist > 1.1:
                linear_speed = 2
                angular_speed = 0.0
            elif obs_dist < 1.1 and obs_dist > 0.6:
                linear_speed = ratio[0]*(0)+ratio[1]*self.a_ao[0,0]+ratio[2]*self.a_c[0,0]+ratio[3]*self.a_cc[0,0]
                angular_speed = ratio[0]*(0)+ratio[1]*self.a_ao[1,0]+ratio[2]*self.a_c[1,0]+ratio[3]*self.a_cc[1,0]
            elif obs_dist < 0.6:
                linear_speed = self.a_ao[0,0]
                angular_speed = self.a_ao[1,0]'''

        '''if obs_dist > 1.1:
            if abs(angle_to_goal - base_yaw) > 0.5:
                linear_speed = 0.0
                angular_speed = 0.5
            else:
                linear_speed = 2
                angular_speed = 0.0
        elif obs_dist < 1.1 and obs_dist > 0.6: #and (angle_to_obs < 90 and angle_to_obs > 270):
            linear_speed = 0.0
            angular_speed = 0.0
            if angle_to_obs < 40 and angle_to_obs > 320:
                linear_speed = self.a_ao[0,0]
                angular_speed = self.a_ao[1,0]
            elif angle_to_obs > 20:
                linear_speed = self.a_c[0,0]
                angular_speed = self.a_c[1,0]
            elif angle_to_obs > 340:
                linear_speed = self.a_cc[0,0]
                angular_speed = self.a_cc[1,0]
        elif obs_dist <= 0.6:
            linear_speed = self.a_ao[0,0]
            angular_speed = self.a_ao[1,0]'''
        '''else:
            if abs(angle_to_goal - base_yaw) > 0.5:
                linear_speed = 0.0
                angular_speed = 0.5
            else:
                linear_speed = 0.8
                angular_speed = 0.0'''

        #angular_speed = 0.6*self.theta_dot+0.4*angular_speed
        # We tell TurtleBot2 the linear and angular speed to set to execute
        self.move_base(linear_speed, angular_speed, epsilon=0.05, update_rate=10)
        self.u_b = numpy.array([linear_speed,angular_speed])
        rospy.logdebug("END Set Action ==>"+str(ratio))

    def _get_obs(self):
        """
        Here we define what sensor data defines our robots observations
        To know which Variables we have acces to, we need to read the
        TurtleBot2Env API DOCS
        :return:
        """
        #self.obstaclemoveto()
        rospy.logdebug("Start Get Observation ==>")
        # We get the laser scan data
        laser_scan = self.get_laser_scan()
        #print("lidar data:", laser_scan)

        discretized_laser_scan = self.discretize_observation( laser_scan,                       #discretized lidar data
                                                                self.new_ranges
                                                                )
        # We get the odometry so that SumitXL knows where it is.
        odometry = self.get_odom()
        #joy = self.get_joy()
        x_position = odometry.pose.pose.position.x
        y_position = odometry.pose.pose.position.y
        base_orientation_quat = odometry.pose.pose.orientation
        base_roll, base_pitch, base_yaw = self.get_orientation_euler(base_orientation_quat)
        print('base_yaw:',base_yaw)
        v = odometry.twist.twist.linear.x
        self.theta_dot = odometry.twist.twist.angular.z

        ###################human input ##############################
        #time_now = time.localtime(time.time())
        time_now = time.time()
        run_time = time_now - self.time_start
        print('run time: ', run_time)

        joy = self.get_joy()

        if run_time > 3:
            if joy.linear.x != 0 or joy.angular.z != 0:
                self.beta = 1

        print('beta_now: ',self.beta)

        annotation = numpy.zeros(8)
        if min(discretized_laser_scan[:23]) <= 3:
            annotation[0] = min(discretized_laser_scan[:23])
        else:
            annotation[0] = 0

        if min(discretized_laser_scan[23:45]) <= 3:
            annotation[1] = min(discretized_laser_scan[23:45])
        else:
            annotation[1] = 0

        if min(discretized_laser_scan[45:68]) <= 3:
            annotation[2] = min(discretized_laser_scan[45:68])
        else:
            annotation[2] = 0

        if min(discretized_laser_scan[68:90]) <= 3:
            annotation[3] = min(discretized_laser_scan[68:90])
        else:
            annotation[3] = 0

        if min(discretized_laser_scan[90:113]) <= 3:
            annotation[4] = min(discretized_laser_scan[90:113])
        else:
            annotation[4] = 0

        if min(discretized_laser_scan[113:135]) <= 3:
            annotation[5] = min(discretized_laser_scan[113:135])
        else:
            annotation[5] = 0

        if min(discretized_laser_scan[135:158]) <= 3:
            annotation[6] = min(discretized_laser_scan[135:158])
        else:
            annotation[6] = 0

        if min(discretized_laser_scan[158:180]) <= 3:
            annotation[7] = min(discretized_laser_scan[158:180])
        else:
            annotation[7] = 0

        if self.beta == 1:
            self.joy_linear = joy.linear.x
            self.joy_angular = joy.angular.z

        ##################### Data Collection #############################
            del_x = (self.desired_point.x-(x_position))
            del_y = (self.desired_point.y-(y_position))
            laser_scan_recorded = numpy.append(discretized_laser_scan,discretized_laser_scan[0])
            #data_needed = numpy.array(["%10.3e"%(base_yaw),"%10.3e"%(v),"%10.3e"%(self.theta_dot),"%10.3e"%(del_x),"%10.3e"%(del_y)])#.encode()    # save the needed data in form of string
            data_needed = numpy.array([(base_yaw),(v),(self.theta_dot),(del_x),(del_y)])
            #data_needed = numpy.array([(base_yaw),(v),(self.theta_dot)])
            data_needed = numpy.concatenate((data_needed,laser_scan_recorded),axis=0)

            #data_needed = numpy.append(data_needed, (annotation))
            #data_needed = numpy.append(data_needed, (del_x),(del_y))

            #data_needed = numpy.append(data_needed,"%10.3e"%(self.joy_linear),"%10.3e"%(self.joy_angular))
            data_needed = numpy.append(data_needed,(joy.linear.x))
            data_needed = numpy.append(data_needed,(joy.angular.z))
            #print( data_needed)

            with open("scaled_house_data_2.dat", "a", newline='') as f:
                #f.write(data_needed+b"\n")           # write the data to the file
                f.write(str(data_needed).replace('\n','').replace('[','').replace(']','')+'\n')

        ###################human agent ##################################
        else:
            print('I am here')
            xdiff = self.desired_point.x - x_position
            ydiff = self.desired_point.y - y_position
            observations = [(base_yaw),(v),(self.theta_dot),(xdiff),(ydiff)]#+ discretized_laser_scan
            observations = numpy.append(observations,discretized_laser_scan)
            #observations = numpy.append(observations,numpy.array(discretized_laser_scan))
            #observations = numpy.append(observations,numpy.array(discretized_laser_scan[:18]))
            #observations = numpy.append(observations,discretized_laser_scan[0])
            s = numpy.array([observations])
            #a = [0,0]
            a = self.choose_action(s)
            self.joy_linear = a[0]
            print(self.joy_linear)
            self.joy_angular = a[1]

        tran = numpy.array([[numpy.cos(0),-numpy.sin(0)],[numpy.sin(0),numpy.cos(0)]]).dot(numpy.array([[1,0],[0,0.115]]))
        self.u_gtg = tran.dot(numpy.array([[self.joy_linear],[self.joy_angular]]))
        self.obstacle_avoidance()

        # We round to only two decimals to avoid very big Observation space
        ################################################  Change Observations  ########################################################################################
        observations = [round(x_position, 2),round(y_position, 2),round(base_yaw, 2),round(v, 2),round(self.theta_dot, 2),round(self.joy_linear, 2),round(self.joy_angular, 2)]+discretized_laser_scan+[self.e_norm, round(self.theta_bt_uh_ob,2)]
        #print(observations)
        #print("Observations==>"+observations)
        rospy.logdebug("Observations==>"+str(observations))
        rospy.logdebug("END Get Observation ==>")
        return observations

    def obstacle_avoidance(self):
        lidar = numpy.array(self.get_laser_scan().ranges)
        #lidar = self.discretize_observation( lidar,self.new_ranges)
        # odometry = self.get_odom()
        # base_orientation_quat = odometry.pose.pose.orientation
        # base_roll, base_pitch, yaw = self.get_orientation_euler(base_orientation_quat)
        yaw = 0
        ################################## nearest ######################################################
        n = numpy.argmin(lidar)                     # gives angle of the obstracle
        if n<=89:
            delta_angle = ((n-89)*2-1)/180*numpy.pi
        else:
            delta_angle = ((n-90)*2+1)/180*numpy.pi
        orientation = yaw + delta_angle
        self.e_norm = lidar[n]
        e = numpy.array([[-self.e_norm*numpy.cos(orientation)],[-self.e_norm*numpy.sin(orientation)]])
        ################################## weighted #######################################################
        # n = numpy.argmin(lidar)
        # if lidar[n]>1.1:
        #     if n<=89:
        #         delta_angle = ((n-89)*2-1)/180*numpy.pi
        #     else:
        #         delta_angle = ((n-90)*2+1)/180*numpy.pi
        #     orientation = yaw + delta_angle
        #     self.e_norm = lidar[n]
        #     e = numpy.array([[-self.e_norm*numpy.cos(orientation)],[-self.e_norm*numpy.sin(orientation)]])
        # else:
        #     lidar_power = numpy.power(lidar, -2)
        #     lidar_power[numpy.argwhere(lidar>1.1)]=0
        #     lidar_power_sum = numpy.sum(lidar_power)
        #     weight=lidar_power/lidar_power_sum
        #     e_robot = numpy.array([numpy.sum(self.cos*lidar*weight),numpy.sum(self.sin*lidar*weight)])
        #     self.e_norm = numpy.linalg.norm(e_robot)
        #     orientation = numpy.arctan2(e_robot[1],e_robot[0])+yaw
        #     e = numpy.array([[-self.e_norm*numpy.cos(orientation)],[-self.e_norm*numpy.sin(orientation)]])
        # print(self.e_norm)
        ########################################### Controller velocities ########################################################

        #u_ao = 0.5/self.e_norm*(1/(self.e_norm**2+0.1))*e       # obstracle avoidance controller
        #u_c = 0.5*numpy.array([[0,1],[-1,0]]).dot(u_ao)         # Follow wall clockwise controller
        #u_cc =0.5*numpy.array([[0,-1],[1,0]]).dot(u_ao)         # Follow wall counter clockwise controller

        u_ao = 2.5/self.e_norm*(1/(self.e_norm**2+0.1))*e
        u_c = 2.5*numpy.array([[0,1],[-1,0]]).dot(u_ao)
        u_cc = 2.5*numpy.array([[0,-1],[1,0]]).dot(u_ao)

        self.a_ao = numpy.array([[1,0],[0,1/0.115]]).dot(numpy.array([[numpy.cos(-yaw),-numpy.sin(-yaw)],[numpy.sin(-yaw),numpy.cos(-yaw)]])).dot(u_ao)
        self.a_c = numpy.array([[1,0],[0,1/0.115]]).dot(numpy.array([[numpy.cos(-yaw),-numpy.sin(-yaw)],[numpy.sin(-yaw),numpy.cos(-yaw)]])).dot(u_c)
        self.a_cc = numpy.array([[1,0],[0,1/0.115]]).dot(numpy.array([[numpy.cos(-yaw),-numpy.sin(-yaw)],[numpy.sin(-yaw),numpy.cos(-yaw)]])).dot(u_cc)
        print("u_ao:",u_ao)
        self.limitu()
        self.theta_bt_uh_ob = abs(numpy.arctan2(self.u_gtg[1,0],self.u_gtg[0,0])-orientation)
        if self.theta_bt_uh_ob > numpy.pi:
            self.theta_bt_uh_ob = 2 * numpy.pi - self.theta_bt_uh_ob
        # self.e_norm = lidar[n]
        #####################################potantial field mathod##############################################################
        # n = numpy.argmin(lidar)
        # if lidar[n]>1.3:
        #     if n<=89:
        #         delta_angle = ((n-89)*2-1)/180*numpy.pi
        #     else:
        #         delta_angle = ((n-90)*2+1)/180*numpy.pi
        #     orientation = yaw + delta_angle
        #     self.e_norm = lidar[n]
        #     e = numpy.array([[-self.e_norm*numpy.cos(orientation)],[-self.e_norm*numpy.sin(orientation)]])
        #     print(self.e_norm)
        #     u_ao = 0.5/self.e_norm*(1/(self.e_norm**2+0.1))*e
        #     u_c = 0.5*numpy.array([[0,1],[-1,0]]).dot(u_ao)
        #     u_cc =0.5*numpy.array([[0,-1],[1,0]]).dot(u_ao)
        #     self.a_ao = numpy.array([[1,0],[0,1/0.115]]).dot(numpy.array([[numpy.cos(-yaw),-numpy.sin(-yaw)],[numpy.sin(-yaw),numpy.cos(-yaw)]])).dot(u_ao)
        #     self.a_c = numpy.array([[1,0],[0,1/0.115]]).dot(numpy.array([[numpy.cos(-yaw),-numpy.sin(-yaw)],[numpy.sin(-yaw),numpy.cos(-yaw)]])).dot(u_c)
        #     self.a_cc = numpy.array([[1,0],[0,1/0.115]]).dot(numpy.array([[numpy.cos(-yaw),-numpy.sin(-yaw)],[numpy.sin(-yaw),numpy.cos(-yaw)]])).dot(u_cc)
        #     self.limitu()
        #     self.theta_bt_uh_ob = abs(numpy.arctan2(self.u_gtg[1,0],self.u_gtg[0,0])-orientation)
        #     if self.theta_bt_uh_ob > numpy.pi:
        #         self.theta_bt_uh_ob = 2 * numpy.pi - self.theta_bt_uh_ob
        # else:
        #     orientation = yaw + self.angle
        #     e = numpy.array([-lidar*numpy.cos(orientation),-lidar*numpy.sin(orientation)])
        #     K = 0.5/lidar*(1/(numpy.power(lidar, 2)+0.1))
        #     K[numpy.argwhere(lidar>1.3)]=0
        #     u_ao = numpy.sum(K*e,axis=1).reshape(2,1)
        #     u_c = 0.5*numpy.array([[0,1],[-1,0]]).dot(u_ao)
        #     u_cc =0.5*numpy.array([[0,-1],[1,0]]).dot(u_ao)
        #     self.a_ao = numpy.array([[1,0],[0,1/0.115]]).dot(numpy.array([[numpy.cos(-yaw),-numpy.sin(-yaw)],[numpy.sin(-yaw),numpy.cos(-yaw)]])).dot(u_ao)
        #     self.a_c = numpy.array([[1,0],[0,1/0.115]]).dot(numpy.array([[numpy.cos(-yaw),-numpy.sin(-yaw)],[numpy.sin(-yaw),numpy.cos(-yaw)]])).dot(u_c)
        #     self.a_cc = numpy.array([[1,0],[0,1/0.115]]).dot(numpy.array([[numpy.cos(-yaw),-numpy.sin(-yaw)],[numpy.sin(-yaw),numpy.cos(-yaw)]])).dot(u_cc)
        #     self.limitu()
        #     self.theta_bt_uh_ob = abs(numpy.arctan2(self.u_gtg[1,0],self.u_gtg[0,0])-numpy.arctan2(-u_ao[1,0],-u_ao[0,0]))
        #     if self.theta_bt_uh_ob > numpy.pi:
        #         self.theta_bt_uh_ob = 2 * numpy.pi - self.theta_bt_uh_ob
        #     self.e_norm = lidar[n]

    def limitu(self,):
        if abs(self.a_ao[0,0])>0.5 or abs(self.a_ao[1,0])>0.3:
            self.a_ao =self.a_ao/max(abs(self.a_ao/[[0.5],[0.3]]))
        if abs(self.a_c[0,0]>0.5) or abs(self.a_c[1,0])>0.4:
            self.a_c =self.a_c/max(abs(self.a_c/[[0.5],[0.4]]))
        if abs(self.a_cc[0,0])>0.5 or abs(self.a_cc[1,0])>0.4:
            self.a_cc =self.a_cc/max(abs(self.a_cc/[[0.5],[0.4]]))
        #print(self.a_ao,self.a_c,self.a_cc)

    def _is_done(self, observations):
        if self._episode_done:
            rospy.logerr("TurtleBot2 is Too Close to wall==>")
        else:
            #rospy.logerr("TurtleBot2 didnt crash at least ==>")
            current_position = Point()
            current_position.x = observations[0]
            current_position.y = observations[1]
            #current_v = observations[3]
            #current_thetadot = observations[4]
            current_position.z = 0.0
            MAX_X = 10
            MIN_X = -10
            MAX_Y = 10
            MIN_Y = -10

            # We see if we are outside the Learning Space

            if current_position.x <= MAX_X and current_position.x > MIN_X:
                if current_position.y <= MAX_Y and current_position.y > MIN_Y:
                    rospy.logdebug("TurtleBot Position is OK ==>["+str(current_position.x)+","+str(current_position.y)+"]")

                    # We see if it got to the desired point
                    if self.is_in_desired_position(current_position):
                        #if current_v == 0 and current_thetadot == 0:
                            self._episode_done = True

                else:
                    rospy.logerr("TurtleBot to Far in Y Pos ==>"+str(current_position.x))
                    self._episode_done = True
                    self._outofrange = True
            else:
                rospy.logerr("TurtleBot to Far in X Pos ==>"+str(current_position.x))
                self._episode_done = True
                self._outofrange = True

        return self._episode_done

    def _compute_reward(self, observations, done):

        current_position = Point()
        current_position.x = observations[0]
        current_position.y = observations[1]
        current_position.z = 0.0
        min_distance = observations[-2]
        current_yaw = observations[2]

        ################    ##################################
        xdiff = self.desired_point.x - observations[0]
        ydiff = self.desired_point.y - observations[1]

        distance_from_des_point = self.get_distance_from_desired_point(current_position)
        #print("distance to des", + distance_from_des_point)
        distance_difference =  distance_from_des_point - self.previous_distance_from_des_point
        theta = numpy.arctan2(ydiff,xdiff)
        d_theta = abs(theta - current_yaw)
        if d_theta > numpy.pi:
            d_theta = 2 * numpy.pi - d_theta
        reward = 0
        ######################################################
        if not done:
            if distance_difference < 0.0:
                #rospy.logwarn("DECREASE IN DISTANCE GOOD")
                reward = -20 * abs(numpy.pi - d_theta) * distance_difference#-30*(1-numpy.tanh(4.5*(min_distance-0.5)))
                #reward = -5
            else:
                reward = -5
            # reward_sim = (numpy.linalg.norm(self.u_h-self.u_b))**2
            # if reward_sim > 2:
            #     reward -= reward_sim
            if min_distance < 0.8:
                reward -= 5/min_distance
            self.success = True
        else:
            if self.is_in_desired_position(current_position):
                #reward = 0
                reward = 1000
                self.success = True
            elif self._outofrange:
                reward = -1000
                self.success = False
            else:
                reward = -1000
                self.success = True
        self.u_h=numpy.array([self.joy_linear,self.joy_angular])
        print("reward:",+ reward)
        self.previous_distance_from_des_point = distance_from_des_point
        rospy.logdebug("reward=" + str(reward))
        self.cumulated_reward += reward
        rospy.logdebug("Cumulated_reward=" + str(self.cumulated_reward))
        self.cumulated_steps += 1
        rospy.logdebug("Cumulated_steps=" + str(self.cumulated_steps))
        return round(reward,2)

    # Internal TaskEnv Methods

    def discretize_observation(self,data,new_ranges):
        """
        Discards all the laser readings that are not multiple in index of new_ranges
        value.
        """
        self._episode_done = False

        discretized_ranges = []
        mod = len(data.ranges)/new_ranges

        rospy.logdebug("data=" + str(data))
        rospy.logwarn("new_ranges=" + str(new_ranges))
        rospy.logwarn("mod=" + str(mod))

        for i, item in enumerate(data.ranges):
            if (i%mod==0):
                if item == float ('Inf') or numpy.isinf(item):
                    discretized_ranges.append(self.max_laser_value)
                elif numpy.isnan(item):
                    discretized_ranges.append(self.min_laser_value)
                else:
                    discretized_ranges.append(round(item,3))

                if (self.min_range > item > 0):
                    #rospy.logerr("done Validation >>> item=" + str(item)+"< "+str(self.min_range))
                    self._episode_done = True
                #else:
                    #rospy.logwarn("NOT done Validation >>> item=" + str(item)+"> "+str(self.min_range))

        return discretized_ranges

    def is_in_desired_position(self,current_position, epsilon=0.5):
        """
        It return True if the current position is similar to the desired poistion
        """

        is_in_desired_pos = False
        is_in_desired_pos = self.get_distance_from_desired_point(current_position) <= epsilon
        '''
        x_pos_plus = self.desired_point.x + epsilon
        x_pos_minus = self.desired_point.x - epsilon
        y_pos_plus = self.desired_point.y + epsilon
        y_pos_minus = self.desired_point.y - epsilon

        x_current = current_position.x
        y_current = current_position.y

        x_pos_are_close = (x_current <= x_pos_plus) and (x_current > x_pos_minus)
        y_pos_are_close = (y_current <= y_pos_plus) and (y_current > y_pos_minus)

        is_in_desired_pos = x_pos_are_close and y_pos_are_close
        '''
        return is_in_desired_pos

    def get_distance_from_desired_point(self, current_position):
        """
        Calculates the distance from the current position to the desired point
        :param start_point:
        :return:
        """
        distance = self.get_distance_from_point(current_position,
                                                self.desired_point)

        return distance

    def get_distance_from_point(self, pstart, p_end):
        """
        Given a Vector3 Object, get distance from current position
        :param p_end:
        :return:
        """
        a = numpy.array((pstart.x, pstart.y, pstart.z))
        b = numpy.array((p_end.x, p_end.y, p_end.z))

        distance = numpy.linalg.norm(a - b)

        return distance

    def get_orientation_euler(self, quaternion_vector):
        # We convert from quaternions to euler
        orientation_list = [quaternion_vector.x,
                            quaternion_vector.y,
                            quaternion_vector.z,
                            quaternion_vector.w]

        r = R.from_quat(orientation_list)
        roll, pitch, yaw = r.as_rotvec()
        return roll, pitch, yaw

    def respawnModel(self):
        if self.success:
            #self.obstacle2_msg.pose.position.x= random.uniform(4.5,7.5)
            #lw = 1.5-abs(self.obstacle2_msg.pose.position.x-6)
            #self.obstacle2_msg.pose.position.y= random.uniform(-lw,lw)
            n = random.randint(0,self.xy.shape[0]-1)
            '''self.desired_point.x = self.xy[n,0]
            self.desired_point.y = self.xy[n,1]'''

            self.desired_point.x = 4.6
            self.desired_point.y = -4.8

            self.beta = 0
            #self.beta = 1
            print('beta: ',self.beta)

            '''ob_position=numpy.array([[6.94,-3.8],[5.55,0.41],[6.13,2.66],[3.21,3.98],[2.33,0.95],[1.57,0.11],[3.3,-2.1],[0.63,-4.26],[-0.21,-3.41]])
            while (abs(ob_position-numpy.array([self.desired_point.x,self.desired_point.y]))<2).any():
                self.desired_point.x = random.uniform(0,8)
                self.desired_point.y = random.uniform(-4.5,4.5)
                print("try new goal position")'''

        #self.time_start = time.localtime(time.time())
        self.time_start = time.time()
        #print('time_start: ',self.time_start[5])
        rospy.wait_for_service('gazebo/spawn_sdf_model')

        '''self.goal_position.position.x = self.desired_point.x
        self.goal_position.position.y = self.desired_point.y'''

        self.goal_position.position.x = 4.6
        self.goal_position.position.y = -4.8

        spawn_model_prox = rospy.ServiceProxy('gazebo/spawn_sdf_model', SpawnModel)
        spawn_model_prox("goal", self.sdff, "", self.goal_position, "world")
        #spawn_model_prox("obstacle1", self.obstacle, "", self.obstacle_position_1, "world")
        #spawn_model_prox("obstacle2", self.obstacle2, "", self.obstacle_position_2, "world")

    def deleteModel(self):
        rospy.wait_for_service('gazebo/delete_model')
        del_model_prox = rospy.ServiceProxy('gazebo/delete_model', DeleteModel)
        del_model_prox("goal")
        #del_model_prox("obstacle1")
        #del_model_prox("obstacle2")

    def moveto(self):
        rospy.wait_for_service('/gazebo/set_model_state')
        set_state = rospy.ServiceProxy('/gazebo/set_model_state', SetModelState)
        self.get_statemsg()
        set_state(self.state_msg )

    def get_statemsg(self):
        if self.success:
            n = random.randint(0,self.xy.shape[0]-1)
            self.state_msg.pose.position.x = self.xy[n,0]
            self.state_msg.pose.position.y = self.xy[n,1]
            goal_position=numpy.array([self.desired_point.x,self.desired_point.y])
            while numpy.linalg.norm(goal_position-numpy.array([self.state_msg.pose.position.x,self.state_msg.pose.position.y]))<5:
                n = random.randint(0,self.xy.shape[0]-1)
                self.state_msg.pose.position.x = self.xy[n,0]
                self.state_msg.pose.position.y = self.xy[n,1]
                print("try new robot position")

            #self.state_msg.pose.position.x = -0.7
            #self.state_msg.pose.position.y = 6.0

            D = random.uniform(0,360)
            r = R.from_euler('z', D, degrees=True)
            self.state_msg.pose.orientation.x, self.state_msg.pose.orientation.y, self.state_msg.pose.orientation.z, self.state_msg.pose.orientation.w = r.as_quat()

    def obstaclemoveto(self):
        ################### obstacle 1##############################################################################
        #self.obstacle1_msg.pose.orientation.x = 1
        rospy.wait_for_service('/gazebo/get_model_state')
        gms = rospy.ServiceProxy('/gazebo/get_model_state', GetModelState)
        resp1 = gms('obstacle1',"world")
        resp2 = gms('mobile_base',"world")
        position = numpy.array([resp1.pose.position.x,resp1.pose.position.y])
        position_m = numpy.array([resp2.pose.position.x,resp2.pose.position.y])
        self.obstacle1_msg.pose.position = resp1.pose.position
        if resp1.pose.position.x<=2 and resp1.twist.linear.x<=0:
            if position_m[1]>=0:
                g=3
            else:
                g=2
            if position_m[0]>=4:
                speed_value = 1.3
            else:
                speed_value = numpy.random.uniform(0.4,0.7)
            speed = speed_value*(self.A[g]-position)/numpy.linalg.norm((self.A[g]-position))
            self.obstacle1_msg.twist.linear.x = speed[0]
            self.obstacle1_msg.twist.linear.y = speed[1]
        elif resp1.pose.position.x>=10 and resp1.twist.linear.x>=0:
            if position_m[1]>=0:
                g=3
            else:
                g=2
            if position_m[0]<=4:
                speed_value = 1.3
            else:
                speed_value = numpy.random.uniform(0.4,0.7)
            speed = speed_value*(self.A[g]-position)/numpy.linalg.norm((self.A[g]-position))
            self.obstacle1_msg.twist.linear.x = speed[0]
            self.obstacle1_msg.twist.linear.y = speed[1]
        elif resp1.pose.position.y<=-4 and resp1.twist.linear.y<=0:
            if position_m[0]<=4:
                g=0
            else:
                g=1
            if position_m[1]>=0:
                speed_value = 1.3
            else:
                speed_value = numpy.random.uniform(0.4,0.7)
            speed = speed_value*(self.A[g]-position)/numpy.linalg.norm((self.A[g]-position))
            self.obstacle1_msg.twist.linear.x = speed[0]
            self.obstacle1_msg.twist.linear.y = speed[1]
        elif resp1.pose.position.y>=4 and resp1.twist.linear.y>=0:
            if position_m[0]<=4:
                g=0
            else:
                g=1
            if position_m[1]<=0:
                speed_value = 1.3
            else:
                speed_value = numpy.random.uniform(0.4,0.7)
            speed = speed_value*(self.A[g]-position)/numpy.linalg.norm((self.A[g]-position))
            self.obstacle1_msg.twist.linear.x = speed[0]
            self.obstacle1_msg.twist.linear.y = speed[1]
        #self.obstacle2_msg.pose.orientation.x = 1
        rospy.wait_for_service('/gazebo/set_model_state')
        set_state = rospy.ServiceProxy('/gazebo/set_model_state', SetModelState)
        set_state(self.obstacle1_msg)

    def goal_space(self):

        X = []
        Y = []

        X,Y = numpy.mgrid[8:9:0.1, -6:-0.2:0.1]                 # mesh for bottom left room
        self.xy = numpy.vstack((X.flatten(), Y.flatten())).T
        X = []
        Y = []

        X,Y = numpy.mgrid[4.1:7.3:0.1, -6:-4.7:0.1]                 # mesh for bottom left room
        self.xy = numpy.append(self.xy,numpy.vstack((X.flatten(), Y.flatten())).T, axis=0)
        X = []
        Y = []

        X,Y = numpy.mgrid[4.1:7.3:0.1, -2.5:0.4:0.1]                 # mesh for bottom left room
        self.xy = numpy.append(self.xy,numpy.vstack((X.flatten(), Y.flatten())).T, axis=0)
        X = []
        Y = []

        X,Y = numpy.mgrid[4.1:5.8:0.1, -4.2:-2.9:0.1]                 # mesh for bottom left room
        self.xy = numpy.append(self.xy,numpy.vstack((X.flatten(), Y.flatten())).T, axis=0)
        X = []
        Y = []

        X,Y = numpy.mgrid[3.7:6.1:0.1, 1.0:6.3:0.1]                 # mesh for middle room
        self.xy = numpy.append(self.xy,numpy.vstack((X.flatten(), Y.flatten())).T, axis=0)
        X = []
        Y = []

        X,Y = numpy.mgrid[8.1:9:0.1, 1.6:6.3:0.1]                 # mesh for bottom right room
        self.xy = numpy.append(self.xy,numpy.vstack((X.flatten(), Y.flatten())).T, axis=0)
        X = []
        Y = []

        X,Y = numpy.mgrid[-0.9:2.5:0.1, 4.2:6.3:0.1]                 # mesh for top right room
        self.xy = numpy.append(self.xy,numpy.vstack((X.flatten(), Y.flatten())).T, axis=0)
        X = []
        Y = []

        X,Y = numpy.mgrid[-0.9:2.8:0.1, -2.9:-0.3:0.1]                 # mesh for top left room
        self.xy = numpy.append(self.xy,numpy.vstack((X.flatten(), Y.flatten())).T, axis=0)
        X = []
        Y = []

        X,Y = numpy.mgrid[-0.3:1.4:0.1, 0.6:2.4:0.1]                 # mesh for top left room
        self.xy = numpy.append(self.xy,numpy.vstack((X.flatten(), Y.flatten())).T, axis=0)
        X = []
        Y = []

        X,Y = numpy.mgrid[0:2.8:0.1, -5.9:-4.6:0.1]                 # mesh for top left room
        self.xy = numpy.append(self.xy,numpy.vstack((X.flatten(), Y.flatten())).T, axis=0)

    '''def goal_space(self):
        X =[]
        Y =[]
        for i in numpy.arange(0,1.8,0.1):
            X11,Y11 = numpy.mgrid[i:i+0.1:0.1, -(4.13+2/3.5*i):-1.5:0.1]
            X12,Y12 = numpy.mgrid[i:i+0.1:0.1, 1.5:(4.13+2/3.5*i):0.1]
            X = numpy.hstack((X, X11.flatten(), X12.flatten()))
            Y = numpy.hstack((Y, Y11.flatten(), Y12.flatten()))

        X21,Y21 = numpy.mgrid[7.5:8.5:0.1, -5.5:-4.9:0.1]
        X22,Y22 = numpy.mgrid[7.5:8.5:0.1, -2:1.6:0.1]
        X23,Y23 = numpy.mgrid[7.5:8.5:0.1, 4.5:5.6:0.1]
        xy1 = numpy.vstack((X, Y)).T
        xy21 = numpy.vstack((X21.flatten(), Y21.flatten())).T
        xy22 = numpy.vstack((X22.flatten(), Y22.flatten())).T
        xy23 = numpy.vstack((X23.flatten(), Y23.flatten())).T
        self.xy=numpy.vstack((xy1,xy21,xy22,xy23))'''


# Main Python file to run our Website with graphics based on Inginious Database.
# Authors : Arys Simon, Alsteens Louis, El Ouilinti Aymen.

import page_creator
import data_base
from flask import Flask, render_template, url_for

app = Flask(__name__)

# ---------Les pages principales---------
@app.route('/')
def accueil():
    """Retourne le contenu de la page index.html."""
    return render_template('index.html')

@app.route('/selection_graphique')
def selection_graphique():
    """Retourne le contenu de la page graphique.html."""
    return render_template('selection_graphique.html')

@app.route('/auteurs')
def auteurs():
    """retourne le contenu de la page index.html"""
    return render_template('auteurs.html')

# -----Les pages de graphiques Chartjs------

# --------------------------------------------------------------------------
# -------------------------Resultats des soumissions------------------------
# --------------------------------------------------------------------------
@app.route('/graphiques_resultats/<cours>')
def graphique_resultats(cours):
    """Retourne une page affichant un graphique Chartjs des resultats des soumissions."""
    y = data_base.nbr_de_chaque_result(cours)
    x = ["%Timeout", "%Crash", "%Overflow", "%Killed", "%Success", "%Failed"]
    colors_resultats = """,
    backgroundColor: [
      "#ff0000",
      "#fff200",
      "#09ff00",
      "#00ffff",
      "#1500ff",
      "#f700ff"
    ],
    hoverBackgroundColor: [
      "#c20000",
      "#ebdf00",
      "#07cc00",
      "#00e3e3",
      "#1100cc",
      "#c800cf" ]"""
    return page_creator.html_page_creator(cours + " : Resultats des soumissions", x, y, 'pie', colors_resultats)

# --------------------------------------------------------------------------
# ----------------Nombre d'etudiants par essais moyens----------------------
# --------------------------------------------------------------------------
@app.route('/graphiques_essais/<cours>')
def graphique_essais(cours):
    """Retourne une page affichant un graphique Chartjs du nombre d'etudiants par nombre d essais moyens"""
    x_et_y = data_base.nbr_etudiants_nbr_essais_moyens(cours)
    colors_essais = """,
    backgroundColor: [
      "#1E90FF",
      "#1E90FF",
      "#1E90FF",
      "#1E90FF",
      "#1E90FF",
      "#1E90FF",
      "#1E90FF",
      "#1E90FF",
      "#1E90FF",
      "#1E90FF",
      "#1E90FF"
    ],
    hoverBackgroundColor: [
      "#0000ff",
      "#0000ff",
      "#0000ff",
      "#0000ff",
      "#0000ff",
      "#0000ff",
      "#0000ff",
      "#0000ff",
      "#0000ff",
      "#0000ff",
      "#0000ff" ]"""
    return page_creator.html_page_creator(cours + " : Nombre d etudiants(y) par nombre d essais moyens(x)", x_et_y[0],
                                          x_et_y[1], 'bar', colors_essais)

# ----------------------------------------------------
# ---------------Reussis / Rates----------------------
# ----------------------------------------------------
@app.route('/graphiques_reussis_rates/<cours>')
def graphique_reussis_rates(cours):
    """Retourne une page affichant un graphique Chartjs le pourcentage de reussites et d echecs"""
    x = ["%Soumissions reussies", "%Soumissions rates"]
    y = data_base.nbr_reussis_nbr_rates(cours)
    colors_reussis_rates = """,
    backgroundColor: [
      "#09ff00",
      "#ff0000"
    ],
    hoverBackgroundColor: [
      "#07cc00",
      "#c20000" ]"""
    return page_creator.html_page_creator(cours + " : Pourcentage de soumissions reussies ou rates", x, y, 'pie',
                                          colors_reussis_rates)

# ----------------------------------------------------
# --------------Soumissions par jour----------------------
# ----------------------------------------------------
@app.route('/graphiques_sub_per_day/<cours>')
def graphique_sub_per_day(cours):
    """Retourne une page affichant un graphique Chartjs le nombre de soumissions par jour"""
    res = data_base.nbr_submissions_per_day(cours)
    x = res[0]
    y = res[1]
    return page_creator.html_page_creator(cours + " : Nombre de soumissions par jour", x, y, 'line')

# ---------------------------------------------
# ------------Taux de reussite-----------------
# ---------------------------------------------
@app.route('/graphique_taux_de_reussite')
def graphique_taux_de_reussite():
    """Retourne une page affichant un graphique Chartjs de comparaison du taux de reussite entre les sinfs et les ingis."""
    x = ["Sinf", "Ingi"]
    y = data_base.taux_de_reussite()
    return page_creator.html_page_creator("%Taux de reussite", x, y, 'bar', colors_taux_de_reussite, options_taux)

colors_taux_de_reussite = """,
backgroundColor: [
  "#42baff",
  "#42baff"
],
hoverBackgroundColor: [
  "#39a0db",
  "#39a0db" ]"""

options_taux = """,
options: {
  scales: {
      yAxes: [{
      ticks: {
             min: 0,
             max: 100
          }
      }]
  }
}
"""

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


#!/usr/bin/env python3.5
#Author : Benika Hall
#Email : Benika.Hall@gmail.com

from urllib.request import *
import urllib.request, json, sys, requests
import pymongo

team_transition= "http://stats.nba.com/js/data/playtype/team_Transition.js"
team_isolation= "http://stats.nba.com/js/data/playtype/team_Isolation.js"
team_ball_handler = "http://stats.nba.com/js/data/playtype/team_PRBallHandler.js"
team_post_up = "http://stats.nba.com/js/data/playtype/team_Postup.js"
team_hand_off = "http://stats.nba.com/js/data/playtype/team_Handoff.js"
team_cut = "http://stats.nba.com/js/data/playtype/team_Cut.js"
team_putbacks = "http://stats.nba.com/js/data/playtype/team_OffRebound.js"
team_roll_man = "http://stats.nba.com/js/data/playtype/team_PRRollman.js"

transition = requests.post(team_transition)
f1 = open('team_transition.json','w')
f1.write(transition.text)
f1.close()
isolation = requests.post(team_isolation)
f2 = open('team_isolation.json','w')
f2.write(isolation.text)
f2.close()
ball_handler = requests.post(team_ball_handler)
f3 = open('team_ball_handler.json','w')
f3.write(ball_handler.text)
f3.close()
post_up = requests.post(team_post_up)
f4 = open('team_post_up.json','w')
f4.write(post_up.text)
f4.close()
cut = requests.post(team_cut)
f5 = open('team_cut.json','w')
f5.write(cut.text)
f5.close()
handoff = requests.post(team_hand_off)
f6 = open('team_handoff.json','w')
f6.write(handoff.text)
f6.close()
putbacks = requests.post(team_putbacks)
f7 = open('team_putbacks.json','w')
f7.write(putbacks.text)
f7.close()
roll_man = requests.post(team_roll_man)
f8 = open('team_roll_man.json','w')
f8.write(roll_man.text)
f8.close()


import sqlite3
import os

from api import Api

api = Api()

def setupBD():
	all_competitons = api.get_all_competitions()
	#setup_all_league(all_competitons)
	create_DB_for_all_league(all_competitons)

def create_DB_for_all_league(all_competitons):
	if not os.path.exists("database"):
		os.makedirs("database")

	for compet in all_competitons:
		createTable(compet)
		create_team_DB(compet)
		create_fixtures_DB(compet)

def create_fixtures_DB(compet):
	if not os.path.exists("database"):
		os.makedirs("database")
	if not os.path.exists("database/{}".format(compet.id)):
		os.makedirs("database/{}".format(compet.id))

	conn = sqlite3.connect("database/{}/fixtures.db".format(compet.id))
	c = conn.cursor()

	c.execute("CREATE TABLE IF NOT EXISTS league(date TEXT, homeTeamName TEXT, awayTeamName TEXT, homeScore REAL, awayScore REAL,homeTeamID REAL,awayTeamID REAL,matchday REAL,halftimeHomeScore REAL,halftimeAwayScore REAL)")

	fixtures = compet.get_fixture().fixtures
	for fix in fixtures:
		date              = fix.date
		homeTeamName      = fix.home_team["name"]
		awayTeamName      = fix.away_team["name"]
		homeScore         = fix.result["goalsHomeTeam"]
		awayScore         = fix.result["goalsAwayTeam"]
		homeTeamID        = fix.home_team["id"]
		awayTeamID        = fix.away_team["id"]
		matchday          = fix.matchday
		try:
			halftimeHomeScore = fix.result["halfTime"]["goalsHomeTeam"]
			halftimeAwayScore = fix.result["halfTime"]["goalsAwayTeam"]
		except Exception as e:
			pass
		c.execute("INSERT INTO league(date,homeTeamName,awayTeamName,homeScore,awayScore,homeTeamID,awayTeamID,matchday,halftimeHomeScore,halftimeAwayScore) VALUES (?,?,?,?,?,?,?,?,?,?)",
			(date,homeTeamName,awayTeamName,homeScore,awayScore,homeTeamID,awayTeamID,matchday,halftimeHomeScore,halftimeAwayScore))
	conn.commit()
	c.close()
	conn.close()

def create_team_DB(compet):
	if not os.path.exists("database"):
		os.makedirs("database")
	if not os.path.exists("database/{}".format(compet.id)):
		os.makedirs("database/{}".format(compet.id))

	conn = sqlite3.connect("database/{}/team.db".format(compet.id))
	c = conn.cursor()

	c.execute("CREATE TABLE IF NOT EXISTS league(team TEXT, id REAL)")
	try:
		teams = compet.get_teams()["teams"]
		for team in teams:
			name = team["name"]
			id = team["_links"]["self"]["href"][38:]
			c.execute("INSERT INTO league(team,id) VALUES (?,?)",(name,id))
	except:
		pass

	conn.commit()
	c.close()
	conn.close()

def createTable(compet):
	if not os.path.exists("database"):
		os.makedirs("database")
	if not os.path.exists("database/{}".format(compet.id)):
		os.makedirs("database/{}".format(compet.id))

	table = compet.get_table()
	try:
		table = table.team
		conn = sqlite3.connect("database/{}/table.db".format(compet.id))
		c = conn.cursor()
		c.execute("CREATE TABLE IF NOT EXISTS league(rank REAL , name TEXT , matchPlayed REAL , wins REAL ,draws REAL ,losses REAL)")
		for team in table:
			c.execute("INSERT INTO league(rank,name,matchPlayed,wins,draws,losses) VALUES (?,?,?,?,?,?)",
				(team["position"],team["teamName"],team["playedGames"],team["wins"],team["draws"],team["losses"]))
		conn.commit()
		c.close()
		conn.close()
	except:
		pass

def setup_all_league(all_competitons):
	if not os.path.exists("database"):
		os.makedirs("database")
	conn = sqlite3.connect('database/leagues.db')
	c = conn.cursor()
	c.execute("CREATE TABLE IF NOT EXISTS competition(name TEXT,symbol TEXT, numberOfMatchdays REAL,numberOfGames REAL,numberOfTeams REAL,id REAL)")
	for compet in all_competitons:
		c.execute("INSERT INTO competition(name,symbol,numberOfMatchdays,numberOfGames,numberOfTeams,id) VALUES(?,?,?,?,?,?)",
			(compet.name,compet.league,compet.numberOfMatchdays,compet.numberOfGames,compet.numberOfTeams,compet.id))

	conn.commit()
	c.close
	conn.close()

if __name__ == '__main__':
	setupBD()


#!/usr/bin/python3
import matplotlib.pyplot as plt
from prep_terrain_data import makeTerrainData
from class_vis import prettyPicture
from time import time
from sklearn.naive_bayes import GaussianNB
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import AdaBoostClassifier
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score

features_train, labels_train, features_test, labels_test = makeTerrainData()

### the training data (features_train, labels_train) have both "fast" and "slow"
### points mixed together--separate them so we can give them different colors
### in the scatterplot and identify them visually
grade_fast = [features_train[ii][0] for ii in range(0, len(features_train)) if labels_train[ii]==0]
bumpy_fast = [features_train[ii][1] for ii in range(0, len(features_train)) if labels_train[ii]==0]
grade_slow = [features_train[ii][0] for ii in range(0, len(features_train)) if labels_train[ii]==1]
bumpy_slow = [features_train[ii][1] for ii in range(0, len(features_train)) if labels_train[ii]==1]

#### initial visualization
plt.xlim(0.0, 1.0)
plt.ylim(0.0, 1.0)
plt.scatter(bumpy_fast, grade_fast, color = "b", label="fast")
plt.scatter(grade_slow, bumpy_slow, color = "r", label="slow")
plt.legend()
plt.xlabel("bumpiness")
plt.ylabel("grade")
plt.title("training dataset")
# plt.show()

def apply_classifier(clftype):
    print('Now running {:s} classifier'.format(clftype))
    clf = classifier[clftype]
    t0 = time()
    clf.fit(features_train, labels_train)
    t1 = time()
    # print('Training took {:0.2f} seconds'.format(t1-t0))
    pred = clf.predict(features_test)
    t2 = time()
    # print('Predicting took {:0.2f} seconds'.format(t2-t1))
    accu = accuracy_score(labels_test, pred)
    print('Accuracy is : {:0.4f}'.format(accu))

classifier = {'K-neighbors': KNeighborsClassifier(n_neighbors=20, algorithm='kd_tree', leaf_size=5),
              'Random_Forest': RandomForestClassifier(n_estimators=30),
              'Adaboost': AdaBoostClassifier(n_estimators=100),
              'GaussianNB': GaussianNB(),
              'SVM': SVC(C=60000),
              'Decision Tree': DecisionTreeClassifier()}

# Highest score so far is achieved with SVC(C=60000) (0.9520)
# Next best performer are KNneighbors and Adaboost

for key in classifier:
    apply_classifier(key)
    plt.figure()
    prettyPicture(classifier[key], features_test, labels_test)
    plt.title('Using {:s} classifier'.format(key))

# Prevent figure from closing by itself
plt.show(block=True)


# -*- coding: utf-8 -*-
from lettuce import step, world
from hamcrest import assert_that, has_item

@step(u'Given I have the following contacts:')
def given_i_have_the_following_contacts(step):
    world.contacts = []
    for contact in step.hashes:
        world.contacts.append((contact['title'],
                               contact['first name'],
                               contact['last name'],
                               contact['ship']))

@step(u'When I convert them to csv')
def when_i_convert_them_to_csv(step):
    world.csv = convert_to_csv(world.contacts)

@step(u'Then I get the following lines:')
def then_i_get_the_following_lines(step):
    for line in step.hashes:
        csv_line = line['line']
        assert_that(world.csv, has_item(csv_line))

def convert_to_csv(contacts):
    return [
        ','.join(
            '"%s"' % field.replace('"', '\\"')
            for field in fields
        ) for fields in contacts
    ]


from django.conf.urls.defaults import patterns, url
from views import *

urlpatterns = patterns('',

	url(r'^bayesiano/$', crear_bayesiano_view),
	url(r'^bayesiano/datos/$', datos_bayesiano_view),
	url(r'^bayesiano/solucion/$', solucion_bayesiano_view),

	url(r'^arbol/$', crear_arbol_view, name="crear_arbol"),
	url(r'^arbol/datos/$', datos_arbol_view, name="datos_arbol"),
	url(r'^arbol/solucion/$', solucion_arbol_view, name="solucion_arbol"),

	url(r'^acercade/([a-z_]+)/$', acerca_de_view),
)


def solution_conv():
    solution = np.array([[63, 63*3], [0,  63]]).astype(np.uint8)

    return solution

original = np.array([
                     [0, 252, 252],
                     [0,   0, 252],
                     [0,   0,   0]]).astype(np.uint8)
# region collapse
# w, h = 512, 512
# data = np.zeros((h, w, 3), dtype=np.uint8)
# data[0:256, 0:256] = [255, 0, 0] # red patch in upper left
# endregion

img_original = Image.fromarray(original, 'L')
plt.figure(figsize=(4, 4))
plt.imshow(img_original.resize((120,120), Image.NEAREST), cmap='gray')
plt.title("Original image")
plt.axis('off')

solution = solution_conv()
if solution.shape[0] > 1:
  img_solution = Image.fromarray(solution, 'L')
  plt.figure(figsize=(3, 3))
  plt.imshow(img_solution.resize((80, 80), Image.NEAREST), cmap='gray')
  plt.title("Convolution result")
  plt.axis('off')


from django.db.models import Q
from django.conf import settings

from experiments.models import Experiment
from labs.models import Lab

def menu_processor(request):
    """Return experiment and lab instances which is available for current user."""
    if request.resolver_match and 'lab_pk' in request.resolver_match.kwargs:
        lab_pk = request.resolver_match.kwargs['lab_pk']
        user = request.user
        lab = Lab.objects.get(pk=lab_pk)
        if not unicode(lab.id) == request.session.get('lab'):
            request.session['lab'] = unicode(lab.id)
        experiments = Experiment.objects.filter(lab=lab_pk, active=True)
        if lab.is_guest(user):
            experiments = experiments.filter(Q(owners=user) | Q(editors=user) | Q(viewers=user))
        return {'experiments_list': experiments,
                'lab': lab,
                'labs_list': Lab.objects.filter((Q(investigator=user) | Q(members=user) | Q(guests=user))).exclude(pk__in=[lab_pk])
                }
    return {}

def sidebar_processor(request):
    """
    Save state of a sidebar, collapsed or not.
    """
    if request.COOKIES.get('sidebarcollapse'):
        return {'SIDEBAR_COLLAPSED': True}
    return {}

def js_variables_processor(request):
    """
    Add variables which are used in js code
    """
    return {
        'DOMAIN': settings.DOMAIN,
        'DEBUG': settings.DEBUG,
    }


from django.shortcuts import render, loader, HttpResponse, HttpResponseRedirect
import random
from Usuario.models import Usuario
from Gestion_App.models import Jugador

# View principal, es la clasificacion de los usuarios.
def index(request):
    usuario = Usuario.objects.order_by('-puntuacion_Jugador')
    template = loader.get_template('Gestion_Clasificacion/clasificacion.html')
    context = {
        'usuario': usuario,
    }
    return HttpResponse(template.render(context, request))

# View que realiza la asignacion de puntos. Hay comprobacion de huecos vacios en la alineacion de los equipos de cada usuario.
def realizarJornada(request):
    listaJugadores = Jugador.objects.all()
    for i in listaJugadores:
        puntuacion = random.randint(0,12)
        i.puntos_Jugador = puntuacion
        i.save()

    listaUsuarios = Usuario.objects.all()
    contadora = 0
    for j in listaUsuarios:
        if j.portero is None:
            puntosPortero = 0
        else:
            puntosPortero = j.portero.puntos_Jugador
        if j.defensa1 is None:
            puntosDefensa1 = 0
        else:
            puntosDefensa1 = j.defensa1.puntos_Jugador
        if j.defensa2 is None:
            puntosDefensa2 = 0
        else:
            puntosDefensa2 = j.defensa2.puntos_Jugador
        if j.defensa3 is None:
            puntosDefensa3 = 0
        else:
            puntosDefensa3 = j.defensa3.puntos_Jugador
        if j.defensa4 is None:
            puntosDefensa4 = 0
        else:
            puntosDefensa4 = j.defensa4.puntos_Jugador
        if j.medio1 is None:
            puntosMedio1 = 0
        else:
            puntosMedio1 = j.medio1.puntos_Jugador
        if j.medio2 is None:
            puntosMedio2 = 0
        else:
            puntosMedio2 = j.medio2.puntos_Jugador
        if j.medio3 is None:
            puntosMedio3 = 0
        else:
            puntosMedio3 = j.medio3.puntos_Jugador
        if j.medio4 is None:
            puntosMedio4 = 0
        else:
            puntosMedio4 = j.medio4.puntos_Jugador
        if j.delantero1 is None:
            puntosDelantero1 = 0
        else:
            puntosDelantero1 = j.delantero1.puntos_Jugador
        if j.delantero2 is None:
            puntosDelantero2 = 0
        else:
            puntosDelantero2 = j.delantero2.puntos_Jugador

        contadora =  puntosPortero + puntosDefensa1 + puntosDefensa2 + puntosDefensa3 + puntosDefensa4 + puntosMedio1 + puntosMedio2 + puntosMedio3 + puntosMedio4 + puntosDelantero1 + puntosDelantero2
        j.puntuacion_Jugador = contadora
        j.save()
    return HttpResponseRedirect('/clasificacion/')


import geom
import random
from draw import random_RGB
from specs import *

class Eat:
    def __init__(self, circle, color):
        self.circle = circle
        self.color = color

def init():
    return [
        Eat(circle=geom.Circles(radius=1, pos_x=random.randint(0, FIELD_MAX_X), pos_y=random.randint(0, FIELD_MAX_Y)),
            color=random_RGB()) for i in range(NUMBER_EAT)]

def eats_food(users, foods):
    for i in users:
        for j in foods:
            if(geom.absorption_circles(i.circle[0], j.circle) == 2):
                i.circle[0].radius += j.circle.radius
                foods.remove(j)

def poop(Users, Eats, time):
    for i in Users:
        if i.circle[0].radius <= 10:
            i.time_eat = time
            continue
        if(time - i.time_eat) > TIME_POOP / i.circle[0].radius:
            i.time_eat = time
            i.circle[0].radius -= 1
            Eats.append(Eat(circle=geom.Circles(radius=1, pos_x=random.randint(0, FIELD_MAX_X), pos_y=random.randint(0, FIELD_MAX_Y)),
                color=random_RGB()))


import PIL, sys, os, glob
from PIL import Image
from sys import argv
from glob import glob

basewidth = 800

script, basewidth = argv
outputfile = ''

outputpath = os.getcwd() + '/Resized/'

os.makedirs(outputpath,exist_ok=True)

filetypes = glob('*.gif')
filetypes.extend(glob('*.png'))
filetypes.extend(glob('*.bmp'))
filetypes.extend(glob('*.jpg'))

for f in filetypes:
    if os.path.isdir(f):
        # skip directories
        continue

    outputfile = 'Resized/' + f
    if os.path.isfile(outputfile):
        continue
    else:
	    img = Image.open(f)
	    wpercent = (int(basewidth) / float(img.size[0]))
	    hsize = int((float(img.size[1]) * float(wpercent)))
	    img = img.resize((int(basewidth), hsize), PIL.Image.ANTIALIAS)
	    img.save(outputfile)


#! /usr/bin/env python3
import numpy as np

import analysis as an
import events
import network
import simulation
import toolkit

yield_world = network.World.load('config files/yield.yml')
yield_sim = simulation.Simulation.load('config files/yield-config.yml')
yield_sim.dbName = 'yield-data.db'
yield_analysis = an.Analysis(idx = 0, world=yield_world, seed=yield_sim.seed)
yield_analysis.interactions = []
#an.createAnalysisTable(sim.dbName)

seeds = [yield_sim.seed+i*yield_sim.increment for i in range(yield_sim.rep)]
yield_minTTCs = {1: [], 2: []}
yield_minDistances = {1: {}, 2: {}}
for categoryNum in yield_minDistances:
    for seed in seeds:
        yield_minDistances[categoryNum][seed] = []  #

yield_PETs = []
yield_interactions = []

yield_rearEndnInter10 = []
yield_rearEndnInter20 = []
yield_rearEndnInter50 = []

yield_sidenInter10 = []
yield_sidenInter20 = []
yield_sidenInter50 = []

# analysis.saveParametersToTable(sim.dbName)
for seed in seeds:
    print(str(seeds.index(seed)+1) + 'out of {}'.format(len(seeds)))
    yield_world = network.World.load('config files/yield.yml')
    yield_sim.seed = seed
    yield_sim.run(yield_world)
    yield_analysis.seed = seed
    yield_analysis.interactions.append(yield_world.completedInteractions)
    # analysis.saveIndicators(sim.dbName)
    for inter in yield_world.completedInteractions:
        if inter.categoryNum is not None:
            yield_distance = inter.getIndicator(events.Interaction.indicatorNames[2])
            if yield_distance is not None:
                yield_minDistances[inter.categoryNum][seed].append(yield_distance.getMostSevereValue(1))
            yield_ttc = inter.getIndicator(events.Interaction.indicatorNames[7])
            if yield_ttc is not None:
                yield_minTTC = yield_ttc.getMostSevereValue(1)*yield_sim.timeStep  # seconds
                if yield_minTTC < 0:
                    print(inter.num, inter.categoryNum, yield_ttc.values)
                if yield_minTTC < 20:
                    yield_minTTCs[inter.categoryNum].append(yield_minTTC)
                values = yield_ttc.getValues(False)
                if len(values) > 5:
                    yield_interactions.append(inter)
            if inter.getIndicator(events.Interaction.indicatorNames[10]) is not None:
                yield_PETs.append(inter.getIndicator(events.Interaction.indicatorNames[10]).getMostSevereValue(1))

    yield_rearEndnInter10.append((np.array(yield_minDistances[1][seed]) <= 10).sum())
    yield_rearEndnInter20.append((np.array(yield_minDistances[1][seed]) <= 20).sum())
    yield_rearEndnInter50.append((np.array(yield_minDistances[1][seed]) <= 50).sum())

    yield_sidenInter10.append((np.array(yield_minDistances[2][seed]) <= 10).sum())
    yield_sidenInter20.append((np.array(yield_minDistances[2][seed]) <= 20).sum())
    yield_sidenInter50.append((np.array(yield_minDistances[2][seed]) <= 50).sum())

yield_nInter10 = {1: np.mean(yield_rearEndnInter10), 2: np.mean(yield_sidenInter10)}
yield_nInter20 = {1: np.mean(yield_rearEndnInter20), 2: np.mean(yield_sidenInter20)}
yield_nInter50 = {1: np.mean(yield_rearEndnInter50), 2: np.mean(yield_sidenInter50)}

toolkit.callWhenDone()

yield_results = {'PETS': yield_PETs,
                'TTCs': yield_minTTCs,
                'side-nInter10': yield_sidenInter10,
                'side-nInter20': yield_sidenInter20,
                'side-nInter50': yield_sidenInter50,
                'rear-nInter10': yield_rearEndnInter10,
                'rear-nInter20': yield_rearEndnInter20,
                'rear-nInter50': yield_rearEndnInter50,
                'nInter10' : yield_nInter10,
                'nInter20': yield_nInter20,
                'nInter50': yield_nInter50,
                'minDistances': yield_minDistances,
                 }
toolkit.saveYaml('yield_results.yml', yield_results)


import re
import os.path

real_print = print
fake_print = lambda *a, **kw: None

#print = fake_print

token_re = re.compile(r'[{}]|"([^"]*?)"|[^\s]+')
def tokenize(vmt):
    def strip_comment(line):
        c = line.find("//")
        if c == -1: return line
        return line[:c]

    return [match.group(1) or match.group(0)
        for line in vmt.split("\n")
            for match in token_re.finditer(strip_comment(line))]

def expect(tokens, token, Skip=Exception):
    if tokens.pop(0) != token:
        print("expected", token)
        raise Skip()

def vmtread(desc, tokens, Skip=Exception):
    n = lambda: tokens.pop(0)

    def shader(func):
        shaders[func.__name__.replace("_", "").lower()] = func
        return func

    shaders = {}

    @shader
    def lightmapped_generic():
        generic(unlit=False)

    @shader
    def unlit_generic():
        generic(unlit=True)

    @shader
    def vertex_lit_generic():
        generic(unlit=False)

    def generic(unlit):
        expect(tokens, "{", Skip)

        while tokens:
            prop = n().lower()
            if prop == "}": return
            elif prop == "$basetexture":
                if unlit:
                    desc.glow_texture = n()
                else:
                    desc.base_texture = n()

            elif prop == "$translucent":
                desc.translucent = bool(n())
            elif prop == "$bumpmap":
                desc.normal_texture = n()
            elif prop == "$surfaceprop":
                desc.comment("surfaceprop = {}".format(n()))

            elif prop == "$envmap":
                envmap = n()
                if envmap != "env_cubemap":
                    print("envmap =", envmap)
                    desc.incomplete = True
                else:
                    desc.reflects_env = True
            elif prop == "$envmapmask":
                desc.specular_texture = n()
            elif prop == "$envmaptint":
                desc.specular_scale = n()
            elif prop == "$envmapcontrast":
                desc.specular_squaring = n() # basically ignored
            elif prop == "$envmapsaturation":
                desc.specular_saturation = n() # basically ignored

            elif prop == "$fullbright":
                desc.fullbright = bool(n())
            elif prop == "$no_fullbright":
                desc.fullbright = not bool(n())

            elif prop == "$normalmapalphaenvmapmask":
                desc.normalmapalphaenvmapmask = bool(n())

            elif prop == "$model":
                desc.model = bool(n())
            elif prop == "$decal":
                desc.decal = bool(n())
            elif prop == "$nodecal":
                desc.decal = not bool(n())
            elif prop in ("$decalscale", "$color", "$envmapcontrast", "$ignorez",
                    "$selfillum", "$selfillumtint",
                    "$nocull", "$nolod", "$nomip",
                    "$additive", "%keywords",
                    "$vertexalpha", "$vertexcolor"):
                desc.comment("{} = {}".format(prop, n()))
            else:
                print("Unknown property:", prop)
                desc.incomplete = True

    def unknown_shader():
        print("don't know", shader)
        desc.incomplete = True

    shader = n().lower()
    shaders.get(shader, unknown_shader)()


import datetime
from game.gamesrc.evemush.evescenesys.models import EveActors, EvePlots, EveScenes, EvePoses, EveSchedules
from game.gamesrc.evemush.command import EveCommand
from game.gamesrc.evemush.evelib import header, subheader, stringsecs, make_table, utcnow
import ev

class EveSceneCommand(EveCommand):
    locks = "cmd:all()"
    sysname = "SCENE"
    help_category = "Roleplay"

class CmdChannel(EveSceneCommand):
    """
    @channel - This replicates some features of PennMUSH's @channel command.

    Usage:
        @channel[/switch] <channel>[=<input>]

        Switches:
        on - turns on a channel, using +[first letter] or [<input>] as an alias.
        off - remove an alias to a channel. Removing all aliases removes the channel.
        list - show all channels.
        who - shows everyone subscribed to a channel.
        title - With no input, displays your title (Player's if @ooc, Char's if @ic)
                for the channel. =<input> sets it, but if <input> is blank, deletes.
        add - works exactly like @ccreate
        rename - renames a channel to <input>
        delete - works exactly like @cdestroy
        lock - works exactly like @cset
        mode - works exactly like @cmode with no switches.
    """
    key = "@channel"
    aliases = ["@chan"]

    def func(self):
        caller = self.caller
        switches = self.switches
        rhs = self.rhs
        lhs = self.lhs

        playswitches = ['list','who','on','off','title','recall','add','rename','delete','lock','mode']

        switches = self.partial(switches,playswitches)

        #Pick a switch, any switch! Or no switch.
        if 'add' in switches:
            self.switch_add()
        elif 'delete' in switches:
            self.switch_delete()
        elif 'lock' in switches:
            self.switch_lock(lhs, rhs)
        elif 'rename' in switches:
            self.switch_rename(lhs,rhs)
        elif 'mode' in switches:
            self.switch_mode(lhs, rhs)
        elif 'list' in switches:
            self.switch_list()
        elif 'who' in switches:
            self.switch_who()
        elif 'on' in switches:
            self.switch_on(lhs,rhs)
        elif 'off' in switches:
            self.switch_off()
        elif 'title' in switches:
            self.switch_title()
        elif 'recall' in switches:
            self.switch_recall(lhs, rhs)
        else:
            self.caller.msg("%s requires a switch. See help %s" % (self.key,self.key))

    def switch_on(self, lhs, rhs):
        if rhs:
            self.caller.execute_cmd("addcom %s=%s" % (rhs,lhs))
        else:
            self.caller.execute_cmd("addcom %s=%s" % ("+" + lhs[0].lower(),lhs))

    def switch_off(self):
        self.caller.execute_cmd("delcom %s" % self.args)

    def switch_title(self):
        self.caller.execute_cmd("@ctitle %s" % self.args)

    def switch_add(self, lhs, rhs):
        self.caller.execute_cmd("@ccreate %s" % self.args)

    def switch_delete(self):
        self.caller.execute_cmd("@cdestroy %s" % self.args)

    def switch_who(self):
        self.caller.execute_cmd("@cwho %s" % self.args)

    def switch_recall(self):
        self.caller.execute_cmd("@crecall %s" % self.args)

    def switch_list(self):
        self.caller.execute_cmd("@clist %s" % self.args)

    def switch_lock(self):
        self.caller.execute_cmd("@cset %s" % self.args)

    def switch_mode(self):
        self.caller.execute_cmd("@cmode %s" % self.args)

class CmdCRename(EveChannelCommand):
    """
    @crename - Rename a channel.

    Usage:
        @crename <channel>=<newname>

    You must control the channel for this to work.
    """
    key = "@crename"
    locks = "cmd:all()"

    def func(self):
        caller = self.caller
        switches = self.switches
        rhs = self.rhs
        lhs = self.lhs

        if not lhs:
            self.error("No channel entered to rename.")
            return
        channel = find_channel(self.player, lhs)
        if not channel:
            self.error("Channel '%s' not found." % lhs)
            return
        if not channel.access(self.player, "control"):
            self.error("You don't control this channel.")
            return
        if not rhs:
            self.error("You must enter a new name for the channel.")
            return
        channel2 = find_channel(self.caller,rhs)
        if len(channel2):
            self.error("A channel by that name already exists.")
            return
        self.sysmsg("Channel '%s' renamed to '%s'!" % (channel,rhs))
        channel.msg("Channel was Renamed to '%s' by %s" % (rhs,self.player.key))
        channel.db_key = rhs
        channel.save()

class CmdCTitle(EveChannelCommand):
    """
    @ctitle - set a channel title.

    Usage:
        @ctitle[/switch] <channel>[=<title>]

    Switches:
        clear - clears a chantitle for given channel.

    Used without a =, such as @ctitle Public, displays relevant title.

    """
    key = "@ctitle"
    locks = "cmd:all()"

    def func(self):
        caller = self.caller
        switches = self.switches
        rhs = self.rhs
        lhs = self.lhs
        playswitches = ['clear']
        admswitches = []
        isadmin = self.isadmin

        if isadmin:
            callswitches = playswitches + admswitches
        else:
            callswitches = playswitches
        switches = self.partial(switches,callswitches)

        if not lhs:
            self.error("No channel entered.")
            return
        channel = find_channel(self.player, lhs)
        if not channel:
            self.error("Channel '%s' not found." % lhs)
            return

        #This check is for clearing titles.
        if 'clear' in switches:
            self.sysmsg("Title for Channel %s cleared." % channel)
            channel.title_clear(self.player)
            return

        if not rhs:
            self.sysmsg("Title for Channel %s is: " % (channel, channel.title_get(self.player)))
            return

        self.sysmsg("Title for Channel %s set to: %s" % (channel, rhs))
        channel.title_set(self.player, rhs)

class CmdCMode(EveChannelCommand):
    """
    @cconfig - change a channel's display mode.

    Usage:
        @cconfig[/switch] <channel>=<mode>

        You must control the channel to change its mode. A switch is necessary.

    Switches:
        titles - Toggles whether titles are allowed. Needs no input.
        length = How many characters titles truncate at.
        color - sets color. Must use a single character.
    """
    key = "@cmode"
    locks = "cmd:all()"

    def func(self):
        caller = self.caller
        switches = self.switches
        rhs = self.rhs
        lhs = self.lhs
        playswitches = ['titles', 'length', 'color']
        admswitches = []
        isadmin = self.isadmin

        if isadmin:
            callswitches = playswitches + admswitches
        else:
            callswitches = playswitches
        switches = self.partial(switches,callswitches)

        if not lhs:
            self.error("No channel entered to configure.")
            return
        channel = find_channel(self.player, lhs)
        if not channel:
            self.error("Channel '%s' not found." % lhs)
            return
        if not channel.access(self.caller, "control"):
            self.error("You don't control this channel.")
            return

        if not switches:
            self.error("A switch is required for this command.")
            return

        if 'color' in switches:
            self.set_color(channel, rhs)
            return
        if 'titles' in switches:
            self.set_titles(channel, rhs)
            return
        if 'length' in switches:
            self.set_length(channel, rhs)
            return

    def set_color(self, channel, rhs=None):
        if not rhs:
            self.error("No color code entered.")
            return
        if len(rhs) > 1:
            self.error("Color mode must be a single character.")
            return
        self.sysmsg("Channel '%s' Color set to '%s'!" % (channel, rhs))
        channel.config_set('color', rhs)
        channel.msg("Channel Color was changed to '%s' by %s" % (rhs, self.player))

    def set_titles(self, channel):
        check = channel.config_get('titles')
        if check:
            channel.config_set('titles', False)
            string = "Titles were DISABLED by %s." % self.player
        else:
            channel.config_set('titles', True)
            string = "Titles were Enabled by %s." % self.player
        channel.msg(string)

    def set_length(self, channel, rhs=None):
        if not rhs:
            self.sysmsg("Length set to default.")
            channel.config_clear('length')
            string = "Title lengths were set to default by: %s" % self.player
        if not re.match(r'^\d+$', rhs):
            self.error("Length must be an integer.")
            return
        if not int(rhs) > 1:
            self.error("Length must be 1 or higher.")
            return
        channel.config_set('length', int(rhs))
        string = "Title lengths were set to %s by: %s" % (rhs, self.player)
        channel.msg(string)

class CmdCMuzzle(EveChannelCommand):
    """
    @cmuzzle - restrict a player from a channel for a length of time.

    Usage:
        @cmuzzle[/switch] <channel>=<player>/<duration>

    You must control the channel to muzzle or unmuzzle a player.

    If no <player> is defined, it will list all muzzles for this channel.

    <duration> must be a series of time values, such as: 5d 2h 6s
        (5 days, 2 hours, 6 seconds).
    Invalid input will be ignored. Order does not matter.

        s = second
        m = minute
        h = hour
        d = day
        w = week
        y = year
        (sorry, no months.)

    Switches:
        remove - Undoes an existing muzzle. Duration ignored.
    """
    key = "@cmuzzle"
    locks = "cmd:all()"

    def func(self):
        caller = self.caller
        switches = self.switches
        rhs = self.rhs
        lhs = self.lhs
        isadmin = self.isadmin
        playswitches = ['remove']
        admswitches = []

        if isadmin:
            callswitches = playswitches + admswitches
        else:
            callswitches = playswitches
        switches = self.partial(switches,callswitches)

        if not lhs:
            self.error("No channel entered.")
            return
        channel = find_channel(self.player, lhs)
        if not channel:
            self.error("Channel '%s' not found." % lhs)
            return
        if not channel.access(self.caller, "control"):
            self.error("You don't control this channel.")
            return

        if 'remove' in switches:
            self.chanmuzzle_remove(channel, rhs)
            return
        if not rhs:
            self.chanmuzzle_list(channel)
            return
        else:
            self.chanmuzzle_apply(channel, rhs)
            return

    def chanmuzzle_list(self, channel):
        muzzled = channel.dbobj.muzzles.filter(until__gt=utcnow())
        if not muzzled:
            self.error("No Muzzlings to show.")
            return
        message = []
        message.append(header("Muzzlings: %s" % channel))
        table = make_table('Name','Muzzled By','Muzzled Until', width=[20, 20, 40])
        for muzzle in muzzled:
            table.add_row(muzzle.pobj,muzzle.setby,muzzle.until.ctime())
        message.append(table)
        message.append(header())
        self.msg_lines(message)
        return

    def chanmuzzle_remove(self, channel, rhs):
        target = ev.search_player(rhs)
        if len(target):
            target = target[0]
        else:
            self.error("Player '%s' not found!" % rhs)
            return
        if not channel.muzzle_check(target):
            self.error("%s is not currently muzzled from %s." % (muzzle.pobj, channel))
        channel.muzzle_remove(target)
        self.sysmsg("%s may now speak on %s." % (target, channel))

    def chanmuzzle_apply(self, channel, rhs):
        if not len(rhs.split('/',1)) > 1:
            self.error("Must enter a duration!")
            return
        tname, durstring = rhs.split("/",1)
        target = ev.search_player(tname)
        if len(target):
            target = target[0]
        else:
            self.error("Player '%s' not found!" % rhs)
            return
        if not durstring:
            self.error("Must include a duration!")
            return
        duration = stringsecs(durstring)
        if not duration:
            self.error("Duration couldn't be calculated, please try again.")
            return
        channel.muzzle_apply(target, duration, self.player)
        until = utcnow() + datetime.timedelta(seconds=duration)
        self.sysmsg("You muzzle %s from %s." % (target, channel))
        self.sysmsg("You have been muzzled from %s by %s until %s" % (channel, self.player, until.ctime()),target)

class CmdChannels(EveChannelCommand):
    """
    list all channels available to you

    Usage:
      @channels
      @clist
      comlist

    Lists all channels available to you, whether you listen to them or not.
    Use 'comlist' to only view your current channel subscriptions.
    Use addcom/delcom to join and leave channels
    """
    key = "@channels"
    aliases = ["@clist", "channels", "comlist", "chanlist", "channellist", "all channels"]
    locks = "cmd: not pperm(channel_banned)"

    def func(self):
        "Implement function"

        caller = self.player

        # all channels we have available to listen to
        channels = [chan for chan in ChannelDB.objects.get_all_channels()
                    if chan.access(caller, 'listen')]
        #print channels
        if not channels:
            self.msg("No channels available.")
            return
        # all channel we are already subscribed to
        subs = ChannelDB.objects.get_subscriptions(caller)
        #print subs

        if self.cmdstring == "comlist":
            # just display the subscribed channels with no extra info
            message = []
            message.append(header("Subscribed Channels"))
            comtable = make_table("{wChannel{n", "{wMy Aliases{n", "{wDescription{n", width=[23, 15, 39])
            for chan in subs:
                clower = chan.key.lower()
                nicks = caller.nicks.get(category="channel")
                comtable.add_row(*["%s%s" % (chan.key, chan.aliases.all() and
                                  "(%s)" % ",".join(chan.aliases.all()) or ""),
                                  "%s".join(nick for nick in make_iter(nicks)
                                  if nick and nick.lower() == clower),
                                  chan.db.desc])
            message.append(comtable)
            message.append(subheader('{w@channels{n to list all, {waddcom{n/{wdelcom{n to sub/unsub)'))
            self.msg_lines(message)

        else:
            # full listing (of channels caller is able to listen to)
            message = []
            message.append(header("Available Channels"))
            comtable = make_table("{wSub{n", "{wChannel{n", "{wmy Aliases{n", "{wLocks{n", "{wDescription{n",width=[4,17,9,22,25])
            for chan in channels:
                clower = chan.key.lower()
                nicks = caller.nicks.get(category="channel")
                nicks = nicks or []
                comtable.add_row(*[chan in subs and "{gYes{n" or "{rNo{n",
                                  "%s%s" % (chan.key, chan.aliases.all() and
                                  "(%s)" % ",".join(chan.aliases.all()) or ""),
                                  "%s".join(nick for nick in make_iter(nicks)
                                  if nick.lower() == clower),
                                  str(chan.locks),
                                  chan.db.desc])
            message.append(comtable)
            message.append(subheader("use {wcomlist{n,{waddcom{n and {wdelcom{n to manage subscriptions"))
            self.msg_lines(message)


from django.urls import path

from .. import apis

app_name = 'members'
urlpatterns = [
    path('userlike/', apis.UserLikeCreateDestoryAPIView.as_view(), name='userlike'),
    path('skill/', apis.SkillListAPIView.as_view(), name='skill-list'),
    path('link/', apis.LinkListAPIView.as_view(), name='link-list'),
    path('applicant/profile/', apis.ApplicantUserUpdateAPIView.as_view(), name='profile'),
    path('applicant/<int:pk>/', apis.ApplicantUserRetrieveAPIView.as_view()),
    path('applicant/link/', apis.ApplicantLinkListUpdateAPIView.as_view(), name='applicantlink-list'),
    path('applicant/skill/', apis.ApplicantSkillListUpdateAPIView.as_view(), name='applicantskill-list'),
]


#!/usr/bin/env python3
import requests
import sys
import math
import time

ARTICLE_SEARCH_URL = 'https://api.nytimes.com/svc/search/v2/articlesearch.json'
LIMIT = 1000
EXTRACT_LIST = ['web_url', 'pub_date','snippet']

def get(api_key, section, count):
    params = {'api-key': api_key, 'fq': 'section_name:(\"{}\")'.format(section), 'sort':'newest'}
    data = []
    for i in range(math.ceil(count/10)):
        params['page'] = i
        r = requests.get(ARTICLE_SEARCH_URL, params)
        json = r.json()['response']['docs']
        data.extend(json)
        time.sleep(1)
    return data

def process(data, extract_list, section):
    processed_data = []
    for i in data:
        item = [section]
        for e in EXTRACT_LIST:
            item.append(i[e].replace('\t',' ').replace('\n',''))
        processed_data.append(item)
    return processed_data

def toString(data):
    result = []
    for i in data:
        result.append("\t".join(i))
    return '\n'.join(result)

def collect(api_key, sectionList, extractList, count):
    colNames = ['section'] + extractList
    result = [colNames]
    for section in sectionList:
        json = get(api_key, section, count)
        processed = process(json, extractList, section)
        result.extend(processed)
    return result

if __name__ == '__main__':
    if len(sys.argv) < 4:
        sys.stderr.write('usage: %s <api_key> <count> <section>...\n ' % sys.argv[0])
        sys.exit(1)
    api_key = sys.argv[1]
    count = int(sys.argv[2])
    sections = sys.argv[3:]

    result = collect(api_key, sections, EXTRACT_LIST, count)
    string = toString(result)
    with open('data.tsv','w') as tsv:
        tsv.write(string)


import re

def le_assinatura():
    '''A funcao le os valores dos tracos linguisticos do modelo e devolve uma assinatura a ser comparada com os textos fornecidos'''
    print("Bem-vindo ao detector automático de COH-PIAH.")
    print("Informe a assinatura típica de um aluno infectado:")

    wal = float(input("Entre o tamanho médio de palavra:"))
    ttr = float(input("Entre a relação Type-Token:"))
    hlr = float(input("Entre a Razão Hapax Legomana:"))
    sal = float(input("Entre o tamanho médio de sentença:"))
    sac = float(input("Entre a complexidade média da sentença:"))
    pal = float(input("Entre o tamanho medio de frase:"))
    return [wal, ttr, hlr, sal, sac, pal]

def le_textos():
    '''A funcao le todos os textos a serem comparados e devolve uma lista contendo cada texto como um elemento'''
    i = 1
    textos = []
    texto = input("Digite o texto " + str(i) +" (aperte enter para sair):")
    while texto:
        textos.append(texto)
        i += 1
        texto = input("Digite o texto " + str(i) +" (aperte enter para sair):")

    return textos

def separa_sentencas(texto):
    '''A funcao recebe um texto e devolve uma lista das sentencas dentro do texto'''
    sentencas = re.split(r'[.!?]+', texto)
    if sentencas[-1] == '':
        del sentencas[-1]
    return sentencas

def separa_frases(sentenca):
    '''A funcao recebe uma sentenca e devolve uma lista das frases dentro da sentenca'''
    return re.split(r'[,:;]+', sentenca)

def separa_palavras(frase):
    '''A funcao recebe uma frase e devolve uma lista das palavras dentro da frase'''
    return frase.split()

def n_palavras_unicas(lista_palavras):
    '''Essa funcao recebe uma lista de palavras e devolve o numero de palavras que aparecem uma unica vez'''
    freq = dict()
    unicas = 0
    for palavra in lista_palavras:
        p = palavra.lower()
        if p in freq:
            if freq[p] == 1:
                unicas -= 1
            freq[p] += 1
        else:
            freq[p] = 1
            unicas += 1

    return unicas

def n_palavras_diferentes(lista_palavras):
    '''Essa funcao recebe uma lista de palavras e devolve o numero de palavras diferentes utilizadas'''
    freq = dict()
    for palavra in lista_palavras:
        p = palavra.lower()
        if p in freq:
            freq[p] += 1
        else:
            freq[p] = 1

    return len(freq)

def compara_assinatura(as_a, as_b):
    '''IMPLEMENTAR. Essa funcao recebe duas assinaturas de texto e deve devolver o grau de similaridade nas assinaturas.'''
    i=0
    contador=0
    for i in range(len(as_a)):
        contador=(abs(as_a[i] - as_b[i]))+contador
        i=i+1
    return contador/6
    pass

def calcula_assinatura(texto):
    '''IMPLEMENTAR. Essa funcao recebe um texto e deve devolver a assinatura do texto.'''
    numero_sentencas=0
    numero_frases=0
    numero_palavras=0
    numero_caracteres=0
    numero_caracteres_sentenca=0
    numero_caracteres_frase=0
    relacao_type_token=0
    razao_hapax_legomana=0
    lista_palavras=[]
    lista_palavras2=[] #Lista de cada palavra separada
    lista_palavras3=[] #Lista de todas as palavras separadamente
    caracter=[]
    lista_caracter=[]
    lista_sentencas=separa_sentencas(texto)
    numero_sentencas=len(lista_sentencas)
    for sentenca in lista_sentencas:
        numero_caracteres_sentenca=numero_caracteres_sentenca + len(sentenca)
        lista_frases=separa_frases(sentenca)
        numero_frases=len(lista_frases)+numero_frases
        for frase in lista_frases:
            numero_caracteres_frase=numero_caracteres_frase + len(frase)
            lista_de_palavras=separa_palavras(frase)
            numero_palavras=len(lista_de_palavras)+numero_palavras # Até aqui tá certo, corrigir o restante
            for word in lista_de_palavras:
                lista_palavras2.append(word) # Lista com cada palavra separada
            for palavra in lista_de_palavras:
                lista_palavras3=palavra.split()
                for caracter in lista_palavras3:
                    y=0
                    while len(caracter)>y:
                        x=caracter[y]
                        y = y+1
                        lista_caracter.append(x)
    numero_caracteres=len(lista_caracter)

    numero_palavras_unicas=n_palavras_unicas(lista_palavras2) # Verifica dentro da lista de cada palavra separada
    numero_palavras_diferentes=n_palavras_diferentes(lista_palavras2) # Verifica dentro da lista de cada palavra separada

    tamanho_medio_palavras = numero_caracteres / numero_palavras # Funciona (5.571428571428571)
    relacao_type_token = numero_palavras_diferentes / numero_palavras # Funciona (0.8253968253968254)
    razao_hapax_legomana = numero_palavras_unicas / numero_palavras # Funciona (0.6984126984126984)
    tamanho_medio_sentenca = numero_caracteres_sentenca / numero_sentencas # Funciona (210.0)
    complexidade = numero_frases / numero_sentencas # Funciona (4.5)
    tamanho_medio_frase = numero_caracteres_frase / numero_frases # Funciona (45.888)

    return [tamanho_medio_palavras, relacao_type_token, razao_hapax_legomana, tamanho_medio_sentenca, complexidade, tamanho_medio_frase]

def avalia_textos(textos, ass_cp):
    '''IMPLEMENTAR. Essa funcao recebe uma lista de textos e uma assinatura ass_cp e deve devolver o numero (1 a n) do texto com maior probabilidade de ter sido infectado por COH-PIAH.'''
    assinaturas = []
    for te in textos:
        assinaturas.append(calcula_assinatura(te))

    grauSimilaridade = 1000.0
    similar = 1

    for i in range( 0, len(textos)):
        similaridade = compara_assinatura(ass_cp, assinaturas[i])
        #print(similaridade)
        if (similaridade < grauSimilaridade):
            grauSimilaridade = similaridade
            similar = i + 1
    return similar

def main():
    assinatura=le_assinatura()
    textos=le_textos()
    copia=avalia_textos(textos,assinatura)
    return print("O autor do texto",copia,"está infectado com COH-PIAH")

main()


class Person:
    def __init__(self, name, jobs, age=None): # class = data + logic
        self.name = name
        self.jobs = jobs
        self.age = age
    def info(self):
        return (self.name, self.jobs)
rec1 = Person('Bob', ['dev', 'mgr'], 40.5) # Construction calls
rec2 = Person('Sue', ['dev', 'cto'])

print(rec1.jobs)    # access the attribute
print(rec2.info())  # call the method