# 两个整数的汉明距离 指的是这两个数字的二进制数对应位不同的数量。
#
# 给你一个整数数组 nums，请你计算并返回 nums 中任意两个数之间 汉明距离的总和 。
from typing import List

class Solution:
    def totalHammingDistance(self, nums: List[int]) -> int:
        def hammingDistance(num1: int, num2: int) -> int:
            hd = num1 ^ num2
            count = 0
            while hd:
                hd = hd & (hd -1)
                count += 1

            return count

        sum = 0

        for i in range(len(nums)-1):
            for j in range(i+1, len(nums)):
                sum += hammingDistance(nums[i], nums[j])

        return sum

    # 逐位统计
    # 考虑同一比特位上的值是否不同
    # 对于数组nums中的某个元素val，若其二进制的第i位为1
    # 只需要统计nums中有多少元素的第i位为0，即计算出了val与其他元素在第i位上的汉明距离之和
    # 若长度为n的数组nums的所有元素二进制位的第i位共有c个1，n-c个0，
    # 则这些元素在二进制的第i位上的汉明距离之和为c*(n-c)
    # 可以从二进制的最低位到最高位，逐步统计汉明距离，将每一位上得到的汉明距离累加即为答案
    def totalHammingDistance(self, nums: List[int]) -> int:
        n = len(nums)
        ans = 0
        for i in range(30):
            c = sum(((val >> i) & 1) for val in nums)
            ans += c * (n -c)

        return ans

a = Solution().totalHammingDistance([4, 14, 4])
print(a)


import logging
import os
import sys
from collections import Counter
from typing import Iterable

import tensorflow as tf
from tensorflow.keras import backend as K

def learning_rate_scheduler(num_epochs, max_learning_rate, min_learninga_rate=1e-7):
    lr_delta = (max_learning_rate - min_learninga_rate) / num_epochs

    def _scheduler(epoch, lr):
        return max_learning_rate - lr_delta * epoch

    return _scheduler

def get_logger():
    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)
    handler = logging.StreamHandler(sys.stdout)
    handler.setFormatter(logging.Formatter("[%(asctime)s] %(message)s"))
    logger.addHandler(handler)
    return logger

def path_join(*paths: Iterable[str]) -> str:
    """ Join paths to string local paths and google storage paths also """
    if paths[0].startswith("gs://"):
        return "/".join([path.strip("/") for path in paths])
    return os.path.join(*paths)

def get_device_strategy(device) -> tf.distribute.Strategy:
    """ Return tensorflow device strategy """
    # Use TPU
    if device.upper() == "TPU":
        resolver = tf.distribute.cluster_resolver.TPUClusterResolver(tpu=os.environ["TPU_NAME"])
        tf.config.experimental_connect_to_cluster(resolver)
        tf.tpu.experimental.initialize_tpu_system(resolver)
        strategy = tf.distribute.TPUStrategy(resolver)

        return strategy

    # Use GPU
    if device.upper() == "GPU":
        devices = tf.config.list_physical_devices("GPU")
        if len(devices) == 0:
            raise RuntimeError("Cannot find GPU!")
        for device in devices:
            tf.config.experimental.set_memory_growth(device, True)
        if len(devices) > 1:
            strategy = tf.distribute.MirroredStrategy()
        else:
            strategy = tf.distribute.OneDeviceStrategy("/gpu:0")

        return strategy

    # Use CPU
    return tf.distribute.OneDeviceStrategy("/cpu:0")

def n_gram_precision(true_tokens, pred_tokens, n):
    true_n_grams = []
    pred_n_grams = []

    for i in range(len(true_tokens) - n + 1):
        true_n_grams.append(tuple(true_tokens[i : i + n]))
    for i in range(len(pred_tokens) - n + 1):
        pred_n_grams.append(tuple(pred_tokens[i : i + n]))

    true_n_gram_counter = Counter(true_n_grams)
    pred_n_gram_counter = Counter(pred_n_grams)

    correct = 0
    for true_n_gram in true_n_gram_counter:
        correct += min(pred_n_gram_counter[true_n_gram], true_n_gram_counter[true_n_gram])
    return correct / len(true_n_grams)

def calculat_bleu_score(true_tokens, pred_tokens):
    n_gram_score = 1.0
    for n in range(1, 5):
        n_gram_score *= n_gram_precision(true_tokens, pred_tokens, n)
    n_gram_score **= 0.25

    brevity_penalty = min(1.0, len(pred_tokens) / len(true_tokens))

    return n_gram_score * brevity_penalty


"""A Raibert style controller for Minitaur."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import math
import attr
import gin
import numpy as np

from pybullet_envs.minitaur.agents.baseline_controller import minitaur_raibert_controller_utils
from pybullet_envs.minitaur.envs.utilities import minitaur_pose_utils

LEFT_FRONT_LEG_ID = 0
LEFT_HIND_LEG_ID = 1
RIGHT_FRONT_LEG_ID = 2
RIGHT_HIND_LEG_ID = 3

DIAGONAL_LEG_PAIR_1 = (LEFT_FRONT_LEG_ID, RIGHT_HIND_LEG_ID)
DIAGONAL_LEG_PAIR_2 = (LEFT_HIND_LEG_ID, RIGHT_FRONT_LEG_ID)

LEFT_LEG_IDS = (LEFT_FRONT_LEG_ID, LEFT_HIND_LEG_ID)
RIGHT_LEG_IDS = (RIGHT_FRONT_LEG_ID, RIGHT_HIND_LEG_ID)

# The max horizontal foot offset (in meters) for turning.
_FOOT_HORIZONTAL_OFFSET_FOR_TURNING = 0.1

_STANCE_TG_PHASE_COMPRESSION = 1.5
_STANCE_TG_DELTA_EXTENSION = 0.2
_STANCE_HORIZONTAL_SCALING_FACTOR = 1.2

_DEFAULT_SWING_SPEED_GAIN = 0.015

_DEFAULT_SWING_FOOT_CLEARANCE = 0.005

_PITCH_SWING_FEEDBACK_SCALING_FACTOR = 1.2

# A POD container to describe the controller's high level behavior.
@attr.s
class BehaviorParameters(object):
  """Highlevel parameters for Raibert style controller."""
  stance_duration = attr.ib(type=float, default=0.25)
  desired_forward_speed = attr.ib(type=float, default=0.)
  desired_turning_speed = attr.ib(type=float, default=0.)
  standing_height = attr.ib(type=float, default=0.2)
  desired_incline_angle = attr.ib(type=float, default=0.)

def generate_default_swing_trajectory(phase, init_pose, end_pose):
  """A swing trajectory generator.

  Args:
    phase: Float. Between [0, 1].
    init_pose: A tuple. The leg pose (swing, extension) at phase == 0 the
      beginning of swing.
    end_pose: A tuple. The leg pose at phase == 1 the end of swing.

  Returns:
    The desired leg pose for the current phase.
  """
  # Try phase compression
  normalized_phase = math.sqrt(min(phase * 1.5, 1))

  # For swing, we use a linear interpolation:
  swing = (end_pose[0] - init_pose[0]) * normalized_phase + init_pose[0]

  # For extension, we can fit a second order polynomial:
  min_ext = (init_pose[1] + end_pose[1]) / 2 - 0.8
  min_ext = max(min_ext, 0.5)

  # The phase value at which the extension reaches the minimal value min_ext.
  # phi is small, the swing leg will try to lift higher in the first half of
  # swing.
  phi = 0.1

  # We convert the extension back into the cartesion space. In this way we can
  # guarantee a lift-up trajectory. The ankle to hip distance is easier to
  # compute than a full forward-kinematics.
  min_ankle_dist = minitaur_raibert_controller_utils.extension_to_ankle_dist(
      min_ext)
  init_ankle_dist = minitaur_raibert_controller_utils.extension_to_ankle_dist(
      init_pose[1])
  end_ankle_dist = minitaur_raibert_controller_utils.extension_to_ankle_dist(
      end_pose[1])

  # The polynomial is: a * phi^2 + b * phi + c
  delta_1 = min_ankle_dist - init_ankle_dist
  delta_2 = end_ankle_dist - init_ankle_dist
  delta_p = phi * phi - phi

  a = (delta_1 - phi * delta_2) / delta_p

  b = (phi * phi * delta_2 - delta_1) / delta_p

  ankle_dist = (
      a * normalized_phase * normalized_phase + b * normalized_phase +
      init_ankle_dist)

  l1 = minitaur_raibert_controller_utils.UPPER_LEG_LEN
  l2 = minitaur_raibert_controller_utils.LOWER_SHORT_LEG_LEN

  ankle_dist = min(max(ankle_dist, l2 - l1 + 0.01), l2 + l1 - 0.01)

  extension = minitaur_raibert_controller_utils.ankle_dist_to_extension(
      ankle_dist)

  return (swing, extension)

@gin.configurable
def generate_default_stance_trajectory(phase,
                                       init_pose,
                                       end_pose,
                                       use_constant_extension=False):
  """A stance strajectory generator.

  Args:
    phase: Float. Between [0, 1].
    init_pose: A tuple. The leg pose (swing, extension) at phase == 0, i.e. the
      beginning of stance.
    end_pose: A tuple. The leg pose at phase == 1, i.e. the end of stance.
    use_constant_extension: Boolean. Whether or not to fix the extension during
      stance.

  Returns:
    The desired leg pose for the current phase.
  """
  normalized_phase = min(_STANCE_TG_PHASE_COMPRESSION * math.sqrt(phase), 1)
  swing = (end_pose[0] - init_pose[0]) * normalized_phase + init_pose[0]

  # The extension evolves nonlinearly according to the parabola equation.
  if use_constant_extension:
    extension = end_pose[1]
  else:
    extension = end_pose[1] - 4 * _STANCE_TG_DELTA_EXTENSION * (
        normalized_phase**2 - normalized_phase)
  return (swing, extension)

def get_stance_foot_offset_for_turning(leg_id, steering_signal):
  """Modify the stance foot position to achieve turning.

  The strategy works for trotting gaits.

  Args:
    leg_id: Integer. The leg index.
    steering_signal: Float. The desired turning signal in [-1, 1]. Because we
      don't have an accurate mapping from angular velocity to the foot offset,
      the steering signal should be treated as a reference and only its relative
      magnitude matters.

  Returns:
    The stance foot's horizontal offset.

  """
  clipped_steering_signal = np.clip(steering_signal, -1, 1)

  if leg_id in LEFT_LEG_IDS:
    return _FOOT_HORIZONTAL_OFFSET_FOR_TURNING * clipped_steering_signal
  else:
    return -(_FOOT_HORIZONTAL_OFFSET_FOR_TURNING * clipped_steering_signal)

def get_leg_swing_offset_for_pitching(body_pitch, desired_incline_angle):
  """Get the leg swing zero point when the body is tilted.

  For example, when climbing up or down stairs/slopes, the robot body will tilt
  up or down. By compensating the body pitch, the leg's trajectory will be
  centered around the vertical direction (not perpendicular to the surface).
  This helps the robot to generate thrust when going upwards, and braking when
  going downwards.

  Args:
    body_pitch: Float. Current body pitch angle.
    desired_incline_angle: Float. The desired body pitch angle.

  Returns:
    The stance and swing leg swing offset.

  """
  kp = 0.2
  return -((1 - kp) * body_pitch + kp * desired_incline_angle)

@gin.configurable
class RaibertSwingLegController(object):
  """The swing leg controller."""

  def __init__(self,
               speed_gain=_DEFAULT_SWING_SPEED_GAIN,
               foot_clearance=_DEFAULT_SWING_FOOT_CLEARANCE,
               leg_trajectory_generator=generate_default_swing_trajectory):
    """Initializes the controller.

    Args:
      speed_gain: Float. The speed feedback gain to modulate the target foot
        position.
      foot_clearance: Float. The foot clearance (at the end of the swing phase)
        in meters.
      leg_trajectory_generator: A trajectory generator function.
    """
    self._speed_gain = speed_gain
    self._foot_clearance = foot_clearance
    self._leg_trajectory_generator = leg_trajectory_generator

  def get_action(self, raibert_controller):
    """Get the swing legs' desired pose."""
    current_speed = raibert_controller.estimate_base_velocity()
    phase = raibert_controller.get_phase()
    rpy = raibert_controller.robot.base_roll_pitch_yaw

    leg_pose_set = {}
    for i in raibert_controller.swing_set:
      # Target foot horizontal position is calculated according to Raibert's
      # original formula in "Legged robots that balance".
      target_foot_horizontal_position = (
          raibert_controller.behavior_parameters.stance_duration / 2 *
          current_speed + self._speed_gain *
          (current_speed -
           raibert_controller.behavior_parameters.desired_forward_speed))

      # 1) Convert the target foot position to leg pose space.
      # Lift the foot a little bit.
      target_foot_vertical_position = -(
          raibert_controller.behavior_parameters.standing_height -
          self._foot_clearance)
      target_foot_position = (target_foot_horizontal_position,
                              target_foot_vertical_position)
      target_leg_pose = minitaur_raibert_controller_utils.foot_position_to_leg_pose(
          target_foot_position)

      # 2) Generates the curve from the swing start leg pose to the target leg
      # pose and find the next leg pose on the curve based on current swing
      # phase.

      desired_leg_pose = self._leg_trajectory_generator(
          phase, raibert_controller.swing_start_leg_pose, target_leg_pose)

      swing_offset = get_leg_swing_offset_for_pitching(
          rpy[1], raibert_controller.behavior_parameters.desired_incline_angle)

      leg_pose_set[i] = (desired_leg_pose[0] + swing_offset,
                         desired_leg_pose[1])

    return leg_pose_set

@gin.configurable
class RaibertStanceLegController(object):
  """The controller that modulates the behavior of the stance legs."""

  def __init__(self,
               speed_gain=0.1,
               leg_trajectory_generator=generate_default_stance_trajectory):
    """Initializes the controller.

    Args:
      speed_gain: Float. The speed feedback gain to modulate the target stance
        foot position.
      leg_trajectory_generator: A trajectory generator function. Generates the
        desired leg pose during the stance phase.
    """
    self._speed_gain = speed_gain
    self._leg_trajectory_generator = leg_trajectory_generator

  def get_action(self, raibert_controller):
    """Get the desired leg pose for the stance legs."""

    phase = raibert_controller.get_phase()
    current_speed = raibert_controller.estimate_base_velocity()
    rpy = raibert_controller.robot.base_roll_pitch_yaw

    leg_pose_set = {}
    for i in raibert_controller.stance_set:
      desired_forward_speed = (
          raibert_controller.behavior_parameters.desired_forward_speed)

      target_foot_horizontal_position = -_STANCE_HORIZONTAL_SCALING_FACTOR * (
          raibert_controller.behavior_parameters.stance_duration / 2 *
          current_speed - self._speed_gain *
          (current_speed - desired_forward_speed))

      target_foot_horizontal_position += get_stance_foot_offset_for_turning(
          i, raibert_controller.behavior_parameters.desired_turning_speed)

      target_foot_position = (
          target_foot_horizontal_position,
          -raibert_controller.behavior_parameters.standing_height)
      target_leg_pose = minitaur_raibert_controller_utils.foot_position_to_leg_pose(
          target_foot_position)

      desired_leg_pose = (
          self._leg_trajectory_generator(
              phase, raibert_controller.stance_start_leg_pose, target_leg_pose))

      swing_offset = _PITCH_SWING_FEEDBACK_SCALING_FACTOR * get_leg_swing_offset_for_pitching(
          rpy[1], raibert_controller.behavior_parameters.desired_incline_angle)

      leg_pose_set[i] = (desired_leg_pose[0] + swing_offset,
                         desired_leg_pose[1])

    return leg_pose_set

@gin.configurable
class MinitaurRaibertController(object):
  """A Raibert style controller for trotting gait."""

  def __init__(self,
               robot,
               behavior_parameters=BehaviorParameters(),
               swing_leg_controller=RaibertSwingLegController(),
               stance_leg_controller=RaibertStanceLegController(),
               pose_feedback_controller=None):
    self._time = 0
    self._robot = robot
    self.behavior_parameters = behavior_parameters

    self._last_recorded_speed = 0

    self._swing_leg_controller = swing_leg_controller
    self._stance_leg_controller = stance_leg_controller
    self._pose_feeback_controller = pose_feedback_controller

    # The leg order is FL, RL, FR, RR -> [0, 1, 2, 3]
    self._swing_set = DIAGONAL_LEG_PAIR_1
    self._stance_set = DIAGONAL_LEG_PAIR_2

    # Compute the initial leg pose.
    self._swing_start_leg_pose = self.get_swing_leg_pose()
    self._stance_start_leg_pose = self.get_stance_leg_pose()

  @property
  def robot(self):
    return self._robot

  @property
  def swing_set(self):
    return self._swing_set

  @property
  def stance_set(self):
    return self._stance_set

  @property
  def swing_start_leg_pose(self):
    return self._swing_start_leg_pose

  @property
  def stance_start_leg_pose(self):
    return self._stance_start_leg_pose

  def _get_average_leg_pose(self, leg_indices):
    """Get the average leg pose."""
    current_leg_pose = minitaur_pose_utils.motor_angles_to_leg_pose(
        self._robot.motor_angles)

    # extract the swing leg pose from the current_leg_pose
    leg_pose = []
    for index in leg_indices:
      leg_pose.append([
          current_leg_pose[index],
          current_leg_pose[index + minitaur_pose_utils.NUM_LEGS]
      ])

    leg_pose = np.array(leg_pose)
    return np.mean(leg_pose, axis=0)

  def get_swing_leg_pose(self):
    """Get the current swing legs' average pose."""
    return self._get_average_leg_pose(self._swing_set)

  def get_stance_leg_pose(self):
    """Get the current stance legs' average pose."""
    return self._get_average_leg_pose(self._stance_set)

  def get_phase(self):
    """Compute the current stance/swing phase."""
    return math.fmod(self._time, self.behavior_parameters.stance_duration
                    ) / self.behavior_parameters.stance_duration

  def _get_new_swing_stance_set(self):
    """Switch the set of swing/stance legs based on timing."""
    swing_stance_phase = math.fmod(self._time,
                                   2 * self.behavior_parameters.stance_duration)
    if swing_stance_phase < self.behavior_parameters.stance_duration:
      return (DIAGONAL_LEG_PAIR_1, DIAGONAL_LEG_PAIR_2)
    return (DIAGONAL_LEG_PAIR_2, DIAGONAL_LEG_PAIR_1)

  def update(self, t):
    """Update the internal status of the controller.

    Args:
      t: Float. The current time after reset in seconds.
    """
    self._time = t
    new_swing_set, new_stance_set = self._get_new_swing_stance_set()

    # If there is a stance/swing switch.
    if new_swing_set[0] is not self._swing_set[0]:
      self._swing_set = new_swing_set
      self._stance_set = new_stance_set

      # Also records the starting pose.
      self._swing_start_leg_pose = self.get_swing_leg_pose()
      self._stance_start_leg_pose = self.get_stance_leg_pose()

  def estimate_base_velocity(self):
    """Estimate the current CoM speed."""
    # It is best to use a sensor fusion approach.
    stance_leg_pose = self.get_stance_leg_pose()

    delta_sw = stance_leg_pose[0] - self._stance_start_leg_pose[0]

    x, y = minitaur_raibert_controller_utils.leg_pose_to_foot_position(
        stance_leg_pose)
    toe_hip_len = math.sqrt(x**2 + y**2)
    horizontal_dist = toe_hip_len * delta_sw
    phase = self.get_phase()
    speed = self._last_recorded_speed
    if phase > 0.1:
      speed = horizontal_dist / (
          self.behavior_parameters.stance_duration * phase)
      self._last_recorded_speed = speed
    return speed

  def get_swing_leg_action(self):
    return self._swing_leg_controller.get_action(self)

  def get_stance_leg_action(self):
    return self._stance_leg_controller.get_action(self)

  def get_action(self):
    """Gets the desired motor angles."""
    leg_pose = [0] * minitaur_pose_utils.NUM_MOTORS
    swing_leg_pose = self.get_swing_leg_action()
    for i in self._swing_set:
      leg_pose[i] = swing_leg_pose[i][0]
      leg_pose[i + minitaur_pose_utils.NUM_LEGS] = swing_leg_pose[i][1]

    stance_leg_pose = self.get_stance_leg_action()
    for i in self._stance_set:
      leg_pose[i] = stance_leg_pose[i][0]
      leg_pose[i + minitaur_pose_utils.NUM_LEGS] = stance_leg_pose[i][1]

    return minitaur_pose_utils.leg_pose_to_motor_angles(leg_pose)


import os
import sys
import json
import click
from pathlib import Path

sys.path.append(Path(__file__).parent.parent.parent.parent.__str__())
from mdls.gerdoolib import get_description, get_version, msg_out

PIF = Path(Path(__file__).parent, 'home.json')

def goto_home(where_opt: bool= False) -> str|None:
    """
    This function does the main work of the 'home' program.
    The task of this function is to change the working directory to the home directory.

    :param where_opt: It means that the (-w, --where) option is selected.
    :return: str|None
    """

    path_file_path: Path = Path(Path(__file__).parent.parent.parent.parent, 'setg', 'PATH.json')

    if path_file_path.exists() and len(path_file_path.read_text()) > 0:
        with open(path_file_path, 'r') as path:
            try:
                home_path = json.load(path)['home']

                if where_opt:
                    if isinstance(home_path, str):
                        return home_path

                os.chdir(home_path)

            except KeyError:
                msg_out(nature='error', message='Error: PATH file is broken!')

            except json.JSONDecodeError:
                msg_out(nature='error', message='Error: PATH file is broken!')

            except FileNotFoundError:
                msg_out(nature='error', message=f'Error: The home path does not exist -> ({home_path})')

            except NotADirectoryError:
                msg_out(nature='error', message=f'Error: The home path is not a directory path -> ({home_path})')
    else:
        msg_out(nature='error', message=f'Error: The PATH file does not exist: \n{path_file_path}')

def home(command: list) -> None:
    """
    This function is the bridge between the kernel and the task and interface of this program.

    :param command: User command in the form of a list.
    :return: None
    """

    sys.argv = command

    try:
        main()
    except SystemExit:
        pass

@click.command(help=get_description(PIF))
@click.option("--version", is_flag=True, help='Show the version of this program.')
@click.option("-w", "--where", is_flag=True, help='The home directory path will be displayed.')
def main(version, where):
    if version:
        get_version(PIF)
    elif where:
        response = goto_home(where_opt=True)
        if isinstance(response, str):
            msg_out(nature='standard', message=response)
    else:
        goto_home()


"""This is a template for State Machine Modules

   A State Machine module is a python file that contains a  `loop` function.
   Similar to how an Arduino program operates, `loop` is called continuously:
   when the function terminates, it is called again.

   The `loop` function should continuously listens to messages generated by:
   - the path detector (concerning the path to follow),
   - the sign detector (concerning road signs detected, if any),
   - the remote command operator (concerning commands to start/stop driving,
     or do specific manoeuvers)
   - and the arduino controller of the physical car (concerning the current
     state; possible sensor readings, ...)

   and decide on how to drive the car correspondingly. See the description of
   the `loop` method below for more details.

   This simplistic State Machine responds to remote commands "GO", "STOP"
   and "TEST_COMM". In addition, it listens to path information from the
   Simplistic Path detector, and sends actuation commands that are
   compatible with the simulator.
"""

import logging
import time
from event import Event
from car import Car
import socket

server = socket.socket()
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
logging.info(socket.gethostbyname(socket.gethostname()))
HOST = ''
POST = 5555
address = (HOST, POST)
server.bind(address)
server.listen(1)
address = 0
conn = 0
def loop():
  global address
  global conn
  logging.info('hello world !!!!!!')
  if address == 0 :
    logging.info('listening for connnection...')
    conn, address = server.accept()
    logging.info('connection received | i know da wae ')
  else :
    logging.info('dis is da wae')
    data = conn.recv(1024)
    command = data.decode()
    logging.info(command)
    if command == 'a' :
      logging.info('right')
      Car.send(0, 0, 2., 55.)
    elif command == 'd' :
      logging.info("left")
      Car.send(0, 0, 2., -55.)
    elif command == 'w' :
      Car.send(0, 0, 2., 0.)
    elif command == 's' :
      Car.send(0, 0, -2., 0.)
    else :
      Car.send(0, 0, 0, 0)


#from ConfigGenerator import ConfigGenerator
from GameRunner_v4 import GameRunner
#from FitnessPlot_v2 import FitnessPlot

#import glob
#from pathlib import Path

#import time

runner = GameRunner(
    num_threads=16,
    show_game=False,
    level_end_score=3186,
    convolution_weight=8,
    config_file_name='config_generated',
    worker_start_num=0,
    #max_generation=1,
    data_folder='data_v4_test'
)

#runner.run_all_threads()

# ======================================================================
# Test the model DURING training
#runner.show_top_n(1)
# ======================================================================

# ======================================================================
# Test the model AFTER training

pth = 'complete_models/winner31.pkl'
runner.play(completed_model_path=pth)
runner.play()

# ======================================================================

# ======================================================================
# This was used to generate the config used for this test
'''
from ConfigGenerator import ConfigGenerator

config = ConfigGenerator(
    filename='config_generated',
    fitness_criterion='max',
    fitness_threshold=100000,
    pop_size=20,
    reset_on_extinction=False,
    activation_default="sigmoid",
    activation_mutate_rate=0.0,
    activation_options="sigmoid",
    aggregation_default="sum",
    aggregation_mutate_rate=0.0,
    aggregation_options="sum",
    bias_init_mean=0.0,
    bias_init_stdev=1.0,
    bias_max_value=30.0,
    bias_min_value=-30.0,
    bias_mutate_power=0.5,
    bias_mutate_rate=0.7,
    bias_replace_rate=0.1,
    compatibility_disjoint_coefficient=1.0,
    compatibility_weight_coefficient=0.5,
    conn_add_prob=0.5,
    conn_delete_prob=0.5,
    enabled_default=True,
    enabled_mutate_rate=0.01,
    feed_forward=True,
    initial_connection="full",
    node_add_prob=0.2,
    node_delete_prob=0.2,
    num_hidden=0,
    num_inputs=840,
    num_outputs=9,
    response_init_mean=1.0,
    response_init_stdev=0.0,
    response_max_value=30.0,
    response_min_value=-30.0,
    response_mutate_power=0.0,
    response_mutate_rate=0.0,
    response_replace_rate=0.0,
    weight_init_mean=0.0,
    weight_init_stdev=1.0,
    weight_max_value=30,
    weight_min_value=-30,
    weight_mutate_power=0.5,
    weight_mutate_rate=0.8,
    weight_replace_rate=0.1,
    compatibility_threshold=3.0,
    species_fitness_func="max",
    max_stagnation=20,
    species_elitism=2,
    elitism=2,
    survival_threshold=0.2
)
#config_params = config.randomize()

#Copy the file N times
config.write_all_configs(0, 1)
'''
# ======================================================================


import re
from collections import defaultdict, namedtuple
from typing import List, Set
from pathlib import Path

INPUT_FILE = Path(__file__).with_suffix(".input")

RE_NUMS = re.compile(r"-?\d+")

Coord = namedtuple("Coord", ["x", "y", "z", "t"])

def parse_input(instructions: str) -> List[Coord]:
    points = []
    for line in instructions.strip().split("\n"):
        points.append(Coord(*list(map(int, RE_NUMS.findall(line)))))
    return points

def calc_distance(loc1: Coord, loc2: Coord) -> int:
    return abs(loc1.x - loc2.x) + abs(loc1.y - loc2.y) + abs(loc1.z - loc2.z) + abs(loc1.t - loc2.t)

def part_1(list_o_stars: List[Coord]) -> List[Set[Coord]]:
    stars_within_range = defaultdict(set)
    for i, star1 in enumerate(list_o_stars):
        for star2 in list_o_stars[i + 1 :]:
            if calc_distance(star1, star2) <= 3:
                stars_within_range[star1].add(star2)

    constellations = []
    for star in list_o_stars:
        star_set = stars_within_range[star]
        star_set.add(star)

        found_constellations = []
        for i, const in enumerate(constellations):
            for neighbor_star in star_set:
                if neighbor_star in const:
                    found_constellations.append(i)
                    break
        if not found_constellations:
            found_const = set()
            constellations.append(found_const)
        else:
            first, *rest = found_constellations
            rest.sort(reverse=True)
            found_const = constellations[first]
            for i in rest:
                found_const |= constellations[i]
                del constellations[i]
        found_const |= star_set

    return constellations

if __name__ == "__main__":
    DATA = INPUT_FILE.read_text().strip()
    print(len(part_1(parse_input(DATA))))


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2022/6/20 21:59
# @Author : HongShaoRou
# @Site :
# @File : demo_breakdown.py
# @Software: PyCharm

# 断点设置及调试

i =1
while i <= 10:
    print(i)
    i += 1


import os
from pathlib import Path
from SourceCode.linkedlist import Node, LinkedList

def get_file_names(path_name):
    return os.listdir(path_name)

def read_files(path_name) -> dict:

    data_sets = {}

    file_names = get_file_names(path_name)

    for file in file_names:
        name = file.split('.')[0]
        data_sets[name] = {}
        with Path(path_name+file).open('r') as opened_file:
            data_sets[name]['length'] = opened_file.readline().split()[0]
            data_sets[name]['order'] = opened_file.readline().split()[0]
            data_sets[name]['list'] = []
            data_sets[name]['sorts'] = {}
            while True:
                try:
                    number = opened_file.readline().split()[0]
                    data_sets[name]['list'].append(int(number))
                except:
                    break

        head = Node(data_sets[name]['list'][0])
        linked_list = LinkedList()
        linked_list.head = head

        for number in data_sets[name]['list'][1:]:
            linked_list.add(number)

        data_sets[name]['linked_list'] = linked_list

    return data_sets

if __name__ == "__main__":
    data_sets = read_files('../Input/')
    print(data_sets['random_50'])


from manim import *

class EDScene(Scene):

    def construct(self):
        title = Tex("Introducción a modelos más complejos")
        title.scale(1.4)

        self.play(
            Write(title)
        )

        self.wait(2)

        self.play(
            title.animate.to_edge(UP).scale(1/1.4)
        )

        l = BulletedList("Propagación por imitación, no por herencia", "\\[x_i\'=x_i\\sum_{j=1}^p [f_{ij}(\\vec{x})-f_{ji}(\\vec{x})]x_j\\]", "$f$ lineales es la ecuación del replicador", "Caso muy general: $x_i\'=x_ig_i(\\vec{x}),g_i \\in \\mathcal{C}^1,\\sum_{i=1}^p x_i g_i(\\vec{x})=0 $", "Las dinámicas {\\itshape payoff monotonic } tienen propiedades\\\\de equilibrio similares al replicador").shift(DOWN*0.5)

        self.play(
            Write(l[0]),Write(l[1])
        )
        self.wait(10)
        self.play(Write(l[2]))
        self.wait(10)
        self.play(Write(l[3]))
        self.wait(20)
        self.play(Write(l[4]))
        self.wait(20)
        self.play(
            *[ FadeOut(mob) for mob in self.mobjects ]
        )


import pandas as pd
import torch
import time
import numpy as np
from gensim.models.word2vec import Word2Vec
from torch.autograd import Variable
from sklearn import metrics
from sklearn.model_selection import train_test_split

import warnings
warnings.filterwarnings('ignore')

from model import MethodNN
from util import *

def get_result_1():
    train_data = pd.read_pickle('parsed_source.pkl').sample(frac=1)
    word2vec = Word2Vec.load("word2vec_node_64").wv
    train_data, val_data = train_test_split(train_data, test_size=0.20, random_state=42)

    MAX_TOKENS = word2vec.syn0.shape[0]
    EMBEDDING_DIM = word2vec.syn0.shape[1]
    embeddings = np.zeros((MAX_TOKENS + 1, EMBEDDING_DIM), dtype="float32")
    embeddings[:word2vec.syn0.shape[0]] = word2vec.syn0

    ENCODE_DIM = 64
    HIDDEN_DIM = 32
    LABELS = 1
    BATCH_SIZE = 13
    USE_GPU = False

    model = MethodNN(EMBEDDING_DIM,HIDDEN_DIM,MAX_TOKENS+1,ENCODE_DIM,LABELS,BATCH_SIZE,USE_GPU, embeddings)
    parameters = model.parameters()
    optimizer = torch.optim.Adamax(parameters)
    loss_function = torch.nn.BCELoss()

    best_val_loss = float("inf")
    epochs = 20
    best_model = None
    best_epoch = -1

    def train():
        total_loss = 0.
        permutation = torch.randperm(len(train_data))
        for i in range(0, len(train_data), BATCH_SIZE):
            idx = permutation[i:i+BATCH_SIZE]
            batch_x = train_data['method_seq'].to_numpy()[idx]
            batch_y = train_data['b_label'].to_numpy()[idx]
            optimizer.zero_grad()
            model.batch_size = len(batch_y)
            model.hidden = model.init_hidden()
            output = model(batch_x)
            loss = loss_function(output[0], Variable(torch.FloatTensor(batch_y)))
            loss.backward()
            torch.nn.utils.clip_grad_norm_(model.parameters(), 0.5)
            optimizer.step()
            total_loss += loss.item()
        return total_loss

    def evaluate(eval_model, data):
        total_loss = 0.
        start_time = time.time()
        permutation = torch.randperm(len(data))

        y_pred = []
        y_true = []
        with torch.no_grad():
            for i in range(0, len(data), BATCH_SIZE):
                idx = permutation[i:i+BATCH_SIZE]
                batch_x = data['method_seq'].to_numpy()[idx]
                batch_y = data['b_label'].to_numpy()[idx]
                model.batch_size = len(batch_y)
                model.hidden = model.init_hidden()
                output = model(batch_x)
                loss = loss_function(output[0], Variable(torch.FloatTensor(batch_y)))
                total_loss += loss
                y_pred.extend(output[0].reshape(-1,))
                y_true.extend(batch_y.reshape(-1,))
        return total_loss, y_pred, y_true

    for epoch in range(1, epochs + 1):
        epoch_start_time = time.time()
        train_loss = train()
        val_loss,_,_ = evaluate(model, val_data)
        # print('| end of epoch {:3d} | time: {:5.2f}s | train loss {:5.2f}| valid loss {:5.2f}'.format(epoch, (time.time() - epoch_start_time),train_loss, val_loss))

        if val_loss < best_val_loss:
            best_val_loss = val_loss
            best_model = model
            best_epoch = epoch

    #print("best_epoch", best_epoch)

    test_data = pd.read_pickle('parsed_source_test.pkl').sample(frac=1)
    #print("TESTING")
    test_loss, y_pred, y_true = evaluate(best_model, test_data)

    precision, recall, thresholds = metrics.precision_recall_curve(y_true, y_pred)
    fscore = (2 * precision * recall) / (precision + recall+10**-10)
    ix = np.argmax(fscore)
    y_pred_class = [x>thresholds[ix] for x in y_pred]

    precision, recall, AUC = metrics.precision_score(y_true, y_pred_class), \
                             metrics.recall_score(y_true, y_pred_class),\
                             metrics.roc_auc_score(y_true, y_pred)

    return precision, recall, fscore[ix], AUC

def get_result(add1, add2):
    precision_list = []
    recall_list = []
    AUC_list = []
    fscore_list = []

    for i in range(5):
        precision, recall, fscore, AUC = get_result_1()
        #print(precision, recall, fscore, AUC)
        precision_list.append(precision)
        recall_list.append(recall)
        fscore_list.append(fscore)
        AUC_list.append(AUC)

    print("Train:%s, Test:%s" %(add1.split("/")[-1], add2.split("/")[-1]))
    print("Precision=%0.3f, Recall=%0.3f, F-Score=%.3f, AUC=%0.3f\n" % (np.mean(precision_list), \
                                                                        np.mean(recall), \
                                                                        np.mean(fscore_list),\
                                                                        np.mean(AUC_list)))

# CAMEL
address1 = "../../Dataset/AST/camel/camel-1.2.csv"
address2 = "../../Dataset/AST/camel/camel-1.4.csv"
address3 = "../../Dataset/AST/camel/camel-1.6.csv"
get_data(address1, address2)
get_result(address1, address2)
get_data(address2, address3)
get_result(address2, address3)

# # Jedit
# address1 = "../../Dataset/AST/jedit/jedit-3.2.csv"
# address2 = "../../Dataset/AST/jedit/jedit-4.0.csv"
# address3 = "../../Dataset/AST/jedit/jedit-4.1.csv"
# # get_data(address1, address2)
# # get_result(address1, address2)
# # get_data(address2, address3)
# get_result(address2, address3)

# # Log4j
# address1 = "../../Dataset/AST/log4j/log4j-1.0.csv"
# address2 = "../../Dataset/AST/log4j/log4j-1.1.csv"
# get_data(address1, address2)
# get_result(address1, address2)

# # lucene
# address1 = "../../Dataset/AST/lucene/lucene-2.0.csv"
# address2 = "../../Dataset/AST/lucene/lucene-2.2.csv"
# address3 = "../../Dataset/AST/lucene/lucene-2.4.csv"
# get_data(address1, address2)
# get_result(address1, address2)
# get_data(address2, address3)
# get_result(address2, address3)

# # xalan
# address1 = "../../Dataset/AST/xalan/xalan-2.4.csv"
# address2 = "../../Dataset/AST/xalan/xalan-2.5.csv"
# address3 = "../../Dataset/AST/xalan/xalan-2.6.csv"
# get_data(address1, address2)
# get_result(address1, address2)
# get_data(address2, address3)
# get_result(address2, address3)

# # synapse
# address1 = "../../Dataset/AST/synapse/synapse-1.0.csv"
# address2 = "../../Dataset/AST/synapse/synapse-1.1.csv"
# address3 = "../../Dataset/AST/synapse/synapse-1.2.csv"
# get_data(address1, address2)
# get_result(address1, address2)
# get_data(address2, address3)
# get_result(address2, address3)

# # xerces
# address1 = "../../Dataset/AST/xerces/xerces-1.2.csv"
# address2 = "../../Dataset/AST/xerces/xerces-1.3.csv"
# address3 = "../../Dataset/AST/xerces/xerces-1.4.csv"
# # get_data(address1, address2)
# get_result(address1, address2)
# get_data(address2, address3)
# get_result(address2, address3)


import numpy as np
import pandas as pd
from sklearn.metrics import precision_recall_fscore_support

def collect_labels(file_address):
    '''
    Collects predicted/actual labels from file at file address.
    Returns list of labels for each text.
    '''
    with open(file_address) as f:
        content = f.readlines()
    labels = [c.split(' ')[0] for c in content]
    return labels

def score_labels(test_labels, predict_labels, label_set):
    '''
    Prints and returns mean scores of lists of labels.
    IN:
    test_labels - list of actual labels
    predict_labels - list of predicted labels
    label_set - set of labels to be tallied in evaluation
    OUT: scores from evaluation by SkLearn
    '''
    precision, recall, fscore, support = precision_recall_fscore_support(test_labels, predict_labels, average=None, labels=label_set)

    print('precision: {}'.format(precision.mean()))
    print('recall: {}'.format(recall.mean()))
    print('fscore: {}'.format(fscore.mean()))
#     print('support: {}'.format(support))

    return precision, recall, fscore, support

def score_txtfiles(test_address, predict_address):
    '''
    IN:
    test_address - test file
    pred_address - file of predictions
    label_set - set of labels to be tallied in evaluation
    OUT: scores from evaluation by SkLearn
    '''
    test_labels = collect_labels(test_address)
    predict_labels = collect_labels(predict_address)
    label_set = sorted(list(set(test_labels)))

    precision, recall, fscore, support = score_labels(test_labels, predict_labels, label_set)

    return precision, recall, fscore, support

def score_columns(df, test_column, predict_column):
    '''
    IN:
    df - dataframe of labels and predictions
    test_column - column name of actual labels
    predict_column - column name of predicted labels
    label_set - set of labels to be tallied in evaluation
    OUT: scores from evaluation by SkLearn
    '''
    test_labels = df[test_column]
    predict_labels = df[predict_column]
    label_set = sorted(list(set(test_labels)))

    precision, recall, fscore, support = score_labels(test_labels, predict_labels, label_set)

    return precision, recall, fscore, support


'''
Problem Solving Programmers winter_coding_3
Author: Injun Son
Date: October 31, 2020
'''
import math
from collections import deque
from itertools import combinations

def print_board(board):
    for i in range(len(board)):
        for j in range(len(board[0])):
            print(board[i][j], end=" ")
        print()
    print()

def solution(v):
    answer = [0, 0, 0]
    graph = v
    # print_board(graph)
    visited = [[-1]*len(graph[0]) for _ in range(len(graph))]

    dx = [-1, 0, 0, 1]
    dy = [0, 1, -1, 0]

    def bfs(y, x):
        visited[y][x] = graph[y][x]
        queue = deque()
        queue.append([y, x, graph[y][x]])

        while queue:
            y, x, food = queue.popleft()
            for i in range(4):
                ny, nx = y+dy[i], x+dx[i]
                if 0<=ny<len(graph) and 0<=nx<len(graph[0]) and food == graph[ny][nx] and visited[ny][nx]==-1:
                    visited[ny][nx] = food
                    queue.append([ny, nx, food])

    for i in range(len(graph)):
        for j in range(len(graph[0])):
            if visited[i][j]==-1:
                answer[graph[i][j]]+=1
                bfs(i, j)
    return answer

print(solution([[0,0,1,1],[1,1,1,1],[2,2,2,1],[0,0,0,2]]))
print(solution([[0,0,1],[2,2,1],[0,0,0]]))


"""
Initialization of private process resource concepts; by private we mean not sharable resources:
internal process state, vm info, page map
"""

import resource_handles
from crloader import crdata
from pstree import ProcessTreeConcept
from resource_concepts import ProcessInternalsConcept

def init_internal_state_resources(process_tree, application):
    """
    :type process_tree: ProcessTreeConcept
    :type application: crdata.Application
    """
    raw_processes = application.processes

    for p in raw_processes:
        process_concept = process_tree.proc_by_pid(p.pid)

        page_map = ProcessInternalsConcept(p.page_map)
        vm_info = ProcessInternalsConcept(p.vm_info)
        fs_props = ProcessInternalsConcept(p.fs)
        process_core = ProcessInternalsConcept(p.core)
        thread_cores = [ProcessInternalsConcept(t_core) for t_core in p.thread_cores]

        process_concept.add_final_resource(page_map, resource_handles.NO_HANDLE)
        process_concept.add_final_resource(vm_info, resource_handles.NO_HANDLE)
        process_concept.add_final_resource(fs_props, resource_handles.NO_HANDLE)
        process_concept.add_final_resource(process_core, resource_handles.NO_HANDLE)
        for thread_core in thread_cores:
            process_concept.add_final_resource(thread_core, resource_handles.NO_HANDLE)


from django.db import models
from apps.vendor.models import Vendor
from apps.application.models import Application

from .config import RESPONSE_TYPE_CHOICES
from config import settings

class AdminAction():
    pub_date = models.DateTimeField('date published')
    pub_by = models.CharField(max_length=180)
    modified_date = models.DateTimeField('date modified')
    modified_by = models.CharField(max_length=180)

class Question(AdminAction, models.Model):
    application = models.ForeignKey(Application, blank=True, null=True)
    question_text = models.TextField()
    is_first_question = models.BooleanField(
        default=False,
        help_text="Designates if the question is the first question in the decision tree")
    category = models.PositiveIntegerField(
        default=1, choices=RESPONSE_TYPE_CHOICES , help_text=('type of response to be stored'))
    next_default_question = models.ForeignKey("self", blank=True, null=True)
    is_active = models.BooleanField(
        default=False, help_text='Designates whether a question is active or not')

    def __str__(self):
        return self.question_text

    #note this carefully
    @property
    def response_data(self):
        fields_to_fetch = ['response_text','comment','response_image_url','response_url','send_user_info']
        all_further_responses = QuesRespRelation.objects.filter(question_id=self.id)
        d = []
        for response in all_further_responses:
            res = Response.objects.get(id=response.response_id)
            di = {key:getattr(res,key,"") for key in fields_to_fetch}
            di.update({'question_next':response.question_next_id})
            di.update({'response_id':response.response_id})
            d.append(di)
        return d

class Response(AdminAction, models.Model):
    application = models.ForeignKey(Application, blank=True, null=True)
    response_text = models.TextField()
    comment = models.TextField(blank=True, null=True, help_text ='used to show comment per response if available')
    response_image = models.ImageField(upload_to='images/', blank=True, null=True)
    response_url = models.URLField(max_length=300, blank=True, null=True)
    is_active = models.BooleanField(
        default=False, help_text='Designates whether a resposne is active or not')
    send_user_info = models.BooleanField(
        default=False, help_text='Designates whether the response_message sends request to vendor or not')

    @property
    def response_image_url(self):
        if self.response_image.name:
            return self.response_image.url
        return None

    def __str__(self):
        return self.response_text

class QuesRespRelation(AdminAction, models.Model):
    application = models.ForeignKey(Application, blank=True, null=True)
    question = models.ForeignKey(Question, blank=True, null=True)
    response = models.ForeignKey(
        Response, related_name='quesresprelation', blank=True, null=True)
    question_next = models.ForeignKey(
        Question, related_name='questionnextrelation', blank=True, null=True)
    is_active = models.BooleanField(
        default=False, help_text='Designates whether a question resposne relation is active or not')

    def __str__(self):
        return "When '" + self.question.question_text + "' is responded by '" + self.response.response_text + "'"


from setuptools import setup, find_packages
from codecs import open
from os import path
here = path.abspath(path.dirname(__file__))

with open(path.join(here, 'README.md'), encoding='utf-8') as f:
    long_description = f.read()

setup(
    name='messagemedia_lookups_sdk',
    version='1.0.0',
    description='The MessageMedia Lookups API provides a number of endpoints for validating the phone numbers you’re sending to by checking their validity, type and carrier records.',
    long_description=long_description,
    author='MessageMedia Developers',
    author_email='developers@messagemedia.com',
    url='https://developers.messagemedia.com',
    packages=find_packages(),
    install_requires=[
        'requests>=2.9.1, <3.0',
        'jsonpickle>=0.7.1, <1.0',
        'cachecontrol>=0.11.7, <1.0',
        'python-dateutil>=2.5.3, <3.0'
    ],
    tests_require=[
        'nose>=1.3.7'
    ],
    test_suite = 'nose.collector'
)


# Hero boilerplate object
class Hero:
    def __init__(self, name, hp, mp, pattk, mattk, pdef, mdef, eva, skill, alive):
        self.name = name
        self.hp = hp                # hit points
        self.mp = mp                # magic points
        self.pattk = pattk          # physical attack
        self.mattk = mattk          # magic attack
        self.pdef = pdef            # physical defense
        self.mdef = mdef            # magic defense
        self.eva = eva              # evasion
        self.skill = skill          # special skill/ability
        self.alive = alive          # bool/is the hero above 0 HP

# Basic heroes

# // stat ranges //
# check to prevent values from exceeding/dropping below mix/max
# how do stats scale up, how do chars level up
'''
    HP: 200 - 500                   # factor of 2.5
    MP: 10 - 50                     # factor of 5
    Physical attack: 10 - 50        # factor of 5
    Magic attack: 10 - 50           # factor of 5
    Physical defense: 10 - 50       # factor of 5
    Magic defense: 5 - 25           # factor of 5
    Evasion: 5 - 25                 # factor of 5
'''

hero_warrior = Hero("Warrior", 350, 10, 30, 10, 50, 10, 10, "Blade Rush", True)
'''
    Blade Rush: three-fold attack with chance of critical hits (multiple targets)
'''

hero_monk = Hero("Monk", 500, 20, 35, 30, 40, 15, 25, "Focus", True)
'''
    Focus: doubles attack and ensures next attack is 100% accurate
'''

hero_blackmage = Hero("Black Mage", 200, 50, 10, 50, 10, 20, 15, "Fireball", True)
'''
    Fireball: a flaming sphere that has the chance to burn for an additional turn"
'''

hero_lancer = Hero("Lancer", 265, 15, 50, 15, 25, 10, 20, "Lunge", True)
'''
    Lunge: a low accuracy attack that causes critical damage
'''

hero_whitemage = Hero("White Mage", 250, 40, 15, 35, 20, 25, 15, "Cure", True)
'''
    Cure: recovers HP for an ally
'''


from collections import defaultdict
from math import sqrt
from typing import Any, Callable, Dict, List, Optional, Tuple

import numpy as np

from trajdata.caching import SceneCache
from trajdata.data_structures.agent import AgentMetadata, AgentType
from trajdata.data_structures.scene import SceneTime, SceneTimeAgent
from trajdata.data_structures.state import StateArray
from trajdata.maps import MapAPI, RasterizedMapPatch, VectorMap
from trajdata.utils.state_utils import convert_to_frame_state, transform_from_frame

class AgentBatchElement:
    """A single element of an agent-centric batch."""

    # @profile
    def __init__(
        self,
        cache: SceneCache,
        data_index: int,
        scene_time_agent: SceneTimeAgent,
        history_sec: Tuple[Optional[float], Optional[float]],
        future_sec: Tuple[Optional[float], Optional[float]],
        agent_interaction_distances: Dict[
            Tuple[AgentType, AgentType], float
        ] = defaultdict(lambda: np.inf),
        incl_robot_future: bool = False,
        incl_raster_map: bool = False,
        raster_map_params: Optional[Dict[str, Any]] = None,
        map_api: Optional[MapAPI] = None,
        vector_map_params: Optional[Dict[str, Any]] = None,
        state_format: Optional[str] = None,
        standardize_data: bool = False,
        standardize_derivatives: bool = False,
        max_neighbor_num: Optional[int] = None,
    ) -> None:
        self.cache: SceneCache = cache
        self.data_index: int = data_index
        self.dt: float = scene_time_agent.scene.dt
        self.scene_ts: int = scene_time_agent.ts
        self.history_sec = history_sec
        self.future_sec = future_sec

        agent_info: AgentMetadata = scene_time_agent.agent
        self.agent_name: str = agent_info.name
        self.agent_type: AgentType = agent_info.type
        self.max_neighbor_num = max_neighbor_num

        raw_state: StateArray = cache.get_raw_state(agent_info.name, self.scene_ts)
        if state_format is not None:
            self.curr_agent_state_np = raw_state.as_format(state_format)
        else:
            self.curr_agent_state_np = raw_state

        self.standardize_data = standardize_data
        if self.standardize_data:
            # Request cache to return observations relative to current agent
            obs_frame: StateArray = convert_to_frame_state(
                raw_state,
                stationary=not standardize_derivatives,
                grounded=True,
            )
            cache.set_obs_frame(obs_frame)

            # Create and store 2d tranformation matrix to agent from world
            agent_pos = self.curr_agent_state_np.position
            agent_heading_vector = self.curr_agent_state_np.heading_vector
            cos_agent, sin_agent = agent_heading_vector[0], agent_heading_vector[1]
            world_from_agent_tf: np.ndarray = np.array(
                [
                    [cos_agent, -sin_agent, agent_pos[0]],
                    [sin_agent, cos_agent, agent_pos[1]],
                    [0.0, 0.0, 1.0],
                ]
            )
            self.agent_from_world_tf: np.ndarray = np.linalg.inv(world_from_agent_tf)
        else:
            self.agent_from_world_tf: np.ndarray = np.eye(3)

        ### AGENT-SPECIFIC DATA ###
        self.agent_history_np, self.agent_history_extent_np = self.get_agent_history(
            agent_info, history_sec
        )
        self.agent_history_len: int = self.agent_history_np.shape[0]

        self.agent_future_np, self.agent_future_extent_np = self.get_agent_future(
            agent_info, future_sec
        )
        self.agent_future_len: int = self.agent_future_np.shape[0]
        self.agent_meta_dict: Dict = get_agent_meta_dict(self.cache, agent_info)

        ### NEIGHBOR-SPECIFIC DATA ###
        def distance_limit(agent_types: np.ndarray, target_type: int) -> np.ndarray:
            return np.array(
                [
                    agent_interaction_distances[(agent_type, target_type)]
                    for agent_type in agent_types
                ]
            )

        nearby_agents, self.neighbor_types_np = self.get_nearby_agents(
            scene_time_agent, agent_info, distance_limit
        )

        self.num_neighbors = len(nearby_agents)
        (
            self.neighbor_histories,
            self.neighbor_history_extents,
            self.neighbor_history_lens_np,
        ) = self.get_neighbor_history(history_sec, nearby_agents)

        (
            self.neighbor_futures,
            self.neighbor_future_extents,
            self.neighbor_future_lens_np,
        ) = self.get_neighbor_future(future_sec, nearby_agents)

        self.neighbor_meta_dicts: Dict = [
            get_agent_meta_dict(self.cache, agent) for agent in nearby_agents
        ]

        ### ROBOT DATA ###
        self.robot_future_np: Optional[StateArray] = None

        if incl_robot_future:
            self.robot_future_np: StateArray = self.get_robot_current_and_future(
                scene_time_agent.robot, future_sec
            )

            # -1 because this is meant to hold the number of future steps
            # (whereas the above returns the current + future, yielding
            # one more timestep).
            self.robot_future_len: int = self.robot_future_np.shape[0] - 1

        ### MAP ###
        self.map_name: Optional[str] = None
        self.map_patch: Optional[RasterizedMapPatch] = None

        map_name: str = (
            f"{scene_time_agent.scene.env_name}:{scene_time_agent.scene.location}"
        )
        if incl_raster_map:
            self.map_name = map_name
            self.map_patch = self.get_agent_map_patch(raster_map_params)

        self.vec_map: Optional[VectorMap] = None
        if map_api is not None:
            self.vec_map = map_api.get_map(
                map_name,
                self.cache
                if self.cache.is_traffic_light_data_cached(
                    # Is the original dt cached? If so, we can continue by
                    # interpolating time to get whatever the user desires.
                    self.cache.scene.env_metadata.dt
                )
                else None,
                **vector_map_params if vector_map_params is not None else None,
            )

        self.scene_id = scene_time_agent.scene.name

        # Will be optionally populated by the user's provided functions.
        self.extras: Dict[str, np.ndarray] = dict()

    def get_agent_history(
        self,
        agent_info: AgentMetadata,
        history_sec: Tuple[Optional[float], Optional[float]],
    ) -> Tuple[StateArray, np.ndarray]:
        agent_history_np, agent_extent_history_np = self.cache.get_agent_history(
            agent_info, self.scene_ts, history_sec
        )
        return agent_history_np, agent_extent_history_np

    def get_agent_future(
        self,
        agent_info: AgentMetadata,
        future_sec: Tuple[Optional[float], Optional[float]],
    ) -> Tuple[StateArray, np.ndarray]:
        agent_future_np, agent_extent_future_np = self.cache.get_agent_future(
            agent_info, self.scene_ts, future_sec
        )
        return agent_future_np, agent_extent_future_np

    # @profile
    def get_nearby_agents(
        self,
        scene_time: SceneTimeAgent,
        agent_info: AgentMetadata,
        distance_limit: Callable[[np.ndarray, int], np.ndarray],
    ) -> Tuple[List[AgentMetadata], np.ndarray]:
        """
        Returns Agent Metadata and Agent types of nearby agents
        """
        # The indices of the returned ndarray match the scene_time agents list
        # (including the index of the central agent, which would have a distance
        # of 0 to itself).
        agent_distances: np.ndarray = scene_time.get_agent_distances_to(agent_info)
        agent_idx: int = scene_time.agents.index(agent_info)

        neighbor_types: np.ndarray = np.array([a.type.value for a in scene_time.agents])
        nearby_mask: np.ndarray = agent_distances <= distance_limit(
            neighbor_types, agent_info.type
        )
        nearby_mask[agent_idx] = False

        nb_idx = agent_distances.argsort()
        nearby_agents: List[AgentMetadata] = [
            scene_time.agents[idx] for idx in nb_idx if nearby_mask[idx]
        ]

        if self.max_neighbor_num is not None:
            # Pruning nearby_agents and re-creating
            # neighbor_types_np with the remaining agents.
            nearby_agents = nearby_agents[: self.max_neighbor_num]

        # Doing this here because the argsort above changes the order of agents.
        neighbor_types_np: np.ndarray = np.array([a.type.value for a in nearby_agents])

        return nearby_agents, neighbor_types_np

    def get_neighbor_history(
        self,
        history_sec: Tuple[Optional[float], Optional[float]],
        nearby_agents: List[AgentMetadata],
    ) -> Tuple[List[np.ndarray], List[np.ndarray], np.ndarray]:
        (
            neighbor_data,
            neighbor_extents_data,
            neighbor_data_lens_np,
        ) = self.cache.get_agents_history(self.scene_ts, nearby_agents, history_sec)
        return (
            neighbor_data,
            neighbor_extents_data,
            neighbor_data_lens_np,
        )

    def get_neighbor_future(
        self,
        future_sec: Tuple[Optional[float], Optional[float]],
        nearby_agents: List[AgentMetadata],
    ) -> Tuple[List[np.ndarray], List[np.ndarray], np.ndarray]:
        (
            neighbor_data,
            neighbor_extents_data,
            neighbor_data_lens_np,
        ) = self.cache.get_agents_future(self.scene_ts, nearby_agents, future_sec)
        return (
            neighbor_data,
            neighbor_extents_data,
            neighbor_data_lens_np,
        )

    def get_robot_current_and_future(
        self,
        robot_info: AgentMetadata,
        future_sec: Tuple[Optional[float], Optional[float]],
    ) -> StateArray:
        robot_curr_np: StateArray = self.cache.get_state(robot_info.name, self.scene_ts)
        # robot_fut_extents_np,
        (
            robot_fut_np,
            _,
        ) = self.cache.get_agent_future(robot_info, self.scene_ts, future_sec)

        robot_curr_and_fut_np: StateArray = np.concatenate(
            (robot_curr_np[np.newaxis, :], robot_fut_np), axis=0
        ).view(self.cache.obs_type)
        return robot_curr_and_fut_np

    def get_agent_map_patch(self, patch_params: Dict[str, int]) -> RasterizedMapPatch:
        world_x, world_y = self.curr_agent_state_np.position
        desired_patch_size: int = patch_params["map_size_px"]
        resolution: float = patch_params["px_per_m"]
        offset_xy: Tuple[float, float] = patch_params.get("offset_frac_xy", (0.0, 0.0))
        return_rgb: bool = patch_params.get("return_rgb", True)
        no_map_fill_val: float = patch_params.get("no_map_fill_value", 0.0)

        if self.standardize_data:
            heading = self.curr_agent_state_np.heading[0]
            patch_data, raster_from_world_tf, has_data = self.cache.load_map_patch(
                world_x,
                world_y,
                desired_patch_size,
                resolution,
                offset_xy,
                heading,
                return_rgb,
                rot_pad_factor=sqrt(2),
                no_map_val=no_map_fill_val,
            )
        else:
            heading = 0.0
            patch_data, raster_from_world_tf, has_data = self.cache.load_map_patch(
                world_x,
                world_y,
                desired_patch_size,
                resolution,
                offset_xy,
                heading,
                return_rgb,
                no_map_val=no_map_fill_val,
            )

        return RasterizedMapPatch(
            data=patch_data,
            rot_angle=heading,
            crop_size=desired_patch_size,
            resolution=resolution,
            raster_from_world_tf=raster_from_world_tf,
            has_data=has_data,
        )

class SceneBatchElement:
    """A single batch element."""

    def __init__(
        self,
        cache: SceneCache,
        data_index: int,
        scene_time: SceneTime,
        history_sec: Tuple[Optional[float], Optional[float]],
        future_sec: Tuple[Optional[float], Optional[float]],
        agent_interaction_distances: Dict[
            Tuple[AgentType, AgentType], float
        ] = defaultdict(lambda: np.inf),
        incl_robot_future: bool = False,
        incl_raster_map: bool = False,
        raster_map_params: Optional[Dict[str, Any]] = None,
        map_api: Optional[MapAPI] = None,
        vector_map_params: Optional[Dict[str, Any]] = None,
        state_format: Optional[str] = None,
        standardize_data: bool = False,
        standardize_derivatives: bool = False,
        max_agent_num: Optional[int] = None,
    ) -> None:
        self.cache: SceneCache = cache
        self.data_index = data_index
        self.dt: float = scene_time.scene.dt
        self.scene_ts: int = scene_time.ts

        if max_agent_num is not None:
            scene_time.agents = scene_time.agents[:max_agent_num]

        self.agents: List[AgentMetadata] = scene_time.agents

        robot = [agent for agent in self.agents if agent.name == "ego"]
        if len(robot) > 0:
            self.centered_agent = robot[0]
        else:
            self.centered_agent = self.agents[0]

        raw_state: StateArray = cache.get_raw_state(
            self.centered_agent.name, self.scene_ts
        )

        if state_format is not None:
            self.centered_agent_state_np = raw_state.as_format(state_format)
        else:
            self.centered_agent_state_np = raw_state

        self.standardize_data = standardize_data

        if self.standardize_data:
            # Request cache to return observations relative to centered agent
            obs_frame: StateArray = convert_to_frame_state(
                raw_state,
                stationary=not standardize_derivatives,
                grounded=True,
            )
            cache.set_obs_frame(obs_frame)

            # Create 2d transformation matrix to and from agent and world
            agent_pos: np.ndarray = self.centered_agent_state_np.position
            agent_heading: float = self.centered_agent_state_np.heading[0]

            cos_agent, sin_agent = np.cos(agent_heading), np.sin(agent_heading)
            self.centered_world_from_agent_tf: np.ndarray = np.array(
                [
                    [cos_agent, -sin_agent, agent_pos[0]],
                    [sin_agent, cos_agent, agent_pos[1]],
                    [0.0, 0.0, 1.0],
                ]
            )
            self.centered_agent_from_world_tf: np.ndarray = np.linalg.inv(
                self.centered_world_from_agent_tf
            )
        else:
            self.centered_agent_from_world_tf: np.ndarray = np.eye(3)
            self.centered_world_from_agent_tf: np.ndarray = np.eye(3)

        ### NEIGHBOR-SPECIFIC DATA ###
        def distance_limit(agent_types: np.ndarray, target_type: int) -> np.ndarray:
            return np.array(
                [
                    agent_interaction_distances[(agent_type, target_type)]
                    for agent_type in agent_types
                ]
            )

        nearby_agents, self.agent_types_np = self.get_nearby_agents(
            scene_time, self.centered_agent, distance_limit
        )

        self.num_agents = len(nearby_agents)
        self.agent_names = [agent.name for agent in nearby_agents]
        (
            self.agent_histories,
            self.agent_history_extents,
            self.agent_history_lens_np,
        ) = self.get_agents_history(history_sec, nearby_agents)
        (
            self.agent_futures,
            self.agent_future_extents,
            self.agent_future_lens_np,
        ) = self.get_agents_future(future_sec, nearby_agents)

        self.agent_meta_dicts = [
            get_agent_meta_dict(self.cache, agent) for agent in nearby_agents
        ]

        ### MAP ###
        self.map_name: Optional[str] = None
        self.map_patches: Optional[RasterizedMapPatch] = None

        map_name: str = f"{scene_time.scene.env_name}:{scene_time.scene.location}"
        if incl_raster_map:
            self.map_name = map_name
            self.map_patches = self.get_agents_map_patch(
                raster_map_params, self.agent_histories
            )

        self.vec_map: Optional[VectorMap] = None
        if map_api is not None:
            self.vec_map = map_api.get_map(
                map_name,
                self.cache if self.cache.is_traffic_light_data_cached() else None,
                **vector_map_params if vector_map_params is not None else None,
            )

        self.scene_id = scene_time.scene.name

        ### ROBOT DATA ###
        self.robot_future_np: Optional[StateArray] = None

        if incl_robot_future:
            self.robot_future_np: StateArray = self.get_robot_current_and_future(
                self.centered_agent, future_sec
            )

            # -1 because this is meant to hold the number of future steps
            # (whereas the above returns the current + future, yielding
            # one more timestep).
            self.robot_future_len: int = self.robot_future_np.shape[0] - 1

        self.scene_id = scene_time.scene.name

        # Will be optionally populated by the user's provided functions.
        self.extras: Dict[str, np.ndarray] = dict()

    def get_nearby_agents(
        self,
        scene_time: SceneTime,
        agent: AgentMetadata,
        distance_limit: Callable[[np.ndarray, int], np.ndarray],
    ) -> Tuple[List[AgentMetadata], np.ndarray]:
        agent_distances: np.ndarray = scene_time.get_agent_distances_to(agent)

        agents_types: np.ndarray = np.array([a.type.value for a in scene_time.agents])
        nearby_mask: np.ndarray = agent_distances <= distance_limit(
            agents_types, agent.type
        )
        # sort the agents based on their distance to the centered agent
        idx = np.argsort(agent_distances)
        num_qualified = nearby_mask.sum()
        nearby_agents: List[AgentMetadata] = [
            scene_time.agents[idx[i]] for i in range(num_qualified)
        ]
        agents_types_np = agents_types[idx[:num_qualified]]
        return nearby_agents, agents_types_np

    def get_agents_history(
        self,
        history_sec: Tuple[Optional[float], Optional[float]],
        nearby_agents: List[AgentMetadata],
    ) -> Tuple[List[StateArray], List[np.ndarray], np.ndarray]:
        # The indices of the returned ndarray match the scene_time agents list (including the index of the central agent,
        # which would have a distance of 0 to itself).
        (
            agent_histories,
            agent_history_extents,
            agent_history_lens_np,
        ) = self.cache.get_agents_history(self.scene_ts, nearby_agents, history_sec)

        return (
            agent_histories,
            agent_history_extents,
            agent_history_lens_np,
        )

    def get_agents_future(
        self,
        future_sec: Tuple[Optional[float], Optional[float]],
        nearby_agents: List[AgentMetadata],
    ) -> Tuple[List[StateArray], List[np.ndarray], np.ndarray]:

        (
            agent_futures,
            agent_future_extents,
            agent_future_lens_np,
        ) = self.cache.get_agents_future(self.scene_ts, nearby_agents, future_sec)

        return (
            agent_futures,
            agent_future_extents,
            agent_future_lens_np,
        )

    def get_agents_map_patch(
        self, patch_params: Dict[str, int], agent_histories: List[np.ndarray]
    ) -> List[RasterizedMapPatch]:
        desired_patch_size: int = patch_params["map_size_px"]
        resolution: float = patch_params["px_per_m"]
        offset_xy: Tuple[float, float] = patch_params.get("offset_frac_xy", (0.0, 0.0))
        return_rgb: bool = patch_params.get("return_rgb", True)
        no_map_fill_val: float = patch_params.get("no_map_fill_value", 0.0)

        map_patches = list()

        curr_state = [state[-1] for state in agent_histories]
        curr_state = np.stack(curr_state).view(self.cache.obs_type)

        if self.standardize_data:
            # need to transform back into world frame
            obs_frame: StateArray = convert_to_frame_state(
                self.centered_agent_state_np, stationary=True, grounded=True
            )
            curr_state = transform_from_frame(curr_state, obs_frame)
            heading = curr_state.heading[:, 0]
        else:
            heading = 0.0 * curr_state.heading[:, 0]

        for i in range(curr_state.shape[0]):
            patch_data, raster_from_world_tf, has_data = self.cache.load_map_patch(
                curr_state.get_attr("x")[i],
                curr_state.get_attr("y")[i],
                desired_patch_size,
                resolution,
                offset_xy,
                heading[i],
                return_rgb,
                rot_pad_factor=sqrt(2),
                no_map_val=no_map_fill_val,
            )
            map_patches.append(
                RasterizedMapPatch(
                    data=patch_data,
                    rot_angle=heading[i],
                    crop_size=desired_patch_size,
                    resolution=resolution,
                    raster_from_world_tf=raster_from_world_tf,
                    has_data=has_data,
                )
            )

        return map_patches

    def get_robot_current_and_future(
        self,
        robot_info: AgentMetadata,
        future_sec: Tuple[Optional[float], Optional[float]],
    ) -> StateArray:
        robot_curr_np: StateArray = self.cache.get_state(robot_info.name, self.scene_ts)
        # robot_fut_extents_np,
        (
            robot_fut_np,
            _,
        ) = self.cache.get_agent_future(robot_info, self.scene_ts, future_sec)

        robot_curr_and_fut_np: StateArray = np.concatenate(
            (robot_curr_np[np.newaxis, :], robot_fut_np), axis=0
        ).view(self.cache.obs_type)
        return robot_curr_and_fut_np

def is_agent_stationary(cache: SceneCache, agent_info: AgentMetadata) -> bool:
    # Agent is considered stationary if it moves less than 1m between the first and last valid timestep.
    first_state: StateArray = cache.get_state(
        agent_info.name, agent_info.first_timestep
    )
    last_state: StateArray = cache.get_state(agent_info.name, agent_info.last_timestep)
    is_stationary = np.square(last_state.position - first_state.position).sum(0) < 1.0
    return is_stationary

def get_agent_meta_dict(
    cache: SceneCache, agent_info: AgentMetadata
) -> Dict[str, np.ndarray]:
    return {
        "is_stationary": is_agent_stationary(cache, agent_info),
    }


import os
import yaml
import lasagne
import pandas as pd
import numpy as np

from network import Network
import architectures as arches

L = lasagne.layers

# loads data with names according to autoload_data.py
from autoload_data import *

# load specs for all networks
with open('arch_specs.yaml') as archfile:
    arch_dict = yaml.load(archfile)

### Compiling results from saved parameters ###

def compute_pretrained_results(net, archname, idx, test_data, fake=False):
    """
    Compute pre-tuning results for a given arch/network on appropriate test data
    """
    Xt, yt = test_data

    if fake:
        fname = '{} {} split fake data.npz'
        fname = fname.format('fake_' + archname, idx)
        paramsdir = os.path.join(paramsdir_, 'fake_' + archname)

    else:
        fname = '{} {} split agg fit exp 1-4.npz'
        fname = fname.format(archname.replace('_', ' '), idx)
        paramsdir = os.path.join(paramsdir_, archname[:-1])

    results_df = pd.DataFrame(index=np.arange(Xt.shape[0]), columns=[idx])

    net.load_params(os.path.join(paramsdir, fname))

    nlls = net.itemized_test_fn(Xt, yt)
    predictions = net.output_fn(Xt)
    results_df[idx] = nlls

    return results_df, predictions

def compute_tuned_results(net, archname, idx, test_idx, test_data, df):
    """
    Compute post-tuning results for a given architecture/network on appropriate
        test data
    """
    Xt, yt = test_data
    group_idx = (test_idx - 1) % 5 # fix eventually to take df/groupidx/selection passed independently?
    selection = df.loc[df['group']==(group_idx+1)].index.values
    results_df = pd.DataFrame(index=np.arange(Xt.shape[0]), columns=[idx])
    predictions_df = pd.DataFrame(index=selection, columns=np.arange(36))

    fname = '{} {} agg fit exp 1-4 {} tune fit exp 0.npz'
    fname = fname.format(archname.replace('_', ' '), idx, test_idx)

    net.load_params(os.path.join(paramsdir_, archname[:-1], fname))

    nlls = net.itemized_test_fn(Xt[selection, :, :, :], yt[selection])
    predictions = net.output_fn(Xt[selection, :, :, :])
    predictions_df.loc[selection, :] = predictions
    results_df.loc[selection, idx] = nlls
    return results_df, predictions_df

def compute_net_results(net, archname, test_data, df):
    """
    For a given network, test on appropriate test data and return dataframes
    with results and predictions (named obviously)
    """
    pretrain_results = []
    pretrain_predictions = []
    tune_results = []
    tune_predictions = []

    for idx in range(5):
        results_df, predictions_df = compute_pretrained_results(net, archname, idx, test_data)
        pretrain_results.append(results_df)
        pretrain_predictions.append(predictions_df)

    pretrain_results = pd.concat(pretrain_results, axis=1)

    for idx in range(5):
        for test_idx in range(5):
            results_df, predictions_df  = compute_tuned_results(net, archname, idx, test_idx, test_data, df)
            tune_results.append(results_df)
            tune_predictions.append(predictions_df)

    tune_results = pd.concat(tune_results, axis=1, join='inner').stack().unstack()

    return pretrain_results, pretrain_predictions, tune_results, tune_predictions

def rehydrate(verbose=False):
    """
    Recompile networks, load params, and run on appropriate test data

    outputs dictionaries with keys = names of architectures as in arch_specs.yaml

    outputs:
    PTx is pretrained on bulk but untuned
    Tx is tuned
    xR is results (nlls)
    xP is predictions (distributions)

    param_counts is what it sounds like.
    """
    Xt, yt, _, _, _ = loading.unpack_data(df)       # get Xs and ys

    PTR = {}                # results and predictions holders
    TR = {}
    PTP = {}
    TP = {}
    param_counts = {}       # counter of parameters per net

    for archname in arch_dict.keys():
        # for each network
        arch_dir = archname[:-1]        # get directory

        if arch_dir not in os.listdir(paramsdir_):
            # if it doesn't exist
            print("{} not started".format(archname[:-1]))       # alert us
            continue

        files = os.listdir(os.path.join(paramsdir_, arch_dir))
        if not any(archname.replace('_', ' ') in f for f in files):
            # if a network doesn't have a full set of parameter fits
            print("{} not completed".format(archname))      # let us know
            continue

        if verbose:
            print(archname)
        arch = arch_dict[archname]
        af = getattr(arches, arch['type'])
        arch_func = lambda input_var: af(input_var, **arch['kwargs'])
        net = Network(arch_func)        # compile network from specs in arch_specs.yaml

        param_counts[archname] = L.count_params(net.net)        # count the params
        pretrain_R, pretrain_P, tune_R, tune_P = compute_net_results(net, archname, (Xt, yt), df)

        PTR[archname] = pretrain_R      # insert results into respective holders
        TR[archname] = tune_R
        PTP[archname] = pretrain_P
        TP[archname] = tune_P

        pretrain_R.to_csv(os.path.join(resultsdir, 'pretrain {}.csv'.format(archname)))     # save results into respective directories
        tune_R.to_csv(os.path.join(resultsdir, 'train {}.csv'.format(archname)))

    return PTR, TR, PTP, TP, param_counts

### Statistics and summaries ###

def entropy_zets(zets):
    """Shannon entropy"""
    z = np.histogram(zets, bins=np.arange(37), normed=True)[0]
    z = z[z > 0]
    return -(z * np.log2(z)).sum()

def count_pieces(row):
    """Counts pieces in a given binstring state representation"""
    bp, wp = row[['bp', 'wp']]
    n_bp = np.array(list(bp)).astype(int).sum()
    n_wp = np.array(list(wp)).astype(int).sum()

    return n_bp + n_wp

def aggregate_results(PTR, TR, param_counts):
    """
    Args:
    PTR, TR, are dictionaries of results dataframes with archnames as keys,
        archnames as in arch_specs.yaml and PTR/TR as produced by rehydrate()
    param_counts also keyed by archnames and as produced by rehydrate; contains
        parameter counts

    outputs:
    F is a dataframe containing individual networks in rows with mean
        performances in columns

    """
    pc_series = pd.Series(param_counts)
    pc_series.to_csv(os.path.join(resultsdir, 'params per net.csv'))
    F = pd.DataFrame(index=np.arange(len(pc_series.index)), columns=['net name'])
    F['net name'] = pc_series.index
    F['num params'] = pc_series.values

    for k, v in PTR.items():
        idx = F['net name'] == k
        v['subject'] = Ss
        v['mean'] = v.mean()
        F.loc[idx, 'pretrained'] = v['mean'].mean()
        pvt = v.pivot_table(index='subject', values='mean', aggfunc=np.mean).mean().values
        F.loc[idx, 'pretrained subject'] = pvt

    for k, v in TR.items():
        idx = F['net name'] == k
        v['subject'] = Ss
        v['mean'] = v.mean()
        F.loc[idx, 'tuned'] = v['mean'].mean()
        pvt = v.pivot_table(index='subject', values='mean', aggfunc=np.mean).mean().values
        F.loc[idx, 'tuned subject'] = pvt

    F['tuning improvement'] = -(F['tuned'] - F['pretrained'])

    return F

def error_per_piece(archname, resultdict, datadf):
    """
    Args:
    archname is name of architecture as in arch_specs.yaml
    resultdict should be a dictionary of predictions where keys = archnames
    datadf is the original data containing positions, subjects, moves, etc

    Outputs:
    preds is a list of dataframes containing predictions for reach observation
        in datadf and training split for archname
    per_pieces is a df with the mean chance-relative nll for each subject and
        number of pieces in position

    """

    chancenll = lambda x: -np.log(1/(36-x))
    cross_entropy = lambda row: -np.log(row[int(row['zet'])])
    preds = [pd.concat(resultdict[archname][i:i+5]).sort_index() for i in range(5)]

    for pred in preds:
        pred['subject'] = df['subject']
        pred['zet'] = df['zet']
        pred['num pieces'] = df['np']
        pred['rt'] = df['rt']
        pred['chance nll'] = chancenll(df['np'].values)
        pred['error'] = pred.apply(cross_entropy, axis=1)
        pred['relative error'] = pred['chance nll'] - pred['error']

    per_pieces = pd.concat([
        p.pivot_table(index='subject', values='relative error', columns='num pieces').mean(axis=0)
        for p in preds
    ], axis=1)

    return preds, per_pieces


import numpy as np

import bridgestan as bs

# These paths are what they are because this example lives in a subfolder
# of the BridgeStan repository. If you're running this on your own, you
# will most likely want to delete the next line (to have BridgeStan
# download its sources for you) and change the paths on the following two
bs.set_bridgestan_path("..")

stan = "../test_models/bernoulli/bernoulli.stan"
data = "../test_models/bernoulli/bernoulli.data.json"
model = bs.StanModel.from_stan_file(stan, data)

print(f"This model's name is {model.name()}.")
print(f"It has {model.param_num()} parameters.")

x = np.random.random(model.param_unc_num())
q = np.log(x / (1 - x))  # unconstrained scale
lp, grad = model.log_density_gradient(q, jacobian=False)
print(f"log_density and gradient of Bernoulli model: {(lp, grad)}")


import cv2 as cv
import numpy as np

src = cv.imread("/home/gyh/opencv/lena.jpg")
img = cv.Canny(src,100,150)
"""
cv2.Canny(),就可以完成以上几步。
让我们看如何使用这个函数。这个函数的第一个参数是输入图像。第二和第三
个分别是 minVal 和 maxVal。第三个参数设置用来计算图像梯度的 Sobel
卷积核的大小,默认值为 3。最后一个参数是 L2gradient,它可以用来设定
求梯度大小的方程。如果设为 True,就会使用我们上面提到过的方程,否则
使用方程:Edge − Gradient (G) = |G 2 x | + |G 2 y | 代替,默认值为 False。
"""

cv.imshow("src",src)
cv.imshow("img",img)
cv.waitKey(0)
cv.destroyAllWindows()


#Author:immortal luo
# -*-coding:utf-8 -*-
import pika
# Broker:它提供一种传输服务,它的角色就是维护一条从生产者到消费者的路线，保证数据能按照指定的方式进行传输,
# vhost:虚拟主机,一个broker里可以有多个vhost，用作不同用户的权限分离。

conneection = pika.BlockingConnection(pika.ConnectionParameters(
    host='localhost'
))

# Channel:消息通道,在客户端的每个连接里,可建立多个channel.
channel = conneection.channel()

# Exchange：消息交换机,它指定消息按什么规则,路由到哪个队列。
channel.exchange_declare(exchange='logs',
                         exchange_type='fanout')

# Queue:消息的载体,每个消息都会被投到一个或多个队列。
result = channel.queue_declare(exclusive=True)#随机创建一个Queue,程序结束后自动删除
queue_name = result.method.queue#获取刚创建的Queue的名称

# Binding:绑定，它的作用就是把exchange和queue按照路由规则绑定起来.
channel.queue_bind(exchange='logs',
                   queue=queue_name)
print("[*] Waiting for logs.To exit press CTRL+C")

def callback(ch,method,properties,body):
    print("[x] %r"%body)

channel.basic_consume(callback,
                      queue=queue_name,
                      no_ack=True)

channel.start_consuming()


# evaluate the mask rcnn model on the kangaroo dataset
from os import listdir
from xml.etree import ElementTree
from numpy import zeros
from numpy import asarray
from numpy import expand_dims
from numpy import mean
from mrcnn.config import Config
from mrcnn.model import MaskRCNN
from mrcnn.utils import Dataset
from mrcnn.utils import compute_ap
from mrcnn.model import load_image_gt
from mrcnn.model import mold_image
import matplotlib.pyplot as plt
import matplotlib.patches as pt

# class that defines and loads the kangaroo dataset
class KangarooDataset(Dataset):
	# load the dataset definitions
	def load_dataset(self, dataset_dir, is_train=True):
		# define one class
		self.add_class("dataset", 1, "algae")
		self.add_class("dataset",2,"Trash_on_water")
		# define data locations
		images_dir = dataset_dir + '/algae/'
		annotations_dir = dataset_dir + '/annotation/'
		# find all images
		count=0
		dict1={}
		for filename in listdir(images_dir):
			# extract image id
			image_id = filename[19:32]
			# if(image_id in discard_id):
			# 	continue
			# dict1[image_id]=count/
			count+=1
			# skip bad images
			#if image_id in ['00090']:
			#	continue
			# skip all images after 150 if we are building the train set
			if is_train and count >= 1001:
				continue
			# skip all images before 150 if we are building the test/val set
			if not is_train and count < 1001:
				continue
			img_path = images_dir + filename
			ann_path = annotations_dir + filename[:-4]+ '.xml'
			# add to dataset
			self.add_image('dataset', image_id=image_id, path=img_path, annotation=ann_path)

	# extract bounding boxes from an annotation file
	def extract_boxes(self, filename):
		# load and parse the file
		tree = ElementTree.parse(filename)
		# get the root of the document
		root = tree.getroot()
		# extract each bounding box
		boxes = list()
		for box in root.findall('.//bndbox'):
			xmin = int(box.find('xmin').text)
			ymin = int(box.find('ymin').text)
			xmax = int(box.find('xmax').text)
			ymax = int(box.find('ymax').text)
			coors = [xmin, ymin, xmax, ymax]
			boxes.append(coors)
		# extract image dimensions
		width = int(root.find('.//size/width').text)
		height = int(root.find('.//size/height').text)
		return boxes, width, height

	# load the masks for an image
	def load_mask(self, image_id):
		# get details of image
		info = self.image_info[image_id]
		# define box file location
		path = info['annotation']
		# load XML
		boxes, w, h = self.extract_boxes(path)
		# create one array for all masks, each on a different channel
		masks = zeros([h, w, len(boxes)], dtype='uint8')
		# create masks
		class_ids = list()
		for i in range(len(boxes)):
			box = boxes[i]
			row_s, row_e = box[1], box[3]
			col_s, col_e = box[0], box[2]
			masks[row_s:row_e, col_s:col_e, i] = 1
			class_ids.append(self.class_names.index('algae'))
			class_ids.append(self.class_names.index('Trash_on_water'))
			# print(self.class_names.index('Trash_on_water'))
			# print(self.class_names.index('algae'))
		return masks, asarray(class_ids, dtype='int32')

	# load an image reference
	def image_reference(self, image_id):
		info = self.image_info[image_id]
		return info['path']

# define the prediction configuration
class PredictionConfig(Config):
	# define the name of the configuration
	print("hey reached prediction config")
	NAME = "algae_cfg"
	# number of classes (background + kangaroo)
	NUM_CLASSES = 1 + 2
	# simplify GPU config
	GPU_COUNT = 1
	IMAGES_PER_GPU = 1

# calculate the mAP for a model on a given dataset
def plot_actual_vs_predicted(dataset, model, cfg, n_images=5):
	# load image and mask
	for i in range(n_images):
		# load the image and mask
		image = dataset.load_image(i)
		mask, _ = dataset.load_mask(i)
		# convert pixel values (e.g. center)
		scaled_image = mold_image(image, cfg)
		# convert image into one sample
		sample = expand_dims(scaled_image, 0)
		# make prediction
		yhat = model.detect(sample, verbose=0)[0]
		# define subplot
		plt.subplot(n_images, 2, i*2+1)
		# plot raw pixel data
		plt.imshow(image)
		plt.title('Actual')
		# plot masks
		for j in range(mask.shape[2]):
			plt.imshow(mask[:, :, j], cmap='gray', alpha=0.3)
		# get the context for drawing boxes
		plt.subplot(n_images, 2, i*2+2)
		# plot raw pixel data
		plt.imshow(image)
		plt.title('Predicted')
		ax = plt.gca()
		# plot each box
		for box in yhat['rois']:
			# get coordinates
			y1, x1, y2, x2 = box
			# calculate width and height of the box
			width, height = x2 - x1, y2 - y1
			# create the shape
			rect = pt.Rectangle((x1, y1), width, height, fill=False, color='red')
			# draw the box
			ax.add_patch(rect)
	# show the figure
	plt.show()

# load the train dataset
train_set = KangarooDataset()
train_set.load_dataset('./Dataset', is_train=True)
train_set.prepare()
print('Train: %d' % len(train_set.image_ids))
# load the test dataset
test_set = KangarooDataset()
test_set.load_dataset('./Dataset', is_train=False)
test_set.prepare()
print('Test: %d' % len(test_set.image_ids))
cfg = PredictionConfig()

model = MaskRCNN(mode='inference', model_dir='./mode/algae_cfg/', config=cfg)
# load model weights
model_path = './mode/algae_cfg/mask_rcnn_algae_cfg_0050.h5'
#model.load_weights(model_path, by_name=True)
# plot predictions for train dataset
image = plt.imread('img1.jpg')

plt.imshow(image)
# convert pixel values (e.g. center)
scaled_image = mold_image(image, cfg)
# convert image into one sample
sample = expand_dims(scaled_image, 0)
# make prediction
yhat = model.detect(sample, verbose=0)[0]
ax = plt.gca()
# plot each box
for box in yhat['rois']:
	# get coordinates
	y1, x1, y2, x2 = box
	# calculate width and height of the box
	width, height = x2 - x1, y2 - y1
	# create the shape
	rect = pt.Rectangle((x1, y1), width, height, fill=False, color='red')
	# draw the box
	ax.add_patch(rect)
#plt.imshow(yhat)

# create config

# define the model
model = MaskRCNN(mode='inference', model_dir='./mode/algae_cfg/', config=cfg)
# load model weights
model_path = './mode/algae_cfg/mask_rcnn_algae_cfg_0050.h5'
model.load_weights(model_path, by_name=True)
# plot predictions for train dataset
plot_actual_vs_predicted(train_set, model, cfg)
# plot predictions for test dataset
plot_actual_vs_predicted(test_set, model, cfg)


import os

def f(file, file_count = 0, size = 0):
    dir_count = 0
    for i in os.listdir(file):
        path = os.path.join(file, i)
        if os.path.isdir(path):
            dir_count += 1
            z, file_count, size = f(path, file_count, size)
        elif os.path.isfile(path):
            file_count += 1
            size += os.path.getsize(path)
    return dir_count, file_count, size

search_file = os.path.join('..')
print(search_file)

dirr, ffile, size = f(search_file)

print(f'Количество папок: {dirr}\nКоличество файлов: {ffile}\nРазмер (кб): {size/1024}')


'''
Author: Mayank Prakash Pandey
'''

import pickle
import streamlit as st
import numpy as np

# Adding header and author information
st.header('Book Recommender')
st.markdown("A **Machine Learning** Powered App by :red[**Mayank Prakash Pandey**] :computer:")

# Loading the necessary pickle files
model = pickle.load(open('models/similarity_scores.pkl', 'rb'))
final_rating = pickle.load(open('models/books.pkl', 'rb'))
book_pivot = pickle.load(open('models/pt.pkl', 'rb'))
top_books = pickle.load(open('models/popular.pkl','rb'))

# Creating a sidebar panel with a list of books
df=top_books
st.sidebar.title("Top 50 Books")
book_list = st.sidebar.selectbox("Select a book", df['Title'])

# Show the selected book's title and rating on the main page
if book_list:
    selected_book = df[df['Title'] == book_list]
    st.sidebar.title("Selected Book")
    st.sidebar.image(selected_book['URL'].values[0])
    st.sidebar.write("Title :red[:] ", selected_book['Title'].values[0])
    st.sidebar.write("Author :red[:] ", selected_book['Author'].values[0])
    st.sidebar.write("Rating :red[:] ", np.round(selected_book['Avg_Rating'].values[0],2),"(",str(selected_book['Num_Ratings'].values[0]),"votes)")
    st.sidebar.write("Publisher :red[:] ", selected_book['Publisher'].values[0])
    st.sidebar.write("Year :red[:] ", str(selected_book['Publication_Year'].values[0]))

# Defining the recommendation function
def recommend_book(book_name):
    # Fetch the index of the selected book
    index = np.where(book_pivot.index == book_name)[0][0]
    # Top 3 similar books
    similar_items = sorted(list(enumerate(model[index])), key=lambda x: x[1], reverse=True)[1:5]

    data = []
    for i in similar_items:
        item = []
        temp_df = final_rating[final_rating['Title'] == book_pivot.index[i[0]]]
        item.extend(list(temp_df.drop_duplicates('Title')['Title'].values))
        item.extend(list(temp_df.drop_duplicates('Title')['Author'].values))
        item.extend(list(temp_df.drop_duplicates('Title')['URL'].values))
        data.append(item)
    return data

# Create a dropdown to select a book
selected_books = st.selectbox(
    "**Type or select a book from the dropdown**",
    book_pivot.index.values
)

if st.button('Show Recommendation'):
    recommended_books  = recommend_book(selected_books)
    col1, col2, col3 = st.columns(3,gap="large")
    with col1:
        st.image(recommended_books[1][2])
        st.text(recommended_books[1][0])
        st.text(recommended_books[1][1])
    with col2:
        st.image(recommended_books[2][2])
        st.text(recommended_books[2][0])
        st.text(recommended_books[2][1])
    with col3:
        st.image(recommended_books[3][2])
        st.text(recommended_books[3][0])
        st.text(recommended_books[3][1])

hide_menu_style="""
            <style>
 #           #MainMenu {visibility: hidden;}
            footer {visibility:hidden;}
            </style>
            """
st.markdown(hide_menu_style, unsafe_allow_html=True)


import os
import random
from typing import *

import torch
import torchvision
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

from argparse import ArgumentParser
from tqdm import tqdm

import scallopy

class MNISTSort2Dataset(torch.utils.data.Dataset):
  mnist_img_transform = torchvision.transforms.Compose([
    torchvision.transforms.ToTensor(),
    torchvision.transforms.Normalize(
      (0.1307,), (0.3081,)
    )
  ])

  def __init__(
    self,
    root: str,
    train: bool = True,
    target_transform: Optional[Callable] = None,
    download: bool = False,
    max_digit: Optional[int] = None,
  ):
    # Contains a MNIST dataset
    self.mnist_dataset = torchvision.datasets.MNIST(
      root,
      train=train,
      transform=self.mnist_img_transform,
      target_transform=target_transform,
      download=download,
    )
    self.index_map = list(range(len(self.mnist_dataset)))
    random.shuffle(self.index_map)

    # Check if we want limited labels
    if max_digit is not None:
      self.index_map = [i for i in self.index_map if self.mnist_dataset[i][1] <= max_digit]

  def __len__(self):
    return int(len(self.index_map) / 2)

  def __getitem__(self, idx):
    # Get two data points
    (a_img, a_digit) = self.mnist_dataset[self.index_map[idx * 2]]
    (b_img, b_digit) = self.mnist_dataset[self.index_map[idx * 2 + 1]]

    # Each data has two images and the GT is the comparison result of two digits
    return (a_img, b_img, 0 if a_digit < b_digit else 1)

  @staticmethod
  def collate_fn(batch):
    a_imgs = torch.stack([item[0] for item in batch])
    b_imgs = torch.stack([item[1] for item in batch])
    cmp = torch.stack([torch.tensor(item[2]).long() for item in batch])
    return ((a_imgs, b_imgs), cmp)

def mnist_sort_2_loader(data_dir, batch_size, max_digit):
  train_loader = torch.utils.data.DataLoader(
    MNISTSort2Dataset(
      data_dir,
      train=True,
      download=True,
      max_digit=max_digit,
    ),
    collate_fn=MNISTSort2Dataset.collate_fn,
    batch_size=batch_size,
    shuffle=True,
  )

  test_loader = torch.utils.data.DataLoader(
    MNISTSort2Dataset(
      data_dir,
      train=False,
      download=True,
      max_digit=max_digit,
    ),
    collate_fn=MNISTSort2Dataset.collate_fn,
    batch_size=batch_size,
    shuffle=True,
  )

  return train_loader, test_loader

class MNISTNet(nn.Module):
  def __init__(self, num_classes=10):
    super(MNISTNet, self).__init__()
    self.conv1 = nn.Conv2d(1, 32, kernel_size=5)
    self.conv2 = nn.Conv2d(32, 64, kernel_size=5)
    self.fc1 = nn.Linear(1024, 1024)
    self.fc2 = nn.Linear(1024, num_classes)

  def forward(self, x):
    x = F.max_pool2d(self.conv1(x), 2)
    x = F.max_pool2d(self.conv2(x), 2)
    x = x.view(-1, 1024)
    x = F.relu(self.fc1(x))
    x = F.dropout(x, p=0.5, training=self.training)
    x = self.fc2(x)
    return F.softmax(x, dim=1)

class MNISTSort2Net(nn.Module):
  def __init__(self, provenance, train_k, test_k, max_digit=9):
    super(MNISTSort2Net, self).__init__()
    self.max_digit = max_digit
    self.num_classes = max_digit + 1

    # MNIST Digit Recognition Network
    self.mnist_net = MNISTNet(num_classes=self.num_classes)

    # Scallop Context
    self.scl_ctx = scallopy.ScallopContext(provenance=provenance, train_k=train_k, test_k=test_k)
    self.scl_ctx.add_relation("digit_1", int, input_mapping=list(range(self.num_classes)))
    self.scl_ctx.add_relation("digit_2", int, input_mapping=list(range(self.num_classes)))
    self.scl_ctx.add_rule("less_than(a < b) = digit_1(a), digit_2(b)")

    # The `less_than` logical reasoning module
    self.less_than = self.scl_ctx.forward_function("less_than", [True, False])

  def forward(self, x: Tuple[torch.Tensor, torch.Tensor]):
    (a_imgs, b_imgs) = x

    # First recognize the two digits
    a_distrs = self.mnist_net(a_imgs)
    b_distrs = self.mnist_net(b_imgs)

    # Then execute the reasoning module; the result is a size 2 tensor
    return self.less_than(digit_1=a_distrs, digit_2=b_distrs)

def bce_loss(output, ground_truth):
  (_, dim) = output.shape
  gt = torch.stack([torch.tensor([1.0 if i == t else 0.0 for i in range(dim)]) for t in ground_truth])
  return F.binary_cross_entropy(output, gt)

def nll_loss(output, ground_truth):
  return F.nll_loss(output, ground_truth)

class Trainer():
  def __init__(self, train_loader, test_loader, model_dir, learning_rate, loss, train_k, test_k, provenance, max_digit=9):
    self.network = MNISTSort2Net(provenance, train_k=train_k, test_k=test_k, max_digit=max_digit)
    self.optimizer = optim.Adam(self.network.parameters(), lr=learning_rate)
    self.train_loader = train_loader
    self.test_loader = test_loader
    self.model_dir = model_dir
    self.min_test_loss = 100000000.0
    if loss == "nll": self.loss = nll_loss
    elif loss == "bce": self.loss = bce_loss
    else: raise Exception(f"Unknown loss function `{loss}`")

  def train(self, epoch):
    self.network.train()
    iter = tqdm(self.train_loader, total=len(self.train_loader))
    for (data, target) in iter:
      self.optimizer.zero_grad()
      output = self.network(data)
      loss = self.loss(output, target)
      loss.backward()
      self.optimizer.step()
      iter.set_description(f"[Train Epoch {epoch}] Loss: {loss.item():.4f}")

  def test(self, epoch):
    self.network.eval()
    num_items = len(self.test_loader.dataset)
    test_loss = 0
    correct = 0
    with torch.no_grad():
      iter = tqdm(self.test_loader, total=len(self.test_loader))
      for (data, target) in iter:
        output = self.network(data)
        test_loss += self.loss(output, target).item()
        pred = output.data.max(1, keepdim=True)[1]
        correct += pred.eq(target.data.view_as(pred)).sum()
        perc = 100. * correct / num_items
        iter.set_description(f"[Test Epoch {epoch}] Total loss: {test_loss:.4f}, Accuracy: {correct}/{num_items} ({perc:.2f}%)")
    if test_loss < self.min_test_loss:
      self.min_test_loss = test_loss
      torch.save(self.network, os.path.join(self.model_dir, "mnist_sort_2_net.pkl"))

  def run(self, n_epochs):
    self.test(0)
    for epoch in range(1, n_epochs + 1):
      self.train(epoch)
      self.test(epoch)

if __name__ == "__main__":
  # Argument parser
  parser = ArgumentParser("mnist_sort_2")
  parser.add_argument("--n-epochs", type=int, default=10)
  parser.add_argument("--batch-size", type=int, default=64)
  parser.add_argument("--learning-rate", type=float, default=0.0001)
  parser.add_argument("--loss-fn", type=str, default="bce")
  parser.add_argument("--seed", type=int, default=1234)
  parser.add_argument("--provenance", type=str, default="difftopkproofs")
  parser.add_argument("--train-k", type=int, default=3)
  parser.add_argument("--test-k", type=int, default=3)
  parser.add_argument("--max-digit", type=int, default=9)
  args = parser.parse_args()

  # Parameters
  torch.manual_seed(args.seed)
  random.seed(args.seed)

  # Directories
  data_dir = os.path.abspath(os.path.join(os.path.abspath(__file__), "../../../data"))
  model_dir = os.path.abspath(os.path.join(os.path.abspath(__file__), "../../../model/mnist_sort_2"))
  if not os.path.exists(model_dir): os.mkdir(model_dir)

  # Dataloaders
  train_loader, test_loader = mnist_sort_2_loader(data_dir, args.batch_size, max_digit=args.max_digit)

  # Create trainer and train
  trainer = Trainer(train_loader, test_loader, model_dir, args.learning_rate, args.loss_fn, args.train_k, args.test_k, args.provenance, max_digit=args.max_digit)
  trainer.run(args.n_epochs)