from concurrent.futures import ThreadPoolExecutor
import numpy as np
import torch
from agent import ActionPredictionNetwork, R2D2Agent, RNDNetwork
from batched_layer import BatchedLayer
from config import Config
from data_type import AgentInputData, DataType, SelectActionOutput
from local_buffer import LocalBuffer
from loss_and_action import LossAndAction
from models import Agent57Network
from reward_generator import RewardGenerator
from shared_data import SharedActorData
from torch.utils.tensorboard import SummaryWriter
import zstandard as zstd

from utils import get_agent_input_burn_in_from_transition, get_agent_input_from_transition, get_loss_input_for_train, get_beta_table, get_gamma_table, get_loss_input_for_replay, to_agent_input

def eval_loop(shared_infer_net, predict_net, embedding_net, config: Config,
              shared_actor_data: SharedActorData, device):
  shared_actor_data.shared.get_shared_memory()
  batch_size = 1

  RND_net = RNDNetwork(device, config, predict_net)
  ids = [0]
  beta_table = get_beta_table(config)
  rng = np.random.default_rng()

  action_getter = LossAndAction((1, 1, config.action_space), device, config)

  executor = ThreadPoolExecutor()

  infer_net = Agent57Network(device, config)
  infer_net.set_weight(*shared_infer_net.get_weight())

  reward_generator = RewardGenerator(batch_size, config, device)

  e_prev_lstm_states, i_prev_lstm_states = infer_net.initial_state(batch_size)
  prev_actions = rng.integers(config.action_space, size=len(ids))

  _, actor_output = shared_actor_data.get_actor_data()
  agent_input_data = AgentInputData(
    state=np.expand_dims(actor_output.next_state, axis=1),
    prev_action=prev_actions.reshape(batch_size, 1),
    e_prev_reward=actor_output.reward.reshape(batch_size, 1, 1),
    i_prev_reward=actor_output.reward.reshape(batch_size, 1, 1),
    meta_index=actor_output.meta_index.reshape(batch_size, 1),
    e_lstm_states=e_prev_lstm_states,
    i_lstm_states=i_prev_lstm_states,
  )

  beta = torch.from_numpy(beta_table[agent_input_data.meta_index]).to(device)
  e_input, i_input = to_agent_input(agent_input_data, device)
  reward_input = reward_generator.input_for_reward(agent_input_data.state)

  # ここからGPU（非同期）
  with torch.no_grad():
    e_qvalues, e_lstm_state = infer_net.e_net(e_input)
    i_qvalues, i_lstm_state = infer_net.i_net(i_input)
    RND_loss = RND_net.get_loss(reward_input)
    controllable_state = embedding_net(reward_input)
  # ここまで

  # 内的報酬取得
  future_intrinsic_reward = executor.submit(reward_generator.get_intrinsic_reward, ids, RND_loss, controllable_state)

  select_action_output: SelectActionOutput = infer_net.select_actions(
    e_qvalues, e_lstm_state, i_qvalues, i_lstm_state,
    config.eval_epsilon, beta, batch_size, action_getter)

  shared_actor_data.put_action(select_action_output.action[0])

  prev_actions = select_action_output.action
  e_prev_lstm_states = select_action_output.e_lstm_states
  i_prev_lstm_states = select_action_output.i_lstm_states

  episode_count = 0

  while True:
    _, actor_output = shared_actor_data.get_actor_data()

    i_reward = future_intrinsic_reward.result()

    agent_input_data = AgentInputData(
      state=np.expand_dims(actor_output.next_state, axis=1),
      prev_action=prev_actions.reshape(batch_size, 1),
      e_prev_reward=actor_output.reward.reshape(batch_size, 1, 1),
      i_prev_reward=i_reward.reshape(batch_size, 1, 1),
      meta_index=actor_output.meta_index.reshape(batch_size, 1),
      e_lstm_states=e_prev_lstm_states,
      i_lstm_states=i_prev_lstm_states,
    )

    beta = torch.from_numpy(beta_table[agent_input_data.meta_index]).to(device)

    e_input, i_input = to_agent_input(agent_input_data, device)
    reward_input = reward_generator.input_for_reward(agent_input_data.state)

    # ここからGPU（非同期）
    with torch.no_grad():
      e_qvalues, e_lstm_state = infer_net.e_net(e_input)
      i_qvalues, i_lstm_state = infer_net.i_net(i_input)
      RND_loss = RND_net.get_loss(reward_input)
      controllable_state = embedding_net(reward_input)
    # ここまで

    # 内的報酬取得
    future_intrinsic_reward = executor.submit(reward_generator.get_intrinsic_reward, ids, RND_loss, controllable_state)

    select_action_output: SelectActionOutput = infer_net.select_actions(
      e_qvalues, e_lstm_state, i_qvalues, i_lstm_state,
      config.eval_epsilon, beta, batch_size, action_getter)

    shared_actor_data.put_action(select_action_output.action[0])

    if actor_output.done:
      episode_count += 1
      e_prev_lstm_states, i_prev_lstm_states = infer_net.initial_state(batch_size)
      prev_actions = rng.integers(config.action_space, size=len(ids))
      prev_actions = np.zeros((batch_size, 1), dtype=np.uint8)
      reward_generator.reset(ids)

      if episode_count % config.eval_update_period == 0:
        infer_net.set_weight(*shared_infer_net.get_weight())

    else:
      prev_actions = select_action_output.action
      e_prev_lstm_states = select_action_output.e_lstm_states
      i_prev_lstm_states = select_action_output.i_lstm_states

def inference_loop(actor_indexes, shared_infer_net, predict_net, embedding_net, transition_queue, shared_actor_datas, device, config: Config):
  data_type = DataType(config)
  cctx = zstd.ZstdCompressor(write_content_size=data_type.transition_dtype.itemsize)

  RND_net = RNDNetwork(device, config, predict_net)

  # この推論プロセスで使う環境IDリストを得る
  env_ids = np.arange(
    actor_indexes[0] * config.num_env_batches,
    actor_indexes[-1] * config.num_env_batches + config.num_env_batches
  )
  first_env_id = env_ids[0]
  ids = env_ids - first_env_id

  batch_size = len(env_ids)
  rng = np.random.default_rng()

  action_getter = LossAndAction((batch_size, 1, config.action_space), device, config)
  executor = ThreadPoolExecutor()

  infer_net = Agent57Network(device, config)
  infer_net.set_weight(*shared_infer_net.get_weight())

  reward_generator = RewardGenerator(batch_size, config, device)

  beta_table = get_beta_table(config)
  gamma_table = get_gamma_table(config)

  for shared_actor_data in shared_actor_datas:
    shared_actor_data.shared.get_shared_memory()

  local_buffer = LocalBuffer(batch_size, config, reward_generator)
  batched_layer = BatchedLayer(env_ids, shared_actor_datas, config)

  e_prev_lstm_states, i_prev_lstm_states = infer_net.initial_state(batch_size)
  prev_actions = rng.integers(config.action_space, size=len(ids))
  prev_meta_indexes = np.zeros(batch_size, dtype=int)

  batched_actor_output = batched_layer.wait_actor_outputs(first_env_id)

  # batched_env_output.next_state(t),
  # meta_indexes(t),
  # batched_env_output.reward(t - 1),
  # batched_env_output.done(t - 1)

  # prev_actions(t - 1),
  # prev_hidden_states(t - 1)
  # prev_cell_states(t - 1)

  agent_input_data = AgentInputData(
    state=np.expand_dims(batched_actor_output.next_state, axis=1),
    prev_action=prev_actions.reshape(batch_size, 1),
    e_prev_reward=batched_actor_output.reward.reshape(batch_size, 1, 1),
    i_prev_reward=batched_actor_output.reward.reshape(batch_size, 1, 1),
    meta_index=batched_actor_output.meta_index.reshape(batch_size, 1),
    e_lstm_states=e_prev_lstm_states,
    i_lstm_states=i_prev_lstm_states,
  )

  # agent_input_data.state(t),
  # agent_input_data.prev_action(t - 1),
  # agent_input_data.e_prev_reward(t - 1),
  # agent_input_data.i_prev_reward(t - 1),
  # agent_input_data.hidden_state(t - 1),
  # agent_input_data.cell_state(t - 1),

  beta = torch.from_numpy(beta_table[agent_input_data.meta_index]).to(device)

  e_input, i_input = to_agent_input(agent_input_data, device)
  reward_input = reward_generator.input_for_reward(agent_input_data.state)

  # ここからGPU（非同期）
  with torch.no_grad():
    e_qvalues, e_lstm_state = infer_net.e_net(e_input)
    i_qvalues, i_lstm_state = infer_net.i_net(i_input)
    RND_loss = RND_net.get_loss(reward_input)
    controllable_state = embedding_net(reward_input)
  # ここまで

  # 内的報酬取得
  future_intrinsic_reward = executor.submit(reward_generator.get_intrinsic_reward, ids, RND_loss, controllable_state)

  select_action_output: SelectActionOutput = infer_net.select_actions(
    e_qvalues, e_lstm_state, i_qvalues, i_lstm_state,
    beta_table[batched_actor_output.meta_index], beta, batch_size, action_getter)

  # select_action_output.action(t)
  # select_action_output.qvalue(t)
  # select_action_output.policy(t)
  # select_action_output.hidden_states(t)
  # select_action_output.cell_states(t)

  batched_layer.send_actions(select_action_output.action)

  steps = 0
  while True:
    steps += 1

    prev_meta_indexes[:] = batched_actor_output.meta_index
    batched_actor_output = batched_layer.wait_actor_outputs(first_env_id)
    # batched_env_output.next_state(t + 1),
    # meta_indexes(t + 1),
    # prev_meta_indexes(t),
    # batched_env_output.reward(t),
    # batched_env_output.done(t)

    i_reward = future_intrinsic_reward.result()
    ret = local_buffer.add(agent_input_data, select_action_output, batched_actor_output, prev_meta_indexes, i_reward)
    if ret and transition_queue.qsize() < config.num_train_envs:
      transitions, qvalues = ret
      qvalues = torch.from_numpy(qvalues[:, config.replay_period:]).to(torch.float32).to(device)
      loss_getter = LossAndAction(qvalues.shape, device, config)

      input = get_loss_input_for_replay(transitions, config, device, beta_table, gamma_table)

      losses = loss_getter.retrace_loss(
        input=input,
        behaviour_qvalues=qvalues,
        target_qvalues=qvalues,
        target_policy_qvalue=qvalues)

      losses = losses.cpu().detach().numpy().copy()

      #: replay_bufferに遷移情報を蓄積
      for loss, transition in zip(losses, transitions):
        transition_queue.put((loss, cctx.compress(transition.tobytes())))

    agent_input_data = local_buffer.get_agent_input()

    beta = torch.from_numpy(beta_table[agent_input_data.meta_index]).to(device)
    e_input, i_input = to_agent_input(agent_input_data, device)
    reward_input = reward_generator.input_for_reward(agent_input_data.state)

    # ここからGPU（非同期）
    with torch.no_grad():
      e_qvalues, e_lstm_state = infer_net.e_net(e_input)
      i_qvalues, i_lstm_state = infer_net.i_net(i_input)
      RND_loss = RND_net.get_loss(reward_input)
      controllable_state = embedding_net(reward_input)
    # ここまで

    # 内的報酬取得
    future_intrinsic_reward = executor.submit(reward_generator.get_intrinsic_reward, ids, RND_loss, controllable_state)

    select_action_output: SelectActionOutput = infer_net.select_actions(
      e_qvalues, e_lstm_state, i_qvalues, i_lstm_state,
      beta_table[batched_actor_output.meta_index], beta, batch_size, action_getter)

    # select_action_output.action(t + 1)
    # select_action_output.hidden_states(t + 1)
    # select_action_output.cell_states(t + 1)

    # 選択アクションをアクターに送信
    batched_layer.send_actions(select_action_output.action)

    if steps % config.infer_update_period == 0:
      infer_net.set_weight(*shared_infer_net.get_weight())

def train_loop(rank, infer_net, predict_net, embedding_net, sample_queue, priority_queue, device, config: Config):
  if rank == 0:
    summary_writer = SummaryWriter("logs")

  e_weight, i_weight = infer_net.get_weight()

  e_agent = R2D2Agent(device, config)
  e_agent.set_weight(e_weight)

  i_agent = R2D2Agent(device, config)
  i_agent.set_weight(i_weight)

  RND_net = RNDNetwork(device, config, predict_net)
  action_prediction_net = ActionPredictionNetwork(device, config, embedding_net)

  beta_table = get_beta_table(config)
  gamma_table = get_gamma_table(config)

  loss_getter = LossAndAction((config.batch_size, config.trace_length + 1, config.action_space), device, config)

  steps = 0

  while True:
    #: リプレイバッファからミニバッチを取得
    indexes, transitions, is_weights = sample_queue.get()

    e_input, i_input = get_agent_input_burn_in_from_transition(transitions, device, config)
    input = get_agent_input_from_transition(transitions, device, config)

    e_online_qvalue, e_target_qvalue = e_agent.get_qvalues(e_input, input)
    i_online_qvalue, i_target_qvalue = i_agent.get_qvalues(i_input, input)

    loss_input = get_loss_input_for_replay(transitions, config, device, beta_table, gamma_table)

    # リプレイのための統一損失
    beta = loss_input.beta.unsqueeze(-1)
    online_qvalue = e_online_qvalue + beta * i_online_qvalue
    target_qvalue = e_target_qvalue + beta * i_target_qvalue
    losses = loss_getter.retrace_loss(loss_input, online_qvalue, target_qvalue, target_qvalue)

    priority_queue.put((indexes, losses.cpu().detach().numpy()))

    loss = (torch.tensor(is_weights, device=device) * losses).mean(0)

    # 訓練のための個別損失
    e_loss_input, i_loss_input = get_loss_input_for_train(transitions, config, device, beta_table, gamma_table)
    e_losses = loss_getter.retrace_loss(e_loss_input, e_online_qvalue, e_target_qvalue, target_qvalue)
    i_losses = loss_getter.retrace_loss(i_loss_input, i_online_qvalue, i_target_qvalue, target_qvalue)

    # seq sum -> batch mean
    e_loss = (torch.tensor(is_weights, device=device) * e_losses).mean(0)
    i_loss = (torch.tensor(is_weights, device=device) * i_losses).mean(0)

    # 訓練
    action_prediction_net.train(transitions)
    RND_net.train(transitions)
    e_agent.train(e_loss)
    i_agent.train(i_loss)

    del transitions

    # 推論モデル更新
    if rank == 0:
      summary_writer.add_scalar("loss", loss, steps)
      infer_net.set_weight(e_agent.online_net.get_weight(), i_agent.online_net.get_weight())

    steps += 1

    #: target-QネットワークをQネットワークと同期
    if steps % config.target_update_period == 0:
      e_agent.update_target()
      i_agent.update_target()


import tensorflow as tf

a = tf.placeholder('float')
b = tf.placeholder('float')

y = tf.multiply(a, b)

sess = tf.Session()

print(sess.run(y, feed_dict={a: 3, b: 3}))

"""
- tensor란 동적 크기를 갖는 다차원 데이터 배열
- 심벌릭 표현으로 된 수식을 계산하기 위해서 session 생성, session.run() 하고 나서야 실행
- 즉, 전체 알고리즘을 먼저 기술하고 그 다음 세션을 생성하여 연산을 실행
"""


def is_palindrome(word):
    # Menghapus spasi dan mengubah huruf menjadi huruf kecil
    clean_word = word.lower().replace(" ", "")

    # Membandingkan kata dengan kebalikannya
    return clean_word == clean_word[::-1]

# to check the plaindrome word
while True:
    kata_input = input("Masukkan kata (q for exit): ")
    if kata_input == "q":
        print("You exited the program")
        break
    if is_palindrome(kata_input):
        print(f"{kata_input} adalah palindrome")
    else:
        print(f"{kata_input} adalah bukan palindrome")


"""
This is a movement utility class that encapsulates movements into an image list and adds some methods
for manipulating the movement, such as interval-based image extraction.
"""
import numpy as np
import os
import sys
import shutil
import re
from collections import Counter

class Image(object):
    def __init__(self, atom_type=None, atom_num = None, iteration=None, Etot = None, Ep = None, Ek = None, scf = None) -> None:
        #76 atoms,Iteration (fs) =   -0.1000000000E+01, Etot,Ep,Ek (eV) =   -0.1335474369E+05  -0.1335474369E+05   0.0000000000E+00, SCF =    14
        self.atom_num = atom_num
        self.iteration = iteration
        self.atom_type = atom_type
        self.Etot = Etot
        self.Ep = Ep
        self.Ek = Ek
        self.scf = scf
        self.lattice = []
        self.stress = []
        self.position = []
        self.force = []
        self.atomic_energy = []
        self.content = []

    def set_md_info(self, method = None ,time = None ,temp = None ,desired_temp = None ,avg_temp = None ,time_interval = None ,tot_temp = None):
        #  MD_INFO: METHOD(1-VV,2-NH,3-LV,4-LVPR,5-NHRP) TIME(fs) TEMP(K) DESIRED_TEMP(K) AVE_TEMP(K) TIME_INTERVAL(fs) TOT_TEMP(K)
        #   2    0.1000000000E+01   0.19941E+04   0.10000E+04   0.19941E+04   0.10000E+03   0.19941E+04\
        self.method = method
        self.time = time
        self.temp = temp
        self.desired_temp = desired_temp
        self.avg_temp = avg_temp
        self.time_interval = time_interval
        self.tot_temp = tot_temp

    def set_energy_info(self, energy_content):
        # "76 atoms,Iteration (fs) =   -0.1000000000E+01, Etot,Ep,Ek (eV) =   -0.1335474369E+05  -0.1335474369E+05   0.0000000000E+00, SCF =    14"
        # after re extract, numbers = ['76', '-0.1000000000E+01', '-0.1335474369E+05', '-0.1335474369E+05', '0.0000000000E+00', '14']
        numbers = re.findall(r"[-+]?\d+(?:\.\d+)?(?:[eE][-+]?\d+)?", energy_content)
        self.atom_num = int(numbers[0])
        self.iteration = format(float(numbers[1]), '.2f')
        self.Etot, self.Ep, self.Ek = float(numbers[2]), float(numbers[3]), float(numbers[4])
        if len(numbers) >= 5:
            self.scf = int(numbers[5])
        # self.content.append(energy_content)

    def set_lattice_stress(self, lattice_content):
        lattic1 = [float(_) for _ in re.findall(r"[-+]?\d+(?:\.\d+)?(?:[eE][-+]?\d+)?", lattice_content[0])]
        lattic2 = [float(_) for _ in re.findall(r"[-+]?\d+(?:\.\d+)?(?:[eE][-+]?\d+)?", lattice_content[1])]
        lattic3 = [float(_) for _ in re.findall(r"[-+]?\d+(?:\.\d+)?(?:[eE][-+]?\d+)?", lattice_content[2])]
        if "stress" in lattice_content[0]:
            self.stress = [lattic1[3:], lattic2[3:], lattic3[3:]]
        self.lattice = [lattic1[:3], lattic2[:3], lattic3[:3]]
        # self.content.append(lattice_content)

    def set_position(self, position_content):
        atom_type = []
        for i in range(0, len(position_content)):
            numbers = re.findall(r"[-+]?\d+(?:\.\d+)?", position_content[i])
            atom_type.append(int(numbers[0]))
            self.position.append([float(_) for _ in numbers[1:4]])
        counter = Counter(atom_type)
        self.atom_type = list(counter.keys())
        self.atom_type_num = list(counter.values())
        assert self.atom_num == sum(self.atom_type_num)
        # self.content.append(position_content)

    def set_force(self, force_content):
        for i in range(0, len(force_content)):
            numbers = re.findall(r"[-+]?\d+(?:\.\d+)?", force_content[i])
            self.force.append([float(_) for _ in numbers[1:4]])
        assert self.atom_num == len(self.force)

    def set_atomic_energy(self, atomic_energy):
        for i in range(0, len(atomic_energy)):
            numbers = re.findall(r"[-+]?\d+(?:\.\d+)?", atomic_energy[i])
            self.atomic_energy.append(float(numbers[1]))
        assert self.atom_num == len(self.atomic_energy)

    def set_content(self, content):
        self.content = content

class MOVEMENT(object):
    def __init__(self, movement_file) -> None:
        self.image_list:list[Image] = []
        self.image_nums = 0
        self.load_movement_file(movement_file)

    '''
    description:
        load movement file, seperate the file to each image contents and get the image nums
    param {*} self
    param {*} movement_file
    return {*}
    author: wuxingxing
    '''
    def load_movement_file(self, movement_file):
        # seperate content to image contents
        with open(movement_file, 'r') as rf:
            mvm_contents = rf.readlines()
        i = 0
        while i < len(mvm_contents):
            image_start = i
            if "Iteration" in mvm_contents[i]:
                # set energy info
                image = Image()
                self.image_list.append(image)
                image.set_energy_info(mvm_contents[i])
                i += 1
            if "Lattice" in mvm_contents[i]:
                # three line for lattic info
                image.set_lattice_stress(mvm_contents[i+1:i+4])
                i += 4
            if " Position" in mvm_contents[i]:
                # atom_nums line for postion
                image.set_position(mvm_contents[i+1:i+image.atom_num+1])
                i = i + 1 + image.atom_num
            if "Force" in mvm_contents[i]:
                image.set_force(mvm_contents[i+1: i+ image.atom_num+1])
                i = i + 1 + image.atom_num
            if "Atomic-Energy" in mvm_contents[i]:
                image.set_atomic_energy(mvm_contents[i+1: i+ image.atom_num+1])
                i = i + 1 + image.atom_num

            # image content end at the line "------------END"
            while "-------------" not in mvm_contents[i]:
                i += 1
            i += 1
            image_end = i
            image.set_content(mvm_contents[image_start:image_end])

        self.image_nums = len(self.image_list)

    '''
    description:
        Sample the movement file according to the interval value and save the sampled result to file
    param {*} self
    param {*} save_file
    param {*} interval
    return {*}
    author: wuxingxing
    '''
    def save_image_interval(self, save_file, interval=1):
         with open(save_file, 'w') as wf:
             for i in range(0, self.image_nums):
                 if i % interval == 0:
                    for line in self.image_list[i].content:
                        wf.write(line)

if __name__ == "__main__":
    source_movement_file = sys.argv[1]
    save_movement_file = sys.argv[2]
    interval = int(sys.argv[3])
    mvm = MOVEMENT(source_movement_file)
    mvm.save_image_interval(save_movement_file, interval=interval)


import os
import random
import shutil
from argparse import ArgumentParser
from datetime import datetime

import matplotlib.pyplot as plt
import numpy as np
import torch
from pytorch_fid.fid_score import calculate_fid_given_paths
from torch.utils.data import DataLoader
from torch.utils.data.dataset import Subset
from torchvision import transforms
from torchvision.datasets import MNIST
from torchvision.utils import save_image
from tqdm import tqdm, trange

from gan import Generator
from train import concat_noise_label

parser =  ArgumentParser()
parser.add_argument('-g', '--gpu-num', type=int, help='what gpu to use', default=0)
parser.add_argument('-s', '--num_samples', type=int, help="number of samples used for culcurating fid score", default=10000)
parser.add_argument('-c', '--conditional', action="store_true", help="Conditional GAN")
parser.add_argument('-z', '--nz', type=int, help='size of the latent z vector', default=16)
parser.add_argument('-e', '--epoch', type=int, help="upper limit of epoch to calculate FID", default=10000)
parser.add_argument('method', choices=['central', 'fl', 'wafl', 'self'])

def fid(epochs, basedir, real_path, device, method, conditional, num_batch, batch_size, nz, node=0):
    fake_path = os.path.join(basedir, 'fake')
    fid_vals = []

    G = Generator(nz, conditional=conditional).to(device)

    for e in epochs:
        g_path = f'nets/{method}/{"cgan" if conditional else "gan"}/g_e{e}_z{nz}{f"_n{node}" if method in ["wafl", "self"] else "" }.pth'
        G.load_state_dict(torch.load(g_path))

        os.makedirs(fake_path)

        # prepare fake images
        for i in trange(num_batch, desc=f"preparing fake images (epoch {e})"):
            noise = torch.randn(batch_size, nz, 1, 1, device=device)
            fake_label = torch.randint(10, (batch_size,), dtype=torch.long, device=device)
            fake_input_noise = concat_noise_label(noise, fake_label, device) if conditional else noise
            fake_images = G(fake_input_noise)

            for j, (image, label) in enumerate(zip(fake_images, fake_label)):
                save_image([image], os.path.join(fake_path, f'{batch_size * i + j}_{label}.png'))

        fid_val = calculate_fid_given_paths([real_path, fake_path], 256, device, 2048, 8)
        fid_vals.append(fid_val)
        shutil.rmtree(fake_path)

    return fid_vals

def prepare_real(basedir, batch_size, num_batch, device):
    real_path = os.path.join(basedir, 'real')

    os.makedirs(real_path)

    # prepare real images
    dataset = MNIST(root='data', train=True, download=True, transform=transforms.ToTensor())
    indices = random.sample(list(range(60000)), batch_size * num_batch)
    subset = Subset(dataset, indices=indices)
    dataloader = DataLoader(subset, batch_size=batch_size, shuffle=True, num_workers=2)
    for i, (images, labels) in tqdm(enumerate(dataloader), total=num_batch, desc="preparing real images"):
        images = images.to(device)
        labels = labels.to(device)
        for j, (image, label) in enumerate(zip(images, labels)):
            save_image([image], os.path.join(real_path, f'{i}_{label}.png'))

    return real_path

def main():
    args = parser.parse_args()

    conditional = args.conditional
    nz = args.nz
    num_sumples = args.num_samples
    epoch = args.epoch
    method = args.method
    batch_size = 256
    num_batch = num_sumples // batch_size + 1

    device = torch.device(f"cuda:{args.gpu_num}" if torch.cuda.is_available() else "cpu")

    basedir = 'tmp_' + str(datetime.now())
    real_path = prepare_real(basedir, batch_size, num_batch, device)

    epochs = list(range(0, epoch+1, 50 if method == "wafl" else 50 if method == "fl" else 10))
    fid_vals = fid(epochs, basedir, real_path, device, method, conditional, num_batch, batch_size, nz)

    shutil.rmtree(basedir)

    basefilename = f'{method}_{"cgan" if conditional else "gan"}_e{epoch}_z{nz}'
    np.save(os.path.join("graphs", basefilename + ".npy"), np.array([epochs, fid_vals]))

    plt.plot(epochs, fid_vals)
    plt.ylabel('FID score')
    plt.xlabel('Epoch')
    plt.savefig(os.path.join("graphs", basefilename + ".png"), bbox_inches='tight')

if __name__ == '__main__':
    main()


from helper import *

@TestInstance
def test_fmtprint():
    name = EUDVariable(Db("dpdkfah"))
    amount = EUDVariable(336)
    resource = EUDArray([EPD(Db("minerals")), EPD(Db("gases"))])
    f_setcurpl(P1)
    f_eprintAll("{:s} gets {} {:t}.", name, amount, resource[0])
    errorline = 0x640B60 + 218 * 12

    expect = "dpdkfah\r gets \r\r336\r \r\r\rminerals.\r\r\r"
    expectdb = Db(expect)
    test_equality("f_eprintf test1", f_strlen(errorline), len(expect))
    test_equality("f_eprintf test2", f_memcmp(errorline, expectdb, len(expect)), 0)


#!/usr/bin/env python

import rospy
from nav_msgs.msg import Odometry
from geometry_msgs.msg import Pose, Twist, Transform, TransformStamped, Pose2D
from gazebo_msgs.msg import LinkStates
from std_msgs.msg import Header
import numpy as np
from numpy import dot
import math
import tf
from racecar_control.msg import drive_param
import scipy.linalg as la
from cmath import phase, exp

waypoints = [[1.147, 1.364], [-3.968, 5.635], [-3.900, 9.532], [-3.131, 12.867]] #Gazebo
#waypoints = [[0.410, -2.703], [2.944, 3.444], [6.689, 4.616], [10.100, 4.947]] #Lidar

# LQR parameter
Q = np.eye(4)
R = np.eye(1)

# parameters
dt = 0.1
L = 0.5 # Wheel base of the vehicle [m]
max_steer = 0.7
velocity = 5.0

def pi_2_pi(angle):
    return (angle + math.pi) % (2 * math.pi) - math.pi

def solve_DARE(A, B, Q, R):
    """
    solve a discrete time_Algebraic Riccati equation (DARE)
    """
    X = Q
    maxiter = 150
    eps = 0.01

    for i in range(maxiter):
        Xn = dot(dot(A.T, X), A) - dot(dot(dot(dot(dot(dot(A.T, X), B),
            la.inv(R + dot(dot(B.T, X), B))), B.T), X), A) + Q
        if (abs(Xn - X)).max() < eps:
            break
        X = Xn

    return Xn

def dlqr(A, B, Q, R):
    """
    x[k+1] = A x[k] + B u[k]
    cost = sum x[k].T*Q*x[k] + u[k].T*R*u[k]
    # ref Bertsekas, p.151
    """

    # first, try to solve the ricatti equation
    X = solve_DARE(A, B, Q, R)

    # compute the LQR gain
    K = dot(la.inv(dot(dot(B.T, X), B) + R), dot(dot(B.T, X), A))

    eigVals, eigVecs = la.eig(A - dot(B, K))

    return K, X, eigVals

def lqr_steering_control(x, y, yaw, waypoints, index, pe, pth_e):
    e, th_e, index = calc_error(x, y, yaw, waypoints, index)
    rospy.loginfo("e: %lf, th_e: %lf", e, th_e)

    k = 0
    v = velocity

    A = np.zeros((4, 4))
    A[0, 0] = 1.0
    A[0, 1] = dt
    A[1, 2] = v
    A[2, 2] = 1.0
    A[2, 3] = dt

    B = np.zeros((4, 1))
    B[3, 0] = v/L

    K, _, _ = dlqr(A, B, Q, R)

    x = np.zeros((4, 1))

    x[0, 0] = e
    x[1, 0] = (e - pe) / dt
    x[2, 0] = th_e
    x[3, 0] = (th_e - pth_e) / dt

    ff = math.atan2(L * k, 1)
    fb = pi_2_pi((dot(-K, x))[0, 0])

    delta = ff + fb

    return delta, e, th_e, index

def calc_error(x, y ,yaw, waypoints, index):
    """
    Compute distance error and theta error given current state
    """

    min_distance_error = float('inf')
    i = index + 1
    # Vector from closest passed waypoint to the next waypoint
    q = np.array([waypoints[i][0] - waypoints[i-1][0], waypoints[i][1] - waypoints[i-1][1]])
    # Vector from car position to the closest passed waypoint
    c = np.array([x - waypoints[i-1][0], y - waypoints[i-1][1]])
    # Vector from current posiition to teh next waypoint
    togo = np.array([x - waypoints[i][0], y - waypoints[i][1]])
    waypoint_distance = np.linalg.norm(togo)

    if np.linalg.norm(c) == 0:
        # If the car is on the waypoint, return distance error 0
        min_distance_error = 0
    else:
        # Project c to q
        proj_q_c = (np.dot(q, c)/ np.linalg.norm(q)) * (q/ np.linalg.norm(q))
        # Compute the vertical distance from the car to the path
        distance_error = np.linalg.norm(c - proj_q_c)
        min_distance_error = distance_error

    # Compute orientation error
    orientation_vector = exp(1j * yaw)
    q = q[0] + 1j * q[1]
    c = c[0] + 1j * c[1]

    theta_error = phase(q/ orientation_vector)
    if theta_error < 0:
        min_distance_error *= -1

    # Configurable tolerance
    if waypoint_distance < 0.3:
        index = min(index + 1, len(waypoints) - 2)

    return min_distance_error, theta_error, index

class Pose_listener:

    def __init__ (self):
        self.listener = rospy.Subscriber('/Car_Pose_gazebo', Pose2D, self.get_Pose)
        self.pose = Pose2D()
        self.pose.x = 1.147
        self.pose.y = 1.364
        self.pose.theta = 2.794
    def get_Pose(self, data):
        self.pose = data

def closed_loop_prediction(waypoints):
    rospy.init_node("path_tracking")

    listener = tf.TransformListener()
    listener.waitForTransform('/map', '/base_link', rospy.Time(), rospy.Duration(20.0))

    pub = rospy.Publisher('drive_parameters', drive_param, queue_size=10)
    index = 0
    pe = 0
    pth_e = 0

    gazebo_pose = Pose_listener()

    while not rospy.is_shutdown():
        t = listener.getLatestCommonTime('/map', '/base_link')
        if listener.canTransform('/map', '/base_link', t):
            position, quaternion = listener.lookupTransform('/map', '/base_link', t)
            rpy = tf.transformations.euler_from_quaternion(quaternion)
            #x = position[0]
            #y = position[1]
            #yaw = rpy[2]
            x = gazebo_pose.pose.x
            y = gazebo_pose.pose.y
            yaw = gazebo_pose.pose.theta
            delta, e, th_e, index = lqr_steering_control(x, y, yaw, waypoints, index, pe, pth_e)
            if delta > max_steer:
                delta = max_steer
            elif delta < -max_steer:
                delta = -max_steer
            pe = e
            pth_e = th_e

            msg = drive_param()
            if np.linalg.norm([x - waypoints[-1][0], y - waypoints[-1][1]]) < 0.3:
                msg.velocity = 0
                rospy.signal_shutdown("the car has reach the goal")
            else:
                msg.velocity = velocity
            msg.angle = -delta
            pub.publish(msg)

if __name__ == '__main__':
    closed_loop_prediction(waypoints)


# -*- coding: utf-8 -*-
"""
Created on Mon Mar 20 13:40:01 2023

@author: oscar
"""

import os
import sys
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import flopy
from flopy.utils.triangle import Triangle as trng
import geopandas as gpd
from shapely.geometry import Polygon
import sfrmaker
import pandas as pd
import dsvFunctions as dsvf
import matplotlib.tri as mtri
import River_conections as rvrCon
import pyvista as pv

def triangleMesh_to_Shapefile(grid,fileName):

    grid.get_vertices()

    cell2d = grid.get_cell2d()

    vertices = grid.get_vertices()

    triangles= list()

    for cell in cell2d:

        vy = [vertices[cell[-1]][-1],vertices[cell[-2]][-1],vertices[cell[-3]][-1],vertices[cell[-1]][-1]]

        vx = [vertices[cell[-1]][-2],vertices[cell[-2]][-2],vertices[cell[-3]][-2],vertices[cell[-1]][-2]]

        polygon = Polygon(list(zip(vx,vy)))

        triangles.append(polygon)

    poly_df = gpd.GeoDataFrame(geometry=triangles)

    poly_df.to_file(fileName,driver='ESRI Shapefile')

def create_Mesh_Dataframe(grid):

    grid.get_vertices()
    cell2d = grid.get_cell2d()
    vertices = grid.get_vertices()
    triangles= list()
    cell_ID = list()
    i  =list()
    k = list()
    nodei = 0
    nodek = 1

    for cell in cell2d:
        vy = [vertices[cell[-1]][-1],vertices[cell[-2]][-1],vertices[cell[-3]][-1],vertices[cell[-1]][-1]]
        vx = [vertices[cell[-1]][-2],vertices[cell[-2]][-2],vertices[cell[-3]][-2],vertices[cell[-1]][-2]]
        polygon = Polygon(list(zip(vx,vy)))
        triangles.append(polygon)
        cell_ID.append(nodei)
        k.append(nodei)
        i.append(nodei)
        nodei = nodei + 1

    grid_df = pd.DataFrame({"k":k,"i":i,"j":i,"nodenumber":cell_ID,"geometry":triangles})
    return grid_df

def geoJson_to_Pandas(geoJsonPath):

    gdf = gpd.read_file('file.geojson')

    gdf.to_file('file.shp')

def generate_Empty_Modflow_Model(exe_path,sim_ws):

    name = 'mf'
    sim = flopy.mf6.MFSimulation(sim_name=name, version='mfusg',
                                 exe_name=exe_path,
                                 sim_ws=sim_ws)
    tdis = flopy.mf6.ModflowTdis(sim, time_units='SECONDS',
                                 perioddata=[[1.0, 1, 1.]])
    gwf = flopy.modflow.Modflow(modelname=name)
    gwf._version = 'mfusg'
    nlay = 1
    top = 1.
    botm = [0.]
    dis = flopy.modflow.ModflowDis(gwf,nlay=nlay,
                               top=top, botm=botm)
    bas = flopy.modflow.ModflowBas(gwf, ibound=1)
    return gwf

def sfr_to_vtk(mesh,sfr,reach_cell_dict,project_name):

    simulation_result = mesh.copy()
    n_cells = mesh.n_cells
    record_names = sfr.output.budget().get_unique_record_names(decode = True)
    sfr_budget = sfr.output.budget()
    sfr_times = sfr_budget.get_times()
    river_cell_id = list(reach_cell_dict.values())
    count = 0
    bc_cells  = dict
    bc_cells.update({'river':{'bc_id':1,'cell_ids':river_cell_id}})
    init_time = True
    for time in sfr_times:
        if init_time == True:

            all_outputs  = sfr_budget.get_data(totim = time)
            sfr_heads = sfr.output.stage().get_data(totim = time)[0][0]

            for output in all_outputs:
                output_name = record_names[count]
                if "FLOW-JA-FACE" in output_name:

                    outFlow  = np.zeros(n_cells)
                    inFlow  = np.zeros(n_cells)
                    flow = output["q"]
                    node2 = output["node2"]
                    for i in range(0,len(flow)):
                        if flow[i] <0:
                            outFlow[reach_cell_dict[node2[i]]] = flow[i] + outFlow[reach_cell_dict[node2[i]]]
                        if flow[i] >0:
                            inFlow[reach_cell_dict[node2[i]]] = flow[i] + inFlow[reach_cell_dict[node2[i]]]

                    simulation_result = mesh.copy()
                    simulation_result.cell_data[output_name]=outFlow
                    simulation_result.save(os.path.join("D:/Master_Erasmus/Thesis/Results",'sim_t_out_1.vtu'))
                    simulation_result = mesh.copy()
                    simulation_result.cell_data[output_name]=inFlow
                    simulation_result.save(os.path.join("D:/Master_Erasmus/Thesis/Results",'sim_t_in_1.vtu'))

                if "GWF" in output_name:
                    output_array_gwf  = np.zeros(n_cells)
                    output_array_head  = np.zeros(n_cells)
                    bc_cells.update({output_name.lower():{'bc_id':count+1,'cell_ids':river_cell_id}})
                    flow = output["q"]
                    node = output["node"]
                    node2 = output["node2"]
                    for i in range(0,len(flow)):
                        output_array_gwf[node2[i]-1]=flow[i]
                        output_array_head[node2[i]-1]=sfr_heads[i]
                    simulation_result = mesh.copy()
                    simulation_result.cell_data["q_leak_SFR_(m3/s)"]=output_array_gwf
                    simulation_result.save(os.path.join("D:/Master_Erasmus/Thesis/Results",'sim_t_1_gwf.vtu'))
                    simulation_result = mesh.copy()
                    simulation_result.cell_data["h_stage_SFR (m)"]=output_array_head
                    simulation_result.save(os.path.join("D:/Master_Erasmus/Thesis/Results",'sim_t_1_head.vtu'))
                    print(output_array_gwf.tolist())

                else:
                    x=2

                count = count + 1

            init_time = False

    # write_pvd(pvd_filename=os.path.join("D:/Master_Erasmus/Thesis/Results",'sim1.pvd'),ts_name_dict='sim_t_1.vtu')
    result_df = pd.DataFrame( {"gw_head (m)":sim.get_model().output.head().get_data()[0][0],
                             "h_stage (m)":output_array_head,
                             "q_leak_(m3/s)":output_array_gwf})
    result_df.to_csv(os.path.join("D:/Master_Erasmus/Thesis/Results",'MODFLOW_resultq0.1.csv'))

    sfr_package_convergence = sfr.output.package_convergence()
    sfr_obs = sfr.output.obs()

workspace ="D:/Master_Erasmus/Thesis/Meras"
'''
#US case

#Define the active domain
active_domain = [(330177, 1246872), (333018, 1246872), (333018, 1249483), (330177, 1249483)]

#Creates triangular grid
tri = trng(angle=20, model_ws=workspace, exe_name="D:/Master_Erasmus/Thesis/Meras/Exe/triangle.exe")
tri.add_polygon(active_domain)
tri.add_region((330277,1246972),0,maximum_area=1000) #coarse discretization
tri.build()

#Plot the grid
fig = plt.figure(figsize=(15, 15))
ax = plt.subplot(1, 1, 1, aspect='equal')
tri.plot(edgecolor='gray')
cell2d = tri.get_cell2d()
vertices = tri.get_vertices()

cell2d = tri.get_cell2d()
vertices = tri.get_vertices()
xcyc = tri.get_xcyc()
ncpl = tri.ncpl
nvert = tri.nvert

grd_df = create_Mesh_Dataframe(tri)
leftcells = tri.get_edge_cells(4)
rightcells = tri.get_edge_cells(2)
'''
#Input exe path
exe_path = "D:/mf6.4.1/bin/mf6.exe"

#Input: Simulation workspace
sim_ws = "D:/Master_Erasmus/Thesis/ModflowModel"

#Input Coordiante system
crs = 'epsg:25833'

#Crete the MODFLOW model
gwf = generate_Empty_Modflow_Model(exe_path,sim_ws)

#triangleMesh_to_Shapefile(tri,"grid2.shp")
grd_df2 = gpd.read_file("D:/Master_Erasmus/Thesis/gridv2/gridv2.shp")

#Cretes the unstructured grid from a shapefile to DISV
grd = sfrmaker.grid.UnstructuredGrid.from_dataframe(
    grd_df2,
    node_col='nodenumber',
    geometry_column='geometry',
    model_units='meters',
    crs='epsg:25833'
)

#US shapeflie path  D:/Master_Erasmus/Thesis/sfrmaker/examples/meras/flowlines.shp
#Synthetic river path D:/Master_Erasmus/Thesis/Germany_River1_v2.shp
#Assignation of the rivers to the grid cells
custom_lines = sfrmaker.Lines.from_shapefile(shapefile='D:/Master_Erasmus/Thesis/Germany_River1_v2.shp',
                                              id_column='COMID',  # arguments to sfrmaker.Lines.from_shapefile
                                              routing_column='tocomid',
                                              width1_column='width1',
                                              width2_column='width2',
                                              up_elevation_column='elevupsmo',
                                              dn_elevation_column='elevdnsmo',
                                              name_column='GNIS_NAME',
                                              attr_length_units='meters',  # units of source data
                                              attr_height_units='meters',
                                              crs='epsg:25833',
                                              )

#m = flopy.modflow.Modflow.load('shellmound.nam', model_ws='D:/Master_Erasmus/Thesis/sfrmaker/sfrmaker/test/data/shellmound/shellmound')
#Export the assigned rivers to a shapefile file for post processing
sfrdata = custom_lines.to_sfr(grid=grd, model=gwf)
sfrdata.write_package(version='mf6',filename='Test2')
sfrdata.export_cells(filename="Test2_grid.shp")
sfrdata.export_lines(filename="Test2.shp")

sfr_df = sfrdata.reach_data

'''
MODFLOW model set up
'''
#Creation of the modflow test case
name = 'mf'
times = [1]
sim = flopy.mf6.MFSimulation(sim_name=name, version='mf6',
                             exe_name=exe_path,
                             sim_ws="D:/Master_Erasmus/Thesis/workSpace")

tdis = flopy.mf6.ModflowTdis(sim, time_units='SECONDS',
                             perioddata=[[1, 1, 1.]])

gwf = flopy.mf6.ModflowGwf(sim, modelname=name, save_flows=True)

ims = flopy.mf6.ModflowIms(sim, print_option='SUMMARY', complexity='complex',
                           outer_hclose=1.e-8, inner_hclose=1.e-8)

tri = dsvf.vtk_to_disv(r"D:/Master_Erasmus/Thesis/example_basin/mesh.vtu")

cell2d = tri["cells2d"]

#To do: make te clock whise polygon general
for cell in range(0,len(cell2d)):
    k  = cell2d[cell][-1]
    l = cell2d[cell][-2]
    cell2d[cell][-1] = l
    cell2d[cell][-2] = k

vertices = tri["vertices"]
nvert = tri["nvert"]
ncpl = tri["ncpl"]
dis = flopy.mf6.ModflowGwfdisv(gwf, length_units='METERS',
                                nlay=1, ncpl=ncpl, nvert=nvert,
                                top=[5], botm=[0],
                                vertices=vertices, cell2d=cell2d)

npf = flopy.mf6.ModflowGwfnpf(gwf, k=0.0001)
ic = flopy.mf6.ModflowGwfic(gwf, strt=5.0)
sto = flopy.mf6.ModflowGwfsto(gwf,iconvert =1,ss = 0)

chdList = []

up = [0,20,40,60,80]
down = [19,39,59,79,99]

for icpl in up: chdList.append([(0, icpl), 1])
for icpl in down: chdList.append([(0, icpl), 0])

chd = flopy.mf6.ModflowGwfchd(gwf, stress_period_data=chdList)
oc = flopy.mf6.ModflowGwfoc(gwf,
                            budget_filerecord='{}.cbc'.format(name),
                            head_filerecord='{}.hds'.format(name),
                            saverecord=[('HEAD', 'all'),
                                        ('BUDGET', 'all')],
                            printrecord=[('HEAD', 'all'),
                                         ('BUDGET', 'all')])

'''
SFR set up
'''
connectionData = rvrCon.river_Conections("Test2.shp",crs = crs)
pckgData = []
pckgConections = []
pckgDiversion = []
reach_cell_dict = {}
num_cells = 100
reach_ID_list = ["No_reach"] *num_cells

for i in range(0,sfr_df.shape[0]):
    reach_ID_list[sfr_df["node"][i]] = sfr_df["rno"][i]

    rno = sfr_df["rno"][i]
    num_Connections = len(connectionData[rno]["in"])+len(connectionData[rno]["out"])

    data = (sfr_df["rno"][i]-1, 0, sfr_df["node"][i], sfr_df["rchlen"][i],
            0.1, 0.01,2,
            0.5,0.0001,0.04,num_Connections,1,0)
    reach_cell_dict[sfr_df["rno"][i]] = sfr_df["node"][i]

    if len(connectionData[rno]["out"]) > 1:

        data = (sfr_df["rno"][i]-1, 0, sfr_df["node"][i], sfr_df["rchlen"][i],
                0.1, 0.01,2,
                0.5,0.0001,0.04,num_Connections,1,1)

        pckgDiversion.append([sfr_df["rno"][i]-1, 0, 15,"UPTO"])

    if rno == 16:
        data = (sfr_df["rno"][i]-1, 0,sfr_df["node"][i], sfr_df["rchlen"][i],
                0.1, 0.01,2,
                0.5,0.0001,0.04,num_Connections,0,0)

    pckgData.append(data)
    pckgConections.append([rno-1,*connectionData[rno]["out"],*connectionData[rno]["in"]])

channel_flow_data = [[0,"inflow",50],[6,"inflow",50],[11,"diversion",0,50]]

sfr = flopy.mf6.ModflowGwfsfr(gwf,nreaches=sfr_df.shape[0],packagedata=pckgData,
                              connectiondata=pckgConections,diversions=pckgDiversion,
                              print_flows=True,print_input =True,print_stage=True,
                              save_flows=True,stage_filerecord="sfr_stage.hds",
                              budgetcsv_filerecord ='{}.csv'.format(name),
                              budget_filerecord =  '{}.cbc'.format(name+"_SFR"),
                              perioddata=channel_flow_data,package_convergence_filerecord='conv{}.csv'.format(name)
                              )

'''
Simulaion set up
'''
sim.write_simulation()
success, buff = sim.run_simulation()

hdobj = flopy.utils.HeadFile("D:/Master_Erasmus/Thesis/workSpace/mf.hds", precision='double')

'''
Simulaion set up
'''

sim.write_simulation()
success, buff = sim.run_simulation()

'''
Write Results
'''
# sfr_flows = flopy.utils.CellBudgetFile("D:/Master_Erasmus/Thesis/Simple_case/SimpleModflow/mf_SFR.cbc")
# flows = flopy.utils.CellBudgetFile("D:/Master_Erasmus/Thesis/Simple_case/SimpleModflow/mf_SFR.cbc").get_data(idx = 1)
# times = [10]
cell_id_list = range(1, 101)

result_dict = {}
prjct_name = "Synthetic_Network_Base_Case_SFR_width_0.1m"
stress_len = 1
result_path = "D:/Master_Erasmus/Thesis/Results_SFR"

csv_name = prjct_name+"_results_"+"qgwf"+"_stress_p_"+str(stress_len)+".csv"
cell_dict = {"cell_id" : cell_id_list,"reach_id":reach_ID_list}
result_df_qgwf = pd.DataFrame(cell_dict)

for time in times:
    result_qgwf = [0]*num_cells
    data = sfr.output.budget().get_data(text="GWF", totim= time)[0]["q"]
    cells_qgwf = sfr.output.budget().get_data(text="GWF", totim= time)[0]["node2"]

    i=0
    for j in range(0,len(result_qgwf)):
        if cell_dict["reach_id"][j] == "No_reach":
            result_qgwf[j] = 0

        else:
            result_qgwf[cells_qgwf[i]-1] = data[i]
            i = i+1

    result_df_qgwf["q leak time "+str(time)+" (m3/s)"] = result_qgwf
result_df_qgwf.to_csv(os.path.join(result_path,csv_name))

csv_name = prjct_name+"_results_"+"stage"+"_stress_p_"+str(stress_len)+".csv"
cell_dict = {"cell_id" : cell_id_list,"reach_id":reach_ID_list}
result_df_stage = pd.DataFrame(cell_dict)

for time in times:
    i = 0
    result_stage = [0]*num_cells

    data = list(sfr.output.stage().get_data(totim = time)[0][0])

    for j in range(0,len(result_stage)):

        if cell_dict["reach_id"][j] == "No_reach":
            result_stage[j] = 0
        else:
            result_stage[cells_qgwf[i]-1] = data[i]
            i = i+1

    result_df_stage["h stage time "+str(time)+" (m)"] = result_stage

result_df_stage.to_csv(os.path.join(result_path,csv_name))

csv_name = prjct_name+"_results_"+"hgw"+"_stress_p_"+str(stress_len)+".csv"
cell_dict = {"cell_id" : cell_id_list,"reach_id":reach_ID_list}
result_df = pd.DataFrame(cell_dict)
i = 0
for time in times:
    result = [0]*num_cells

    result = sim.get_model().output.head().get_data(totim = time)[0][0]
    result_df["gw head time "+str(time)+" (m)"] = result

    i = i+1

result_df.to_csv(os.path.join(result_path,csv_name))

# head = hdobj.get_data()

# flows = flopy.utils.CellBudgetFile("D:/Master_Erasmus/Thesis/workSpace/mf.cbc").get_data(idx = 1)
# sfr_flows = flopy.utils.CellBudgetFile("D:/Master_Erasmus/Thesis/workSpace/mf_SFR.cbc")
# # sfr_flows.list_records()
# sfr_inpt = sfr_flows.get_data(idx = 6, text = "EXT-INFLOW")
# print(sim.get_model().output.head().get_data()[0][0])

# x = np.zeros(nvert)
# y = np.zeros(nvert)
# triangles = []

# for i in range(0,nvert):
#     x[i] = tri["vertices"][i][-2]
#     y[i] = tri["vertices"][i][-1]

# for i in range(0,ncpl):
#     triangles.append([tri["cells2d"][i][-3],tri["cells2d"][i][-2],tri["cells2d"][i][-1]])

# '''
# Simulaion plotting
# '''
# triang = mtri.Triangulation(x, y, triangles)

# fig, ax = plt.subplots()
# ax.triplot(triang, 'ko-')
# tpc = ax.tripcolor(triang,facecolors = head[0][0])
# fig.colorbar(tpc)
# plt.show()

# gwf.package_names
# gwf.get_package_list()
# u=gwf.output.methods()

#Function to get the available methods of the sfr output
# sfr_methods = sfr.output.methods()

# sfr_package_convergence = sfr.output.package_convergence()
# sfr_obs = sfr.output.obs()
# sfr_stage = sfr.output.stage()

# '''
# VTK creation
# '''
# mesh = pv.read(r"D:/Master_Erasmus/Thesis/example_basin/mesh.vtu")
# sfr_to_vtk(mesh,sfr,reach_cell_dict,name)
# simulation_result = mesh.copy()
# simulation_result.cell_data["gw_head(m)"]=sim.get_model().output.head().get_data()[0][0]
# simulation_result.save(os.path.join("D:/Master_Erasmus/Thesis/Results",'sim_gw_head.vtu'))
# fig = plt.figure(figsize=(15, 15))
# ax = plt.subplot(1, 1, 1, aspect='equal')
# img=tri.plot(ax=ax, a=head[0, 0, :], cmap='Spectral')
# fig.colorbar(img, fraction=0.02)

# fname = os.path.join(sim_ws, name + '.hds')
# hdobj = flopy.utils.HeadFile(fname, precision='double')
# head = hdobj.get_data()


#!/usr/bin/env python
# -*-coding:utf-8-*-
# author:sware
"""
工具箱：
日志、配置
"""

import os
import time
import logging

# log_path 是存放日志的路径
cur_path = os.path.dirname(os.path.abspath(__file__))
log_path = os.path.join(os.path.dirname(cur_path),'logs')

# 如果logs文件夹不存在，就自动创建一个
if not os.path.exists(log_path): os.mkdir(log_path)

class Log(object):
    """
    # https://www.jianshu.com/p/8799aff60f24
    logging.basicConfig函数各参数：
    filename：指定日志文件名；
    filemode：和file函数意义相同，指定日志文件的打开模式，'w'或者'a'；
    format：指定输出的格式和内容，format可以输出很多有用的信息，
    参数：作用
    %(levelno)s：打印日志级别的数值
    %(levelname)s：打印日志级别的名称
    %(pathname)s：打印当前执行程序的路径，其实就是sys.argv[0]
    %(filename)s：打印当前执行程序名
    %(funcName)s：打印日志的当前函数
    %(lineno)d：打印日志的当前行号
    %(asctime)s：打印日志的时间
    %(thread)d：打印线程ID
    %(threadName)s：打印线程名称
    %(process)d：打印进程ID
    %(message)s：打印日志信息

    datefmt：指定时间格式，同time.strftime()；

    level：设置日志级别，默认为logging.WARNNING；

    stream：指定将日志的输出流，可以指定输出到sys.stderr，sys.stdout或者文件，默
    """
    def __init__(self,file=None):
        # self.log_path = log_path
        self.logname = os.path.join(log_path,"{}.log".format(
            time.strftime("%Y_%m_%d")))  # 当初始化时没有指定日志文件名称，默认使用时间作为名称
        self.logger = logging.getLogger()
        self.logger.setLevel(logging.INFO)
        # 日志输出格式
        self.formatter = logging.Formatter('[%(asctime)s] - [%(filename)s - %(lineno)d line] - %(levelname)s: %(message)s')

    def __console(self, level, message):
        # if os.path.exists(self.logname): os.mkdir(self.logname)
        # 创建一个FileHandler，用于写到本地
        fh = logging.FileHandler(self.logname, 'a', encoding='utf-8')
        fh.setLevel(logging.INFO)
        fh.setFormatter(self.formatter)
        self.logger.addHandler(fh)

        # 创建一个StreamHandler，用于输出到控制台
        ch = logging.StreamHandler()
        ch.setLevel(logging.INFO)
        ch.setFormatter(self.formatter)
        self.logger.addHandler(ch)

        if level == 'info':
            self.logger.info(message)
        elif level == 'debug':
            self.logger.debug(message)
        elif level == 'warning':
            self.logger.warning(message)
        elif level == 'error':
            self.logger.error(message)
        else:
            raise Exception('only input info|debug|warning|error')
        # 此两行代码是为了避免日志输出重复的问题
        self.logger.removeHandler(ch)
        self.logger.removeHandler(fh)
        # 关闭打开的文件
        fh.close()

    def debug(self, message):
        self.__console('debug', message)

    def info(self, message):
        self.__console('info', message)


from utils import *

def main():
    # Starts a game of tic-tac-toe.
    print("Welcome to Tic-Tac-Toe!")
    while True:
        versus = input_multiplayer_or_computer()
        if versus == 1:
            sym1 = input_symbol(1)
            while True:
                sym2 = input_symbol(2)
                if sym1 == sym2:
                    print("Symbol already taken! Please type another symbol for your player.")
                else:
                    break
            game, player1, player2 = start_game(sym1, sym2)
            dim = game.get_board_dim()
            display_str = "To play, please type in the row number, then the column number separated by a comma, no spaces. "
            display_str += "Row number and column number start at 0 and go down and right, respectively."
            print(display_str)
            flag = True
            while game.is_in_progress():
                print(game)
                if flag:
                    i, j = input_place(dim, sym1)
                    result = player1.place(i, j)
                else:
                    i, j = input_place(dim, sym2)
                    result = player2.place(i, j)
                if result == 0:
                    flag = not flag
            game.game_over()
            x = input_play_again()
            if x == 'n':
                return
        elif versus == 2:
            print("Sorry! Feature not implemented yet!")
        else:
            print("Please follow directions! 1 or 2.")

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

if __name__ == "__main__":
    main()


import random
wrong_choices_allowed = 9
guessed_letters = []
word_bank = ('desk', 'phone', 'harpie', 'microphone', 'kazoomaniafool', 'football')

def bank():
  chosen_word = random.choice(word_bank)
  return chosen_word

word = bank()
def get_guesses_remaining():
  wrong_choices_allowed - len(set(guessed_letters) - set(word))

print('Let\'s play hangman')

dash_word = ['_ '] * len(word)

def display_word():
  display = " "
  for letter in word:
    if guessed_letters.count(letter):
      display += letter + " "
    else:
      display += "_ "
  print(display)
  print()

def return_word():
  display = " "
  for letter in word:
    if guessed_letters.count(letter):
      display += letter + " "
    else:
      display += "_ "
  return display

def guessed(letter):
  if letter in guessed_letters:
    print('You have already guessed this letter')
    exit
  else:
    guessed_letters.append(letter)

#function to check if the letter guessed was in the word and replace the dash with it. The check to see if it is in the word works
def check_letter(letter):
  if letter in word:
    print(f'You guessed one, {letter} is in the word.')
  else:
    print(f'Nope! {letter} is not in this word.')

def get_guesses_remaining():
  return wrong_choices_allowed - len(guessed_letters)

def won():
  return return_word().replace(' ', '') == word

#main loop to play game. work in progress
letter = ''
while letter != "exit":
  return_word()
  display_word()
  print(f'Guess all the correct letters to win? You have {get_guesses_remaining()} guesses before you lose the game. Type exit to end game early.')
  letter = input("Choose a letter: ")
  guessed(letter)
  print('These are your guessed letters ' + str(guessed_letters))
  #print('You have ' + str(counter) + ' guesses left.')
  check_letter(letter)
  if won():
    print('You won!')
  if get_guesses_remaining() > 0:
    continue

  if won():
    print('You won!')
  else:
    print(f'You lose! The word was {word}')
    exit


from utils.info import pktInfo
from utils.my_enum import interfaceState
from utils.record import pktRecord
from .gcc_twcc_estimator import GCC

BaseDelay = 200  # ms, 假设传播时延

class GccNativeEstimator(object):
	def __init__(self, initialBwe, maxBwe, minBwe, filterType):
		self.pktsRecord = pktRecord(BaseDelay)
		self.pktsRecord.reset()

		self.state = interfaceState.INIT

		self.gcc = GCC(initialBwe, filterType)

		# last interval value or initial value, bps, int
		self.predictionBandwidth = initialBwe

		self.minBwe = minBwe
		self.maxBwe = maxBwe

		self.stats = []

	def report_states(self, stats: dict):
		"""
		stats is a rtp pkt to a dict with the following items
		{
			"send_time_ms": uint,
			"arrival_time_ms": uint,
			"payload_type": int,
			"sequence_number": uint,
			"ssrc": int,
			"padding_length": uint,
			"header_length": uint,
			"payload_size": uint
		},
		example:
		[
			{
				'arrival_time_ms': 66113,
				'header_length': 24,
				'padding_length': 0,
				'payload_size': 1389,
				'payload_type': 126,
				'send_time_ms': 60999,
				'sequence_number': 54366,
				'ssrc': 12648429
			},
			{
				'arrival_time_ms': 66181,
				'header_length': 24,
				'padding_length': 0,
				'payload_size': 1389,
				'payload_type': 126,
				'send_time_ms': 61069,
				'sequence_number': 54411,
				'ssrc': 12648429}
		]
		"""
		if self.state == interfaceState.ESTIMATE:
			self.stats = []
		self.state = interfaceState.REPORT

		if len(stats) <= 0:
			return

		pkt_info = pktInfo()
		pkt_info.payload_type = stats["payload_type"]
		pkt_info.ssrc = stats["ssrc"]
		pkt_info.sequence_number = stats["sequence_number"]
		pkt_info.send_timestamp_ms = stats["send_time_ms"]
		pkt_info.receive_timestamp_ms = stats["arrival_time_ms"]
		pkt_info.padding_length = stats["padding_length"]
		pkt_info.header_length = stats["header_length"]
		pkt_info.payload_size = stats["payload_size"]

		pkt_info.size = stats["padding_length"] + \
		                stats["header_length"] + stats["payload_size"]

		pkt_info.bandwidth_prediction_bps = self.predictionBandwidth

		# todo: 确认是否应该给包加上假设的 base delay
		self.pktsRecord.on_receive(pkt_info)

		self.gcc.rateCalculator.update(pkt_info)

		self.gcc.rttCalculator.simpleRtt(self.pktsRecord.pkts[-1].delay)

		self.gcc.currentTimestamp = pkt_info.receive_timestamp_ms

		self.stats.append(stats)

	def get_estimated_bandwidth(self) -> int:
		if self.state == interfaceState.REPORT:
			self.state = interfaceState.ESTIMATE
		# else:
		# 	return self.predictionBandwidth

		assert self.pktsRecord.packet_num > 0

		self.gcc.setIntervalState(self.pktsRecord, self.stats)

		self.predictionBandwidth = self.gcc.getEstimateBandwidth()

		return self.predictionBandwidth


import setuptools
with open("README.md", "r") as fh:
    long_description = fh.read()
setuptools.setup(
     name='aiopyql',
     version='PYQLVERSION',
     packages=setuptools.find_packages(include=['aiopyql'], exclude=['build']),
     author="Joshua Jamison",
     author_email="joshjamison1@gmail.com",
     description="A fast and easy-to-use asyncio ORM(Object-relational Mapper) for performing C.R.U.D. ops within RBDMS tables using python",
     long_description=long_description,
   long_description_content_type="text/markdown",
     url="https://github.com/codemation/aiopyql",
     classifiers=[
         "Programming Language :: Python :: 3",
         "License :: OSI Approved :: MIT License",
         "Operating System :: OS Independent",
     ],
     python_requires='>=3.7, <4',
     install_requires=['aiosqlite', 'aiomysql', 'asyncpg', 'cryptography'],
 )


import sys
# Find all pairs of ints that add up to given value
def find_all_sum_of_two(input, val):
  theResult = []
  found_values = set()
  for a in input:
    if val - a in found_values:
      #return True
      theResult.append([val-a,a])
    found_values.add(a)
  #return False
  return theResult

if __name__ == '__main__':
    # command line input: "1,2,3,4,6,7,8,9" 12
    instring = sys.argv[1]
    value = sys.argv[2]
    inputnumbers = list(map(int, instring.split(',')))
    print(find_all_sum_of_two(inputnumbers, int(value)))


# -*- coding: utf-8 -*-
import logging
import pickle
from api import apis
from datetime import datetime
from flask import Flask, render_template
from my.util import hatena
from my.db import datastore
from google.appengine.api import memcache

app = Flask(__name__)
app.register_blueprint(apis)
app.config['DEBUG'] = True

logging.getLogger().setLevel(logging.DEBUG)

# 1ページあたりに表示する記事件数
ENTRIES_PER_PAGE = 10

@app.route('/')
@app.route('/<page>')
def home(page=None):
    pageNum = 0 if page == None else int(page)
    memcache_key = 'public_entries_' + str(pageNum);
    entries = memcache.get(memcache_key)
    if entries is None:
        entries = pickle.dumps(datastore.get_public_entries(limit=ENTRIES_PER_PAGE, offset=(ENTRIES_PER_PAGE * pageNum)))
        memcache.add(memcache_key, entries, 60 * 60 * 24)
    entries = pickle.loads(str(entries))
    return render_template('home.html', entries=entries, sidebar_entries=__sidebar_entry(), page=pageNum)

@app.route('/popular')
def popular():
    memcache_key = 'get_popular_entries';
    entries = memcache.get(memcache_key)
    if entries is None:
        entries = pickle.dumps(datastore.get_popular_entries(limit=ENTRIES_PER_PAGE))
        memcache.add(memcache_key, entries, 60 * 60 * 24)
    entries = pickle.loads(str(entries))
    return render_template('home.html', entries=entries, sidebar_entries=__sidebar_entry(), page=0)

def __sidebar_entry():
    """サイドバー表示を管理"""
    memcache_key = 'get_public_entries';
    newer = memcache.get(memcache_key)
    if newer is None:
        newer = pickle.dumps(datastore.get_public_entries())
        memcache.add(memcache_key, newer, 60 * 60 * 24)
    newer = pickle.loads(str(newer))
    memcache_key = 'get_popular_entries';
    popular = memcache.get(memcache_key)
    if popular is None:
        popular = pickle.dumps(datastore.get_popular_entries())
        memcache.add(memcache_key, popular, 60 * 60 * 24)
    popular = pickle.loads(str(popular))
    return {'newer': newer[:6], 'popular': popular[:6]}

@app.route('/entry/<eid>')
def entry(eid):
    """エントリーページを表示する"""
    entry = datastore.get_public_entry(int(eid))
    comments = []
    score = 0
    for comment in entry.bookmarkcomment_set:
        comments.append({
          'data': comment,
          'score': __style_from_score(hatena.get_star_score(comment)),
        })
    return render_template('entry.html', entry=entry, comments=comments, sidebar_entries=__sidebar_entry())

def __style_from_score(score):
    """スコアを計算して、0-9の値を返す"""
    score_table = [70, 60, 50, 40, 35, 20, 10, 5, 1]
    for i, value in enumerate(score_table):
        if score > value:
            return len(score_table) - i
    return 0

@app.route('/category/<category>')
@app.route('/category/<category>/<page>')
def category(category, page=None):
    """エントリーページを表示する"""
    pageNum = 0 if page == None else int(page)
    memcache_key = 'public_entries_in_category_' + category + '_' + str(pageNum);
    entries = memcache.get(memcache_key)
    if entries is None:
        entries = pickle.dumps(datastore.get_public_entries_in_category(category, limit=ENTRIES_PER_PAGE, offset=(ENTRIES_PER_PAGE * pageNum)))
        memcache.add(memcache_key, entries, 60 * 60 * 24)
    entries = pickle.loads(str(entries))
    return render_template('home.html', entries=entries, sidebar_entries=__sidebar_entry(), page=pageNum)

@app.errorhandler(404)
def page_not_found(e):
    """Return a custom 404 error."""
    return 'Sorry, nothing at this URL.', 404


#!/usr/bin/env python3

import sys
import socket
import selectors
import traceback

import libclient

def create_request(action, value):
    return dict(
        type="text/json",
        encoding="utf-8",
        content=dict(action=action, value=value),
    )

class HeartCli:
    def __init__(self):
        self.sel = selectors.DefaultSelector()
        self.message = None
        self.host = '127.0.0.1'
        self.port = 8000

    def start_connection(self, host, port, request):
        addr = (host, port)
        print("starting connection to", addr)
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.setblocking(False)
        sock.connect_ex(addr)
        events = selectors.EVENT_WRITE
        self.message = libclient.Message(self.sel, sock, addr, request)
        self.sel.register(sock, events, data=self.message)

    def send_heart(self, request):
        self.start_connection(self.host, self.port, request)
        try:
            while True:
                events = self.sel.select(timeout=1)
                for key, mask in events:
                    self.message = key.data
                    try:
                        self.message.write_without_reply()
                    except Exception:
                        print(
                            "main: error: exception for",
                            f"{self.message.addr}:\n{traceback.format_exc()}",
                        )
                        self.message.close()
                        return False
                # Check for a socket being monitored to continue.
                if not self.sel.get_map():
                    # result_info = self.message.response
                    break
        except OSError:
            return False
        except Exception as e:
            return False
            print(f"未知错误：f{e} --> {type(e)}")
        finally:
            self.sel.close()
        return True

if __name__ == '__main__':
    request = create_request('heart', "")
    cli = HeartCli()
    r = cli.send_heart(request)
    print('发送是否成功：', r)


#!/usr/bin/env python
# coding: utf-8

# In[ ]:

import numpy as np
import skfuzzy as fuzz
from skfuzzy import control as ctrl

Sign = ctrl.Antecedent(np.arange(-1,1.1,0.10),'sign')
Strength = ctrl.Antecedent(np.arange(-1,1.1,0.10),'strength')
preg = ctrl.Consequent(np.arange(-1,1.1,0.10),'preg')

Sign['Negative'] = fuzz.trimf(Sign.universe,[-1,-1,0])
Sign['Zero'] = fuzz.trimf(Sign.universe,[-1,0,1])
Sign['Positive'] = fuzz.trimf(Sign.universe,[0,1,1])
Strength['Small'] = fuzz.trimf(Sign.universe,[-1,-1,0])
Strength['Medium'] = fuzz.trimf(Sign.universe,[-1,0,1])
Strength['Large'] = fuzz.trimf(Sign.universe,[0,1,1])

preg['NL'] = fuzz.trapmf(preg.universe, [-1, -1,-0.7,-0.3])
preg['NM'] = fuzz.trapmf(preg.universe, [-0.7, -0.3,-0.3,-0.1])
preg['NS'] = fuzz.trapmf(preg.universe, [-0.3, -0.1,-0.1,0])
preg['ZE'] = fuzz.trapmf(preg.universe, [-0.1,0, 0, 0.1])
preg['PS'] = fuzz.trapmf(preg.universe, [0, 0.1, 0.1,0.3])
preg['PM'] = fuzz.trapmf(preg.universe, [0.1, 0.3, 0.3,0.7])
preg['PL'] = fuzz.trapmf(preg.universe, [0.3,0.7,1,1])

Sign.view()
Strength.view()
preg.view()

rule1 = ctrl.Rule(Sign['Negative']&Strength['Small'],preg['NS'])
rule2 = ctrl.Rule(Sign['Negative']&Strength['Medium'],preg['NM'])
rule3 = ctrl.Rule(Sign['Negative']&Strength['Large'],preg['NL'])
rule4 = ctrl.Rule(Sign['Zero'],preg['ZE'])
rule5 = ctrl.Rule(Sign['Positive']&Strength['Small'],preg['PS'])
rule6 = ctrl.Rule(Sign['Positive']&Strength['Medium'],preg['PM'])
rule7 = ctrl.Rule(Sign['Positive']&Strength['Large'],preg['PL'])

tipping_ctrl = ctrl.ControlSystem([rule1,rule2,rule3,rule4,rule5,rule6,rule7])
tipping = ctrl.ControlSystemSimulation(tipping_ctrl)

tipping.input['sign'] = -0.1
tipping.input['strength'] = -0.1
tipping.compute()
print(tipping.output['preg'])
preg.view(sim=tipping)


# -*- coding: utf-8 -*-
"""
Created on Thu Jun  2 16:40:51 2016

@author: kevinzhang
"""

def squares(start, terms):
    return sum([i**2 for i in range(start, terms+1)])

def cubes(start, terms):
    return sum([i**3 for i in range(start, terms+1)])

user_str = input('Enter a command: ')
if user_str == 'squares':
    start_sq = int(input('Enter a starting integer: '))
    terms_sq = int(input('Enter the number of terms: '))
    result = squares(start_sq, terms_sq)
    print(result)
else:
    print('***Invalid Choice***')
    user_str = int(input('Try again: '))
if user_str == 'cubes':
    start_cb = int(input('Enter a starting integer: '))
    terms_cb = int(input('Enter the number of terms: '))
    result = squares(start_cb, terms_cb)
    print(result)
else:
    print('***Invalid Choice***')
    user_str = int(input('Try again: '))
if user_str == 'exit':
    print('Program halted normally')
else:
    print('***Invalid Choice***')
    user_str = int(input('Try again: '))


try:
    from plugin import JSPlugin
except ImportError:
    from .plugin import JSPlugin

class QuillJSPlugin(JSPlugin):
    def __init__(self, **kwargs):
        super(QuillJSPlugin, self).__init__(name="quill",
                                            static="./static/",
                                            cdn_urls=["https://cdn.quilljs.com/1.3.6/quill.js"],
                                            cdn_min_urls=["https://cdn.quilljs.com/1.3.6/quill.min.js"],
                                            **kwargs)

# class QuillJSPlugin:
#     def __init__(self):
#         self.name = "quill.js"
#         self.cdn_url = ""

#     def save(self, path):
#         import os
#         # if not os.path.exists(path): open(path, "w").write(bytes(self._code).decode("iso 8859-15"))

#     def __str__(self):
#         static_url = "{{ "+f"url_for('static', '{self.name}')"+" }}"
#         return f'''<script src="{static_url}"></script>'''

#     def __repr__(self):
#         return self.__str__()


from flask import Flask
from flask import render_template

from flask import Flask, render_template
from flask_socketio import SocketIO
from flask_socketio import send, emit

from flask_socketio import join_room, leave_room, rooms

app = Flask(__name__)
app.config['SECRET_KEY'] = 'vnkdjnfjknfl1232#'
socketio = SocketIO(app)

@app.route('/')
def sessions():
    return render_template('session.html')

@socketio.on('connect')
def handle_connect():
    send('Hello, you succesfully connected to the distributed computing planner of the scanner')

@socketio.on('message')
def handle_message(message):
    send('received' + message + '_' + str(rooms()))

@socketio.on('join')
def on_join(data):
    username = data['username']
    room = data['room']
    join_room(room)
    emit('message', username + ' has entered the room.', room=room)

@socketio.on('leave')
def on_leave(data):
    username = data['username']
    print("tip")
    room = data['room']
    leave_room(room)
    emit('message', username + ' has left the room.', room=room)

@socketio.on('request')
def handle_request(param):
    emit('data', 'info of the data , data returned by a function ', room =rooms()[0])
    #on écrit dans la db que le calcul est en cours associé à l'id de co

@socketio.on("computing")
def handle_computing(response):
    # on recupère le result
    # on écrit dans la db
    # on marque la tache comme done
    emit('conclusion','sign that everything get good ')

class Planner:
    def __init__(self):
        pass

# @socketio.on('receive_msg')
# def handle_my_custom_event(json, methods=['GET', 'POST']):
#     print('received my event: ' + str(json))
#     socketio.emit('the_response', json)

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


'''
Programa para determinar si un deportista es aceptado en el equipo de
baloncesto de Bogotá. Las condiciones para ser aceptado son:
a) La edad debe ser menor o igual a 18 años
b) La estatura debe ser mayor a 180 cm
c) El peso debe ser menor o igual a 80 kg

Si el aspirante cumple las 3 condiciones
'''
#pedimos y validamos datos
#edad
while True:
    try:
        edad = int(input("Escribe la edad del jugador: "))
    except ValueError:
        print("Debes escribir un número.")
        continue

    if edad < 0:
        print("Debes escribir un número positivo.")
        continue
    else:
        break
#estatura
while True:
    try:
        estatura = int(input("Escribe la estatura del jugador: "))
    except ValueError:
        print("Debes escribir un número.")
        continue

    if estatura < 0:
        print("Debes escribir un número positivo.")
        continue
    else:
        break
#peso
while True:
    try:
        peso = int(input("Escribe el peso del jugador: "))
    except ValueError:
        print("Debes escribir un número.")
        continue

    if peso < 0:
        print("Debes escribir un número positivo.")
        continue
    else:
        break

    #definimos funciones de comprobacion
def esMayorDeEdad(edad):
    '''Comprueba si el jugador es mayor de edad '''
    return True if edad >= 18 else False

def compruebaPeso(peso):
    '''Comprueba el peso del jugador'''
    return True if peso <= 80 else False

def compruebaEstatura(estatura):
    '''Comprueba estatura del jugador'''
    return True if estatura > 180 else False

if(esMayorDeEdad and compruebaPeso and compruebaEstatura):
    print("el jugador cumple, es adminido")
else:
    print("Jugador no admitido")


import sys
sys.path.append("/home/cloud/projects/bin/nemo-gitannex/")

from gi.repository import Nemo, GObject
import gitannex_utils as utils
import urllib
import os.path

class GitAnnexMenuProvider(GObject.GObject, Nemo.MenuProvider):
    def __init__(self):
        pass
    def menu_get_cb(self, menu, path_list):
        for path in path_list:
            utils.getPath(path)
    def menu_lock_cb(self, menu, path_list):
        for path in path_list:
            utils.lockPath(path)
    def menu_unlock_cb(self, menu, path_list):
        for path in path_list:
            utils.unlockPath(path)
    def menu_drop_cb(self, menu, path_list):
        for path in path_list:
            utils.dropPath(path)
    def menu_sync_cb(self, menu, path):
        utils.sync(path)

    def get_file_items(self, window, files):
        files = [file for file in files if file.get_uri_scheme() == 'file']
        if len(files) < 1:
            return
        file_paths = []
        for file in files:
            file_paths.append(urllib.unquote(file.get_uri()[7:]))

        file = files[0]
        file_path = file_paths[0]
        dir_path = os.path.dirname(file_path)

        if not utils.isGitAnnex(dir_path):
            return

        submenulist = []
        lock_menuitem = Nemo.MenuItem(name='GitAnnexMenuProvider::lock', label='lock', tip='',icon='')
        unlock_menuitem = Nemo.MenuItem(name='GitAnnexMenuProvider::unlock', label='unlock', tip='',icon='')
        get_menuitem = Nemo.MenuItem(name='GitAnnexMenuProvider::get', label='get', tip='',icon='')
        drop_menuitem = Nemo.MenuItem(name='GitAnnexMenuProvider::drop', label='drop', tip='',icon='')
        lock_menuitem.connect('activate', self.menu_lock_cb, file_paths)
        unlock_menuitem.connect('activate', self.menu_unlock_cb, file_paths)
        get_menuitem.connect('activate', self.menu_get_cb, file_paths)
        drop_menuitem.connect('activate', self.menu_drop_cb, file_paths)
        if file.is_directory() or len(files) > 1:
            submenulist.append(get_menuitem)
            submenulist.append(lock_menuitem)
            submenulist.append(unlock_menuitem)
            submenulist.append(drop_menuitem)
        else:
            if utils.isFileLocalAvailable(file_path):
                if utils.isFileModifyable(file_path):
                    submenulist.append(lock_menuitem)
                else:
                    submenulist.append(unlock_menuitem)
                    submenulist.append(drop_menuitem)
            else:
                submenulist.append(get_menuitem)

        top_menuitem = Nemo.MenuItem(name='GitAnnexMenuProvider::GitAnnex',
                                         label='GitAnnex',
                                         tip='',
                                         icon='')
        submenu = Nemo.Menu()
        top_menuitem.set_submenu(submenu)

        for sub_menuitem in submenulist:
          submenu.append_item(sub_menuitem)

        return top_menuitem,

    def get_background_items(self, window, file):

        if file.get_uri_scheme() != 'file':
            return
        dir_path = urllib.unquote(file.get_uri()[7:])
        if not file.is_directory():
            dir_path = os.path.dirname(dir_path)
        if not utils.isGitAnnex(dir_path):
            return

        sync_menuitem = Nemo.MenuItem(name='GitAnnexMenuProvider::sync', label='sync', tip='', icon='')
        sync_menuitem.connect('activate', self.menu_sync_cb, dir_path)

        submenu = Nemo.Menu()
        submenu.append_item(sync_menuitem)
        menuitem = Nemo.MenuItem(name='GitAnnexMenuProvider::GitAnnex',
                                         label='GitAnnex',
                                         tip='',
                                         icon='')
        menuitem.set_submenu(submenu)

        return menuitem,


import sys
from io import StringIO
import unittest

from src.AOJ.ITP1_6_B import resolve

class TestClass(unittest.TestCase):
    def assertIO(self, input, output):
        stdout, stdin = sys.stdout, sys.stdin
        sys.stdout, sys.stdin = StringIO(), StringIO(input)
        resolve()
        sys.stdout.seek(0)
        out = sys.stdout.read()[:-1]
        sys.stdout, sys.stdin = stdout, stdin
        self.assertEqual(out, output)

    def test_1(self):
        input = """47
S 10
S 11
S 12
S 13
H 1
H 2
S 6
S 7
S 8
S 9
H 6
H 8
H 9
H 10
H 11
H 4
H 5
S 2
S 3
S 4
S 5
H 12
H 13
C 1
C 2
D 1
D 2
D 3
D 4
D 5
D 6
D 7
C 3
C 4
C 5
C 6
C 7
C 8
C 9
C 10
C 11
C 13
D 9
D 10
D 11
D 12
D 13"""
        output = """S 1
H 3
H 7
C 12
D 8"""
        self.assertIO(input, output)


from django.contrib.sessions.backends.db import SessionStore
from django.contrib.gis.geos import LineString, Point
from django.core.serializers import serialize
from anchorwhat.models import Drawing, Questions, Survey, Sessions, PageTime, Pages, Trials, Sets
from datetime import datetime, timezone
from device_detector import DeviceDetector
from user_agents import parse
from random import choice
import json

def create_session(data):
    s = SessionStore()
    s.create()
    key = s.session_key
    ua = data["userAgent"]
    device = DeviceDetector(ua).parse()
    browser = parse(ua)
    start = datetime.now(timezone.utc)

    session = Sessions()
    session.django_key = key
    session.device = device.device_type()
    session.os = device.os_name()
    session.browser = browser.browser.family
    session.user_agent = ua
    session.start = start
    session.screen_width = data["resolution"][0]
    session.screen_height = data["resolution"][1]
    session.save()

    return key

def update_page_time(user, page, time):
    s = Sessions.objects.get(django_key=user)
    p = Pages.objects.get(pk=page)
    if PageTime.objects.filter(session=s.id, page_number=p.id).exists():
        pt = PageTime.objects.get(session=s.id, page_number=p.id)
        pt.duration_ms = pt.duration_ms + time
        pt.save()
    else:
        e = PageTime(
            session = s,
            page_number = p,
            duration_ms = time
        )
        e.save()

def insert_form(data):
    user = data['user']
    s = Sessions.objects.get(django_key=user)
    page = data['data']['page']
    questions = data['data']['questions']
    for question in questions:
        an = questions[question]['answer']
        if isinstance(an, list):
            a = ', '.join(an)
        else:
            a = an
        q = Questions.objects.get(page_number=page, number=question)
        if Survey.objects.filter(session=s, question=q).exists():
            new = Survey.objects.get(session=s, question=q)
            new.answer = a
        else:
            new = Survey(
                session = s,
                question = q,
                answer = a
            )
        new.save()

def insert_trial(data):
    session = Sessions.objects.get(django_key=data['user'])
    s = Sets.objects.get(id=data['setid'])
    trial = Trials(
        session = session,
        zoom = data['zoom'],
        start = data['start'],
        end = data['end'],
        duration_ms = data['duration'],
        set_id = s,
        layer1 = data['layers'][0],
        layer2 = data['layers'][1],
        layer3 = data['layers'][2],
        layer4 = data['layers'][3],
        layer5 = data['layers'][4]
    )
    trial.save()

    layers = data['objects']
    index = 1
    for l in layers:
        layer = index
        for o in l:
            nodes = []
            for p in o['geometry']:
                nodes.append(Point(p[0], p[1]))
            linestring = LineString(nodes, srid = 3857)
            line = Drawing(
                trial = trial,
                layer = layer,
                importance = o['importance'],
                thickness = o['thickness'],
                buffer = o['buffer'],
                geom_line = linestring,
                geom_poly = linestring.buffer(o['buffer'])
            )
            line.save()
        index += 1

def get_results(data, end):
    i = data['index']
    s = Sessions.objects.get(django_key=data['user'])
    if end:
        s.end = datetime.now(timezone.utc)
        s.save()

    usertrials = Trials.objects.filter(session=s)
    if i >= len(usertrials):
        i = 0
    usertrial = usertrials[i]
    userdrawing = Drawing.objects.filter(trial=usertrial)

    if usertrial.set_id.basemap == 'google':
        basemaptype = 'google'
        srid = 4326
    else:
        basemaptype = 'ol'
        srid = 3857

    user = serialize('geojson', userdrawing, geometry_field='geom_poly', fields=('layer', 'importance'), srid=srid)

    othertrials = Trials.objects.filter(zoom=usertrial.zoom, set_id=usertrial.set_id).exclude(session=s)
    if othertrials:
        othertrial = choice(othertrials)
        otherdrawing = Drawing.objects.filter(trial=othertrial)
        other = json.loads(serialize('geojson', otherdrawing, geometry_field='geom_poly', fields=('layer', 'importance'), srid=srid))
    else:
        other = False

    return {
        'index': i,
        'type': basemaptype,
        'basemap': usertrial.set_id.basemap,
        'center': [usertrial.set_id.x, usertrial.set_id.y],
        'zoom': usertrial.zoom,
        'user': json.loads(user),
        'other': other
    }


class Node:

    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

    def __str__(self):
        return str(self.data)

class BinarySearchTree:

    salary = 1000
    incre = 5

    def __init__(self):
        self.root = None

    def _insert(self, root, data):
        if root.data <= data:
            if root.right:
                self._insert(root.right, data)
            else:
                root.right = Node(data)

        if root.data > data:
            if root.left:
                self._insert(root.left, data)
            else:
                root.left = Node(data)

    def insert(self, data):
        if not self.root:
            self.root = Node(data)
        else:
            self._insert(self.root, data)

    def _inOrder(self, rt):
        if not rt:
            return
        self._inOrder(rt.left)
        print(rt.data, end=' ')
        self._inOrder(rt.right)

    def inOrder(self):
        root = self.root
        self._inOrder(root)

    @staticmethod
    def _findMiniNode(root):
        curr = root
        min_node = None
        while curr:
            min_node = curr
            curr = curr.left
        return min_node

    def _deleteNode(self, root, key):
        if root is None:
            print(f"Key '{key}' is not found")
            return
        if root.data < key:
            root.right = self._deleteNode(root.right, key)
        elif root.data > key:
            root.left = self._deleteNode(root.left, key)
        else:
            if root.left is None:
                return root.right
            elif root.right is None:
                return root.left
            else:
                min_right = self._findMiniNode(root.right)
                root.data = min_right.data
                root.right = self._deleteNode(root.right, min_right.data)
        return root

    def deleteNode(self, key):
        root = self.root
        self._deleteNode(root, key)

    @classmethod
    def func(cls):
        cls.salary = cls.salary * cls.incre

if __name__ == '__main__':
    bst = BinarySearchTree()
    bst.insert(5)
    bst.insert(6)
    bst.insert(8)
    bst.insert(2)
    bst.insert(0)
    bst.insert(1)
    bst.insert(10)
    bst.insert(22)
    bst.insert(7)
    bst.insert(7)
    bst.inOrder()
    bst.deleteNode(1000)
    print()
    bst.inOrder()


import json
from logging import getLogger

from datalad.dochelpers import borrowkwargs
from datalad.downloaders.http import HTTPDownloader
from datalad.support.exceptions import DownloadError
from datalad.utils import auto_repr

lgr = getLogger("datalad.downloaders.shub")

@auto_repr
class SHubDownloader(HTTPDownloader):
    """Resolve shub:// URLs before handing them off to HTTPDownloader.
    """

    api_url = "https://singularity-hub.org/api/container/"

    @borrowkwargs(HTTPDownloader)
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def _resolve_url(self, url):
        if not url.startswith("shub://"):
            return url

        info_url = self.api_url + url[7:]
        content = self.fetch(info_url)
        try:
            shub_info = json.loads(content)
        except json.decoder.JSONDecodeError as e:
            raise DownloadError(
                "Failed to get information from {}"
                .format(info_url)) from e
        return shub_info["image"]

    @borrowkwargs(HTTPDownloader)
    def access(self, method, url, *args, **kwargs):
        return super().access(method, self._resolve_url(url), *args, **kwargs)


# -*- coding: utf-8 -*-
import uuid
from datetime import datetime
from tempfile import NamedTemporaryFile
from time import time
from unittest.mock import MagicMock, patch

import pxapi
import pytest
from chaoslib.exceptions import ActivityFailed, InvalidExperiment

from chaospixie import (
    encode,
    execute_script,
    get_auth,
    handle_timestamp,
    load_script_from_file,
    nanotime_to_datetime,
    serialize_row,
)

PXL_SCRIPT = """
import px
df = px.DataFrame('http_events')[['resp_status','req_path']]
df = df.head(10)
px.display(df, 'http_table')
"""

def test_get_auth_expects_cluster_id():
    with pytest.raises(InvalidExperiment):
        get_auth({}, {"api_key": "secret"})

def test_get_auth_expects_api_key():
    with pytest.raises(InvalidExperiment):
        get_auth({"pixie_cluster_id": "abc"}, {})

def test_load_script_from_file_requires_realfile():
    with pytest.raises(ActivityFailed):
        load_script_from_file("blah.py")

def test_load_script_from_file():
    with NamedTemporaryFile() as f:
        f.write(PXL_SCRIPT.encode("utf-8"))
        f.seek(0)
        assert load_script_from_file(f.name) == PXL_SCRIPT

def test_serialize_row():
    r = MagicMock()
    r.columns = [
        MagicMock(column_name="cola", column_type=2),
        MagicMock(column_name="colb", column_type=2),
        MagicMock(column_name="colc", column_type=5),
    ]

    tableA = pxapi.data._TableStream(
        "a", relation=pxapi.data._Relation(r), subscribed=False
    )
    row = pxapi.data.Row(tableA, [1, 2, "three"])

    assert serialize_row(row) == {"cola": 1, "colb": 2, "colc": "three"}

def test_handle_time_():
    r = MagicMock()
    r.columns = [
        MagicMock(column_name="cola", column_type=2),
        MagicMock(column_name="colb", column_type=2),
        MagicMock(column_name="time_", column_type=6),
    ]

    tableA = pxapi.data._TableStream(
        "a", relation=pxapi.data._Relation(r), subscribed=False
    )
    row = pxapi.data.Row(tableA, [1, 2, int(time()) / 1e9])

    row = serialize_row(row)
    handle_timestamp(row)
    assert "_dt" in row

def test_handle_create_time():
    r = MagicMock()
    r.columns = [
        MagicMock(column_name="cola", column_type=2),
        MagicMock(column_name="colb", column_type=2),
        MagicMock(column_name="create_time", column_type=6),
    ]

    tableA = pxapi.data._TableStream(
        "a", relation=pxapi.data._Relation(r), subscribed=False
    )
    row = pxapi.data.Row(tableA, [1, 2, int(time()) / 1e9])

    row = serialize_row(row)
    handle_timestamp(row)
    assert "_dt" in row

def test_handle_start_time():
    r = MagicMock()
    r.columns = [
        MagicMock(column_name="cola", column_type=2),
        MagicMock(column_name="colb", column_type=2),
        MagicMock(column_name="start_time", column_type=6),
    ]

    tableA = pxapi.data._TableStream(
        "a", relation=pxapi.data._Relation(r), subscribed=False
    )
    row = pxapi.data.Row(tableA, [1, 2, int(time()) / 1e9])

    row = serialize_row(row)
    handle_timestamp(row)
    assert "_dt" in row

def test_encode_datetime():
    d = datetime.utcnow()
    i = d.isoformat()
    assert encode(d) == i

def test_encode_uuid():
    u = uuid.uuid4()
    assert encode(u) == str(u)

def test_nanotime_to_datetime():
    n = int(time()) * 1.0e9
    d = datetime.now()

    nanotime_to_datetime(n) == d

@patch("chaospixie.pxapi.Client", autospec=True)
def test_execute_script(client: MagicMock):
    c = MagicMock()
    s = MagicMock()
    c.prepare_script.return_value = s

    r = MagicMock()
    r.columns = [
        MagicMock(column_name="cola", column_type=2),
        MagicMock(column_name="colb", column_type=2),
        MagicMock(column_name="start_time", column_type=6),
    ]

    tableA = pxapi.data._TableStream(
        "a", relation=pxapi.data._Relation(r), subscribed=False
    )
    row = pxapi.data.Row(tableA, [1, 2, int(time()) / 1e9])

    s.results.return_value = [row]

    execute_script(c, PXL_SCRIPT, "http_table")