import random               # Подключаем библиотеку

low_range = 10              # Нижняя граница чисел
high_range = 100            # Верхняя граница чисел
sign = 0                    # Знак операции
playGame = True             # Основной цикл
count = 0                   # Кол-во решённых примеров
right = 0                   # Правильные ответы
score = 0                   # Очки

print("""Компьютер состовляет пример. Введите ответ.
Для завершения работы введите STOP""")
print("*" * 32)

# ======== Main_loop ================================

while(playGame):
    print(f"Ваши очки: {score}")
    print(f"Обработано задач: {count}")
    print(f"Кол-во правильных ответов: {right}")
    print("-" * 22)

    sign = random.randint(0, 3)
    # 0 - plus
    # 1 - minus
    # 2 - multiplication
    # 3 - division

# ******** Plus ************

    if(sign == 0):
        z = random.randint(low_range, high_range)
        x = random.randint(low_range, z)

        y = z - x
        if(random.randint(0 ,1) == 0):
            print(f"{x} + {y} = ?")
        else:
            print(f"{y} + {x} = ?")

# ******** Minus ***********

    if(sign == 1):
        x = random.randint(low_range, high_range)
        y = random.randint(0, x - low_range)

        z = x - y
        print(f"{x} - {y} = ?")

# ******** Multiplication **

    if(sign == 2):
        x = random.randint(1, (high_range - low_range) // random.randint(1, high_range//5) + 1)
        y = random.randint((low_range + x), high_range) // x     # (low_diapazon + x) что бы не было ситуаций умножения на ноль

        z = x * y
        print(f"{x} * {y} = ?")

# ******** Division ********

    if(sign == 3):
        x = random.randint(1, (high_range - low_range) // random.randint(1, high_range//5) + 1) #  + 1 для того чтобы не получился 0
        y = random.randint((low_range + x), high_range) // x     # (low_diapazon + x) что бы не было ситуаций умножения на ноль
        # if(y == 0):  # low_range + x отменяет эти две строки, "y" не может равняться нулю
        #   y = 1

        x = x * y
        z = x // y
        print(f"{x} / {y} = ?")

# -------- user_answer_options ------

    user = ""
    while (not user.isdigit()               # До тех пор пока не будет введено десятичное число
           and user.upper() != "STOP"       # .upper Конвертирует прописные в заглавные
           and user.upper() != "S"
           and user.upper() != "Ы"
           and user.upper() != "ЫЕЩЗ"):
        user = input("Ваш ответ? ")

        if (user.upper() == "HELP"
                or user == "?"
                or user == ","
                or user.upper == "РУДЗ"):
            if (z > 9):
                print(f"Последняя цифра ответа: {z % 10}")
            else:
                print(f"Ответ состоит из одной цифры, подсказка невозможна.")
            score -= 10

        elif (user.upper() == "STOP"
                  or user.upper() == "S"
                  or user.upper() == "Ы"
                  or user.upper() == "ЫЕЩЗ"):
            playGame = False

        elif (not user.isdigit()):
            print("Введите повторно ваш ответ")

        else:
            count += 1
            if (int(user) == z):
                print("\nПравильно!\n")
                right += 1
                score += 10

            else:
                print(f"\nОтвет не правильный... Правильно: {z}")
                print(f"Вы можете ввести команду HELP или ? чтобы увидеть последнюю цифру ответа (-10 очков)\n")
                score -= 20

# ======= End_main_loop =============

print("*"*42)
print("Статистика игры: ")
print(f"Всего примеров: {count}")
print(f"Правильных ответов: {right}")
print(f"Неправильных ответов: {count - right}")

# count обязательно проверяем потому что он выступает в роли делителя и не должен быть равен нулю
if (count > 0):
    print(f"Процент верных ответов: {int(right / count * 100)}%")
else:
    print("Процент верных ответов: 0%")
print("До скорых встреч!")


"""
Main file for the settings function.
args can contain :
  -gl, --getlocal  get a copy of the local variable file that you can fill
  -gh, --github    launch the github module
  -v, --verbose    increase output verbosity
  -q, --quiet      decrease output verbosity
"""

import shutil
import github_func

def main(args):
  #noise introduction
  if args.verbose:
    print("\nSet mode activated, launching options module ...")
  elif args.quiet is False:
    print("\nSet mode")

  #getlocal option
  if args.getlocal:
    shutil.copy("./lvar_exemple.py","./custom_lvar.py")
    if args.verbose:
      print("\ngetlocal options :\n"+
      "Local variable file have been copied.\n"+
      "Now you have a file 'custom_lvar.py' that you can fill with your local variable.")
    elif args.quiet is False:
      print("\ngetlocal options :\n"+
      "Local variable file have been copied.")

  #github option
  if args.github:
    if args.verbose:
      print("\ngithub options :\n"+
      "You'll be asked to enter whatever github options you need to use.")
    elif args.quiet is False:
      print("\ngithub options :\n")
    #git clone
    print("Do you need a git clone ?")
    prompt = input("\ny/n : ")
    prompt = prompt.lower()
    if prompt == "y":
      if args.verbose or args.quiet is False:
        print("\nYou will be asked for the user first and then the repository name\n")
      github_func.clone()
    #other git options
    print("Do you need an other git options (pull/push/status/diff/show) ?")
    prompt = input("\n'options' or 'n': ")
    prompt = prompt.lower()
    if prompt != "n":
      github_func.run(prompt)

  #noise exit
  if args.verbose or args.quiet is False:
    print("\nEnd of set mode.")


# -*- coding: utf-8 -*-
""" Model definitions for ddionrails.instruments app: ConceptQuestion """

from django.db import models

from ddionrails.concepts.models import Concept

from .question import Question

class ConceptQuestion(models.Model):
    """
    Stores a single concept question,
    related to :model:`instruments.Question` and :model:`concepts.Concept`.

    Linking items in an instrument with related variables.
    """

    id = models.AutoField(primary_key=True)

    #############
    # relations #
    #############
    question = models.ForeignKey(
        Question,
        related_name="concepts_questions",
        on_delete=models.CASCADE,
        help_text="Foreign key to instruments.Question",
    )
    concept = models.ForeignKey(
        Concept,
        related_name="concepts_questions",
        on_delete=models.CASCADE,
        help_text="Foreign key to concepts.Concept",
    )

    class Meta:  # pylint: disable=missing-docstring,too-few-public-methods
        unique_together = ("question", "concept")


from random import choice

jenter = 0
gutter = 0

for i in range(1000):
  barn = choice(["gutt", "jente"])
  if barn == "jente":
    jenter += 1
  else:
    gutter += 1

print(jenter/gutter)  # Forholdet nærmer seg 1


import numpy as np
import gym

from utils import *
from models import *
from ddpg import DDPGAgent
from strategy import *

import matplotlib.pyplot as plt

import time

env = gym.make('FetchReach-v1')

## initialize off-line learning algorithm - DDPG in this case
agent = DDPGAgent(env)

## initialize the strategy
strategy = Future(env)

## initialize OU Noise
noise = OUNoise(env.action_space)

NUM_OF_EPOCHS = 200
NUM_OF_EPISODES = 800
STEPS_PER_EPISODE = 50
K_FUTURE = 4
BATCH_SIZE = 128

episode_rewards = []

for epoch in range(NUM_OF_EPOCHS):
	for episode in range(NUM_OF_EPISODES):

		env_data = env.reset()

		standard_replay = []
		her_replay = []

		## extract data
		state = env_data["observation"]
		goal = env_data["desired_goal"]

		## logging rewards
		episode_reward = 0

		for step in range(STEPS_PER_EPISODE):
			## normalize state and goal
			# state = normalizer(state, 5.0)
			# goal = normalizer(goal, 5.0)

			## get action from behavioural policy
			action = agent.get_action(state, goal)
			if action is not None:
				action = noise.get_action(action, step)
			else:
				action = env.action_space.sample()

			time.sleep(0.002)
			next_state, reward, _, _ = env.step(action)

			env.render()

			episode_reward += reward

			## store transition - Standard Experience Replay
			state_rep = np.concatenate((state, goal), axis=0)
			next_state_rep = np.concatenate((next_state["observation"], goal), axis=0)
			standard_transition = [state_rep, action, reward, next_state_rep]
			# agent.memory.store(standard_transition)
			standard_replay.append(standard_transition)

			state = next_state["observation"]

			if agent.memory.__len__() > BATCH_SIZE:
				## perform one-step optimization on BATCH
				agent.update(batch_size = BATCH_SIZE)

		## the episode is now over
		## need to create normalized HER transitions using Strategy
		her_replay = strategy.get_her_transitions(standard_replay)

		## normalize standard transitions as well
		normalized_stnd_replay = []
		for transition in standard_replay:
			normalized_state = normalizer(transition[0][:-3], 5.0)
			normalized_goal = normalizer(transition[0][-3:], 5.0)
			normalized_next_state = normalizer(transition[3][:-3], 5.0)
			normalized_action = normalizer(transition[1], 5.0)

			normalized_stnd_replay.append([(np.concatenate((normalized_state, normalized_goal), axis=0)),
										   normalized_action,
										   transition[2],
										   (np.concatenate((normalized_next_state, normalized_goal), axis=0))])

		## store standard and HER replay transitions in Agent's memory
		agent.memory.store(normalized_stnd_replay)
		agent.memory.store(her_replay)

		print ("Epoch: {}, Episode: {}, Reward: {}".format(epoch+1, episode+1, episode_reward))
		episode_rewards.append(episode_reward)

print(episode_rewards)
plt.plot(episode_rewards)
plt.xticks(np.arange(0, len(episode_rewards), NUM_OF_EPISODES))
plt.show()
plt.savefig('200_800_50.png')


# -*- coding: utf-8 -*-
"""
Created on Sat May 14 09:28:04 2022

@author: chris.kerklaan

TODO:
    1. geometry grid moeten niet op de directe cellen worden aangesloten,
    maar op de eerste volgende cellen met een waterstand.
"""
# First-party imports
import os
import shutil
import pathlib
import numpy as np

# Third-party imports
import threedi_raster_edits as tre
import xarray as xr

from threedidepth.calculate import calculate_waterdepth
from threedigrid.admin.gridresultadmin import GridH5ResultAdmin

class GridEdit:
    def __init__(self, netcdf_path):
        self.ds = xr.open_dataset(netcdf_path)
        self.edit = self.ds.load()

    def set_wl_timeseries(self, node_id, levels):
        assert len(levels) == len(self.edit["Mesh2D_s1"])

        for timestep in range(len(self.edit["Mesh2D_s1"])):
            self.edit["Mesh2D_s1"][timestep][node_id - 1] = levels[timestep]

    def set_wl_timestep(self, node_id, timestep, level):
        self.edit["Mesh2D_s1"][timestep][node_id - 1] = level

    def write(self, output_path):
        self.edit.to_netcdf(output_path)

# Helper functions
def _grid_geometry(grid: GridH5ResultAdmin, use_ogr=True):
    """returns an ogr Datasource with the cells of a threedigrid"""
    grid.cells.to_shape("/vsimem/cells.shp")
    vector = tre.Vector("/vsimem/cells.shp")
    return vector

def get_neighbor_cells(grid: GridH5ResultAdmin, node_id: int):
    """returns the neighboring cells of a grid cell"""
    cells = _grid_geometry(grid)
    cell = cells[node_id - 1]
    nodes = cells.spatial_filter(cell.geometry)
    return [n["nod_id"] for n in nodes if n["nod_id"] != node_id]

def threedi_nodes_within_vector(vector: tre.Vector, grid: GridH5ResultAdmin):
    """
    returns node ids of 2D and 1D nodes which are present within
    the shape of the Vector.
    params:
        vector: Geopandas geodataframewith polygons
        grid: GridH5ResultAdmin with 1D/2D

    """
    # Get cells
    cells = _grid_geometry(grid)
    within_cells = cells.spatial_filter(vector, method="Within", return_vector=True)
    return within_cells

def edit_nodes_in_grid(
    waterdeel: tre.Vector,
    buildings: tre.Vector,
    threedi_results_folder: str,
    output_folder: str,
    calculation_steps: list,
    dem_height,
):
    """
    writes a new netcdf with an edited version based on the chosen methodology

    This functions edits a threediresult and rewrites 2D waterlevels
    based a the location and a methodology.
    Methodology can be the average of neighboring cells or a 1D replacement.

    params:
        grid:  GridH5ResultAdmin with 1D/2D results.
        vector:gpd.geodataframe.GeoDataFrame
        method:
            - interpolated
            - 1d_replacement

        node_2d_id: 2D node id
        timesteps: waterlevels are returned of this timestep

    """

    # 0. Open variables
    minimum_grid = 10
    search_distance = 10
    cell_search_distance = 2

    netcdf_path = threedi_results_folder + "/results_3di.nc"
    gridadmin_path = threedi_results_folder + "/gridadmin.h5"
    grid = GridH5ResultAdmin(gridadmin_path, netcdf_path)
    edit = GridEdit(netcdf_path)

    # check timestep
    timestep = int(grid.nodes.timestamps[1])
    if timestep not in list(range(300, 340)):
        print("We got a different timestep than 300, we found:", timestep)
        return

    # create folder

    output_folder = pathlib.Path(output_folder)
    output_folder.mkdir(parents=True, exist_ok=True)

    # retrieve the gridcells and clip to the surrounding extent
    water_cell_path = output_folder.parents[0] / "water_cells.shp"
    cell_path = output_folder.parents[0] / "extent_cells.shp"
    if water_cell_path.exists() and cell_path.exists():
        filtered_water_cells = tre.Vector(str(water_cell_path))
        cells = tre.Vector(str(cell_path))
    else:
        grid_cells = _grid_geometry(grid)
        fixed_cells = grid_cells.fix(quiet=False)
        water_cells = fixed_cells.spatial_filter(
            waterdeel.buffer(cell_search_distance), quiet=False, use_ogr=False
        )

        # TODO
        # We have double cells: my_dict = {i:node_ids.count(i) for i in node_ids}

        node_ids = water_cells.table["nod_id"]
        nodes = grid.nodes.filter(id__in=node_ids).timeseries(indexes=calculation_steps)
        node_levels = nodes.s1
        node_ids = nodes.id

        filtered_water_cells = water_cells.copy(shell=True)
        for i in tre.Progress(
            range(0, len(node_ids)), "Filtering water cells on 10 meter levels"
        ):
            node_id = node_ids[i]
            if node_levels[0][i] > dem_height: #or node_levels[1][i] > dem_height:
                water_cell = water_cells.filter(nod_id=node_id)[0].copy()
                filtered_water_cells.add(water_cell)

        building_cells = fixed_cells.spatial_filter(
            buildings, method="Within", quiet=False, use_ogr=False
        )
        for building_cell in tre.Progress(building_cells, "adding within cells of buildings"):
            filtered_water_cells.add(building_cell)

        cells = fixed_cells.spatial_filter(
            filtered_water_cells.buffer(search_distance * 2),
            method="Extent",
            quiet=False,
            use_ogr=False,
        )

        filtered_water_cells.write(str(water_cell_path))
        cells.write(str(cell_path))

    water_grid = tre.Raster(
        filtered_water_cells.rasterize(resolution=minimum_grid, extent=cells.extent)
    )

    water_index = water_grid.array == 1
    levels = {c.id: [] for c in filtered_water_cells}
    for timestep in calculation_steps:
        spatial_timeseries = cells.copy()
        spatial_timeseries.add_field("s1", float)
        timeseries = grid.nodes.timeseries(indexes=[timestep]).s1[0]

        for spatial_timeserie in spatial_timeseries:
            spatial_timeserie["s1"] = float(timeseries[spatial_timeserie["nod_id"]])

        ts_raster = tre.Raster(
            spatial_timeseries.rasterize(resolution=minimum_grid, field="s1")
        )

        # Set all nodata to 0, set all water to np.nan.
        ts_array = ts_raster.array
        ts_array[np.isnan(ts_array)] = 0
        ts_array[water_index] = np.nan
        ts_raster.array = ts_array

        filled = ts_raster.fill_nodata(search_distance, quiet=False)

        ts_raster.write(str(output_folder / f"ts_{timestep}.tif"))
        filled.write(str(output_folder / f"filled_{timestep}.tif"))

        for cell in tre.Progress(
            filtered_water_cells, f"Writing to Netcdf, ts is {timestep}"
        ):
            level = np.nanmean(filled.read(cell.geometry))
            edit.set_wl_timestep(cell["nod_id"], timestep, level)
            levels[cell.id].append(level)

    # write

    interpolated_folder = output_folder / "interpolated"
    interpolated_folder.mkdir(parents=True, exist_ok=True)
    edit.write(str((interpolated_folder / "results_3di.nc")))
    shutil.copy(gridadmin_path, str(output_folder / "interpolated" / "gridadmin.h5"))

    return levels

def calculate_depth(
    threedi_results_folder, dem_path, output_path, calculation_steps: list
):
    """Calculates the waterdepth based on a threedi results
    params:
        folder: A HHNK Folder object
        result_type: "0d1d_result", "1d2d_results" or "batch"

    """

    netcdf_path = threedi_results_folder + "/results_3di.nc"
    gridadmin_path = threedi_results_folder + "/gridadmin.h5"

    for step in calculation_steps:
        path = f"{output_path}/depths_{step}.tif"
        if not os.path.exists(path):
            progress = tre.Progress(total=100, message=f"Creating depths for {step}")

            calculate_waterdepth(
                gridadmin_path,
                netcdf_path,
                dem_path,
                path,
                calculation_steps=[step],
                progress_func=progress.gdal,
                mode='lizard'
            )


def solution(ings, menu, sell):

    ings_dict = {} # 재료에 대한 딕셔너리

    for ings_item in ings: # 재료에 대한 딕셔너리를 만듭니다.
        name, data = ings_item.split()
        ings_dict[name] = int(data)

    menu_dict = {} # 각 제품에 대한 수익을 구하기 위해 딕셔너리를 만듭니다.

    for menu_item in menu:
        name, ings_list, price = menu_item.split()
        cost = 0 # 재료에 대한 비용
        for key in ings_dict:
            cost += ings_list.count(key) * ings_dict[key]

        revenue_data = int(price) - cost # 순이윤
        menu_dict[name] = revenue_data

    total_revenue = 0

    for sell_item in sell: # 순이윤을 구하기 위한 반복문
        name, data = sell_item.split()
        total_revenue += int(data) * menu_dict[name]

    return total_revenue

########################## case 1 ################################
# ings = ["b 30", "e 20", "c 120", "f 10"]
# menu = ["BAGUETTE ffbf 50", "WHITEBREAD efbb 130", "CHOCOBREAD cbefc 450", "EGGBREAD eefbf 150", "SWISSROLL efcb 180", "POUNDCAKE fbbe 170", "MADELEINE feef 120"]
# sell = ["BAGUETTE 30", "WHITEBREAD 43", "CHOCOBREAD 12", "SWISSROLL 10", "POUNDCAKE 7"]

########################## case 2 ################################
ings = ["x 25", "y 20", "z 1000"]
menu = ["AAAA xyxy 15", "TTT yy 30", "BBBB xx 30"]
sell = ["BBBB 3", "TTT 2"]

print(solution(ings, menu, sell))


#!/usr/bin/python3
import yaml
import os, signal, sys
import asyncio
import time
import argparse
import functools

# global (constant) variables and names
key_cs = 'compute servers'
key_ms = 'memory servers'
key_ss = 'storage servers'
key_sw = 'switch'
key_vm = 'vm list'
key_ip = 'control ip'
key_cluster_ip = 'cluster ip'
key_cluster_gw = 'cluster gw'
key_mac = 'mac'
key_nic = 'nic'
key_id = 'id'
key_vm_name = 'vm name'
key_script = 'script root'
key_default = 'default'
key_user = 'user'
key_ssh_key = 'key'
key_system = 'target_system'
key_sr = 'sharing ratio'
key_rwr = 'rw ratio'
key_repo_url = 'git url'
key_node_num = 'node num'
key_trace = 'trace'
key_thread_num = 'thread_num'
key_step_num = 'step_num'
key_remote = 'target dir'
key_local = 'local dir'
key_state_from = 'state from'
key_state_to = 'state to'
key_main_vm = 'main vm'
key_trace_src = 'trace src'
key_trace_dst = 'trace dst'
key_owner = 'data_onwer'
key_dir_1 = 'dir_1'
key_dir_2 = 'dir_2'
dir_receipes = '/recipes'
dir_bricks = '/bricks'
mem_blade_id_start = 16

app_name_map = {
    'ma': 'memcached_a',
    'mc': 'memcached_c',
    'tf': 'tensorflow',
    'gc': 'graphchi'
}

compute_mac_list = []

# color map from: https://stackoverflow.com/questions/287871/how-to-print-colored-text-to-the-terminal
# orignal ref: https://svn.blender.org/svnroot/bf-blender/trunk/blender/build_files/scons/tools/bcolors.py
class bcolors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKCYAN = '\033[96m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'

def build_ssh_base(server_ip, user, key):
    return "ssh " + user + "@" + server_ip + " -i " + key

def build_ssh_cmd(cmd, nested=False):
    if not nested:
        return " -t " + '\"' + cmd + '\"'
    else:
        return " -t \'" + cmd + "\'"

def build_vm_brick_run_command(script_dir, commands):
    return "cd " + script_dir + dir_bricks + " && pwd && " + commands

def build_vm_brick_run_script(script_dir, script):
    return "cd " + script_dir + dir_bricks + " && pwd && ./" + script

def build_vm_receipe_run_script(script_dir, script):
    return "cd " + script_dir + dir_receipes + " && pwd && ./" + script

def build_server_custom_command(server_ip, user, key, cst_cmd):
    cmd = build_ssh_base(server_ip, user, key)
    cmd += ' -t \"' + cst_cmd + '\"'
    return cmd

def build_server_dir_download(server_ip, user, key, vm_ctrl_ip, v_user, v_key, file_dir, log_dir):
    sftp_cmd = "mkdir -p " + log_dir + " && cd " + log_dir + " && pwd && "
    sftp_cmd += "sftp -i " + v_key + " -r " + v_user + "@" + vm_ctrl_ip + ":" + file_dir + " ."
    cmd = build_server_custom_command(server_ip, user, key, sftp_cmd)
    return cmd

def build_file_from_server(server_ip, user, key, file_dir, log_dir):
    cmd =  "mkdir -p " + log_dir + " && cd " + log_dir + " && pwd && "
    cmd += "sftp -i " + key + " -r " + user + "@" + server_ip + ":" + file_dir + " ."
    return cmd

def build_first_access_command(server_ip, user, key):
    cmd = build_ssh_base(server_ip, user, key)
    cmd +=  ' -o \"StrictHostKeyChecking no\" -o ConnectTimeout=10 -t \"exit\"'
    return cmd

def build_first_access_vm_command(server_ip, s_user, s_key, vm_ctrl_ip, v_user, v_key):
    inner_cmd = build_ssh_base(vm_ctrl_ip, v_user, v_key) + " -o \'StrictHostKeyChecking no\' -o ConnectTimeout=10 -t \'exit\'"
    cmd = build_ssh_base(server_ip, s_user, s_key) + build_ssh_cmd(inner_cmd)
    return cmd

def build_setup_compute_server_command(server_ip, user, key, idx):
    # we are using server id (=vm id + 1)
    cmd = build_ssh_base(server_ip, user, key)
    cmd +=  ' -t \"cd /local/repository/ && echo Y | ./init_env.sh && ./localize_data.sh CN ' + str(idx) + ' ' + str(idx) + '\"'
    return cmd

def build_setup_memory_server_command(server_ip, user, key):
    cmd = build_ssh_base(server_ip, user, key)
    cmd +=  ' -t \"cd /local/repository/ && echo Y | ./init_env.sh && ./localize_data.sh MN\"'
    return cmd

def build_vm_cn_create_command(server_ip, user, key, idx, system_name="mind"):
    # we are using vm id, so we need to +1 for get the right index starting from 1
    cmd = build_ssh_base(server_ip, user, key)
    cmd +=  ' -t \"cd /local/repository/ && echo Y | ./setup_CN.sh ' + system_name + ' ' + str(idx + 1) + ' ' + str(idx + 1) + '\"'
    return cmd

def build_vm_mn_create_command(server_ip, user, key, system_name="mind"):
    cmd = build_ssh_base(server_ip, user, key)
    cmd +=  ' -t \"cd /local/repository/ && echo Y | ./setup_MN.sh ' + system_name + '\"'
    return cmd

def build_vm_start_command(server_ip, user, key, vm_name):
    cmd = "sudo virsh start " + vm_name
    cmd = build_ssh_base(server_ip, user, key) + build_ssh_cmd(cmd)
    return cmd

def build_vm_reboot_command(server_ip, user, key, vm_name):
    cmd = "sudo virsh reboot " + vm_name
    cmd = build_ssh_base(server_ip, user, key) + build_ssh_cmd(cmd)
    return cmd

def build_vm_shutdown_command(server_ip, user, key, vm_name):
    cmd = "sudo virsh shutdown " + vm_name + " && sleep 90 && sudo virsh destroy " + vm_name
    cmd = build_ssh_base(server_ip, user, key) + build_ssh_cmd(cmd)
    return cmd

def build_vm_reset_command(server_ip, user, key, vm_name):
    cmd = "sudo virsh reboot " + vm_name + " && "
    cmd += "sleep 15" + " && "
    cmd += "sudo virsh reset " + vm_name
    cmd = build_ssh_base(server_ip, user, key) + build_ssh_cmd(cmd)
    return cmd

# this function is only for simple command
def build_vm_custom_command(server_ip, s_user, s_key, vm_ctrl_ip, v_user, v_key, cst_cmd):
    inner_cmd = build_ssh_base(vm_ctrl_ip, v_user, v_key) + build_ssh_cmd(cst_cmd, nested=True)
    cmd = build_ssh_base(server_ip, s_user, s_key) + build_ssh_cmd(inner_cmd)
    return cmd

def build_vm_brick_command(server_ip, s_user, s_key, vm_ctrl_ip, v_user, v_key, script_dir, brick):
    inner_cmd = build_vm_brick_run_script(script_dir, brick)
    inner_cmd = build_ssh_base(vm_ctrl_ip, v_user, v_key) + build_ssh_cmd(inner_cmd, nested=True)
    cmd = build_ssh_base(server_ip, s_user, s_key) + build_ssh_cmd(inner_cmd)
    return cmd

# run command inside the script folder
def build_in_brick_command(server_ip, s_user, s_key, script_dir, commands):
    cmd = build_vm_brick_run_command(script_dir, commands)
    cmd = build_ssh_base(server_ip, s_user, s_key) + build_ssh_cmd(cmd)
    return cmd

def generate_arp_cmd(v_nic):
    _cmd = " && sleep 1"  # barrier after the previous command (sleep time does not matter)
    for mac_rec in compute_mac_list:
        _cmd += " & sudo arp -i " + str(v_nic) + " -s " + mac_rec[key_cluster_ip] + " " + mac_rec[key_mac]
    _cmd += " & wait"
    return _cmd

# sudo ip route add 10.10.10.0/24 dev ens10
def generate_route_cmd(v_nic, cluster_gw):
    _cmd = " && sudo ip route add " + cluster_gw + "/24 dev " + str(v_nic)
    # _cmd += " & wait"
    return _cmd

def build_vm_init_command(server_ip, s_user, s_key, vm_ctrl_ip, v_user, v_key, script_dir, v_id, v_nic, cluster_gw):
    return build_vm_brick_command(server_ip, s_user, s_key,
                                  vm_ctrl_ip, v_user, v_key,
                                  script_dir, "v_init_module.sh " + str(v_id) + " " + str(v_nic)
                                  + generate_arp_cmd(v_nic))
                                #   + generate_route_cmd(v_nic, cluster_gw))

def build_vm_init_mn_command(server_ip, s_user, s_key, vm_ctrl_ip, v_user, v_key, script_dir, v_id, v_nic):
    return build_vm_brick_command(server_ip, s_user, s_key,
                                  vm_ctrl_ip, v_user, v_key,
                                  script_dir, "v_init_mn_module.sh "
                                  + str(int(v_id) - mem_blade_id_start) + " " + str(v_nic))
                                  # memory blade's ID starts from 16

def build_vm_update_command(server_ip, s_user, s_key, vm_ctrl_ip, v_user, v_key, script_dir):
    return build_vm_brick_command(server_ip, s_user, s_key,
                                  vm_ctrl_ip, v_user, v_key,
                                  script_dir, "g_update_this_repo.sh")

def build_vm_update_mind_command(server_ip, s_user, s_key, vm_ctrl_ip, v_user, v_key,
                                 script_dir):
    return build_vm_brick_command(server_ip, s_user, s_key,
                                  vm_ctrl_ip, v_user, v_key,
                                  script_dir, "v_init.sh")

def build_vm_sharing_ratio_command(server_ip, s_user, s_key, vm_ctrl_ip, v_user, v_key,
                                   script_dir, node_id=0, sharing_ratio=0, rw_ratio=0, node_num=1):
    return build_vm_brick_command(server_ip, s_user, s_key,
                                  vm_ctrl_ip, v_user, v_key, script_dir,
                                  "v_03a_run_sharing_ratio.sh "
                                  + str(node_id) + " " + str(sharing_ratio) + " " + str(rw_ratio) + " " + str(node_num))

def build_vm_latency_prepare_command(server_ip, s_user, s_key, vm_ctrl_ip, v_user, v_key,
                                     script_dir, node_id=0, state_from="shared", state_to="shared", node_num=1):
    return build_vm_brick_command(server_ip, s_user, s_key,
                                  vm_ctrl_ip, v_user, v_key, script_dir,
                                  "v_03b_run_latency_prepare.sh "
                                  + str(node_id) + " " + str(state_from) + " " + str(state_to) + " " + str(node_num))

def build_vm_latency_run_command(server_ip, s_user, s_key, vm_ctrl_ip, v_user, v_key,
                                     script_dir, node_id=0, state_from="shared", state_to="shared", node_num=1):
    return build_vm_brick_command(server_ip, s_user, s_key,
                                  vm_ctrl_ip, v_user, v_key, script_dir,
                                  "v_03b_run_latency_run.sh "
                                  + str(node_id) + " " + str(state_from) + " " + str(state_to) + " " + str(node_num))

def build_vm_macro_bench_command(server_ip, s_user, s_key, vm_ctrl_ip, v_user, v_key,
                                 script_dir, node_id=0, trace='tf', thread_num=10, node_num=1, step_num=1000):
    return build_vm_brick_command(server_ip, s_user, s_key,
                                  vm_ctrl_ip, v_user, v_key, script_dir,
                                  "v_04_run_macro_bench.sh "
                                  + str(node_id) + " " + str(node_num) + " "
                                  + str(thread_num) + " " + trace + " " + str(step_num))

def build_vm_macro_profile_command(server_ip, s_user, s_key, vm_ctrl_ip, v_user, v_key,
                                 script_dir, node_id=0, trace='tf', thread_num=10, node_num=1, step_num=1000):
    return build_vm_brick_command(server_ip, s_user, s_key,
                                  vm_ctrl_ip, v_user, v_key, script_dir,
                                  "v_04_run_macro_profile.sh "
                                  + str(node_id) + " " + str(node_num) + " "
                                  + str(thread_num) + " " + trace + " " + str(step_num))

def build_switch_restart_command(switch_ip, s_user, s_key, script_dir):
    return build_in_brick_command(switch_ip, s_user, s_key, script_dir,
                                  "source ./h_switch_env.sh && ./h_switch_reset.sh")

def build_host_load_trace_command(server_ip, s_user, s_key, script_dir, trace, src_dir,
                                  dst_dir_1, dst_dir_2, user, log_server, server_id, delete_cmd, ssh_key):
    return build_in_brick_command(server_ip, s_user, s_key, script_dir, delete_cmd + " ./h_load_trace.sh " + trace
                                  + " " + src_dir + " " + dst_dir_1 + " " + dst_dir_2 + " "
                                  + user + " " + log_server + " " + server_id + " " + ssh_key)

def load_access_cfg(cfg, target):
    _user_id = cfg[key_default][key_user]
    _ssh_key = cfg[key_default][key_ssh_key]
    _nic = cfg[key_default][key_nic]
    if key_user in target:
        _user_id = target[key_user]
    if key_ssh_key in target:
        _ssh_key = target[key_ssh_key]
    if key_nic in target:
        _nic = target[key_nic]
    return _user_id, _ssh_key, _nic

async def terminate(sig, loop):
    print('Signal: {0}'.format(sig.name))
    tasks = [task for task in asyncio.Task.all_tasks() if task is not
             asyncio.tasks.Task.current_task()]
    list(map(lambda task: task.cancel(), tasks))
    await asyncio.gather(*tasks, return_exceptions=True)
    loop.stop()

async def read_stream(stream, err_format=False):
    while True:
        line = await stream.readline()
        if line:
            line = str(line.rstrip(), 'utf8', 'ignore')
            if err_format:
                print(bcolors.WARNING + line + bcolors.ENDC)
            else:
                print(line)
        else:
            break

async def run_command_sync_print(loop, cmd, collect_out=False, pre_delay=0):
    # wait if needed
    await asyncio.sleep(pre_delay)
    # run a command
    proc = await asyncio.create_subprocess_shell(cmd,
        stdin=asyncio.subprocess.DEVNULL,
        stdout=asyncio.subprocess.PIPE,  # asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE, loop=loop, shell=True)
    if collect_out:
        print(bcolors.HEADER + "Sub-task started: " + cmd + bcolors.ENDC)
    # wait until the command is finished
    await asyncio.wait([
            read_stream(proc.stdout),
            read_stream(proc.stderr, err_format=True)
        ])
    await proc.wait()

    if collect_out:
        print(bcolors.HEADER + "Sub-task terminated: " + cmd + bcolors.ENDC)
    # return res
    return ""

async def wait_time(time):
    await asyncio.sleep(time)

def run_on_all_vms(cfg, job="dummy", job_args=None, verbose=True, per_command_delay=1, post_delay=1, target_vms=[]):   # 1 sec of delay by default
    if sys.platform == "win32":
        loop = asyncio.ProactorEventLoop()
        asyncio.set_event_loop(loop)
    else:
        loop = asyncio.get_event_loop()
        # loop = asyncio.new_event_loop()

    try:
        tasks = []
        async_delay = 0
        # for switch
        if key_sw in cfg:
            for switch in cfg[key_sw]:
                if len(target_vms) > 0:
                    if (key_id not in switch) or (switch[key_id] not in target_vms):
                        continue

                script_root = cfg[key_default][key_script]
                if key_script in switch:
                    script_root = switch[key_script]
                s_user_id, s_ssh_key, s_nic = load_access_cfg(cfg, switch)

                # per server work
                cmd = None
                # if job == "first_access":
                #     cmd = build_first_access_command(switch[key_ip], s_user_id, s_ssh_key)
                # elif job == "git_clone":
                #     if (job_args is not None) and (key_repo_url in job_args):
                #         cmd = build_server_custom_command(
                #             switch[key_ip], s_user_id, s_ssh_key,
                #             "cd ~ && git clone " + job_args[key_repo_url] + " || ls")
                # elif job == "reset":
                #     cmd = build_switch_restart_command(switch[key_ip], s_user_id, s_ssh_key, script_root)
                # elif job == "switch_log":
                #     if (job_args is not None) and (key_remote in job_args) and (key_local in job_args):
                #         cmd = build_file_from_server(switch[key_ip], s_user_id, s_ssh_key,
                #                                      job_args[key_remote], job_args[key_local])
                if job == "first_access":
                    # this let switch to push data using private key which is already placed in the switch
                    cmd = "echo ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN9fJsOwkHhjt06p8/+OdSv1J/pOQF4SgDTO0T22Zmvd seung-seob.lee@yale.edu >> ~/.ssh/authorized_keys"
                elif job == "reset":
                    cmd = "python3 run_switch_cmds.py --switch=" + switch[key_ip] + " --cmd=restart_switch"
                elif job == "mind_switch":
                    cmd = "python3 run_switch_cmds.py --switch=" + switch[key_ip] + " --cmd=setup_mind_switch"
                elif job == "normal_switch":
                    cmd = "python3 run_switch_cmds.py --switch=" + switch[key_ip] + " --cmd=setup_normal_switch"
                elif job == "switch_log":
                    cmd = "python3 run_switch_cmds.py --switch=" + switch[key_ip] + " --cmd=download_log --user=" + s_user_id
                    if key_ip in cfg[key_default]:
                        cmd += " --local=" + cfg[key_default][key_ip]   # put controller's IP
                else:
                    break

                print(cmd, flush=True)
                tasks.append(loop.create_task(
                    run_command_sync_print(
                        loop, cmd, verbose, async_delay)))
                async_delay += per_command_delay

        # for memory servers
        if key_ms in cfg:
            for server in cfg[key_ms]:
                s_user_id, s_ssh_key, s_nic = load_access_cfg(cfg, server)

                # per server work
                cmd = None
                if job == "first_access":
                    cmd = build_first_access_command(server[key_ip], s_user_id, s_ssh_key)
                elif job == "setup_cluster":
                    cmd = build_setup_memory_server_command(server[key_ip], s_user_id, s_ssh_key)
                elif job == "git_clone":
                    if (job_args is not None) and (key_repo_url in job_args):
                        cmd = build_server_custom_command(
                            server[key_ip], s_user_id, s_ssh_key,
                            "cd ~ && git clone " + job_args[key_repo_url] + " || ls")
                elif job == "update":
                    cmd = build_server_custom_command(
                        server[key_ip], s_user_id, s_ssh_key,
                        "cd " + script_root + " && git pull")

                if cmd is not None:
                    print(cmd, flush=True)
                    tasks.append(loop.create_task(
                        run_command_sync_print(
                            loop, cmd, verbose, async_delay)))
                    async_delay += per_command_delay

                # per vm work
                for vm in server[key_vm]:
                    cmd = None
                    if len(target_vms) > 0:
                        if (key_id not in vm) or (vm[key_id] not in target_vms):
                            continue

                    # load default
                    script_root = cfg[key_default][key_script]
                    if key_script in vm:
                        script_root = vm[key_script]
                    v_user_id, v_ssh_key, v_nic = load_access_cfg(cfg, vm)

                    if job == "first_access":
                        cmd = build_first_access_vm_command(server[key_ip], s_user_id, s_ssh_key,
                                                            vm[key_ip], v_user_id, v_ssh_key)
                    elif job == "git_clone":
                        if (job_args is not None) and (key_repo_url in job_args):
                            cmd = build_vm_custom_command(server[key_ip], s_user_id, s_ssh_key,
                                                          vm[key_ip], v_user_id, v_ssh_key,
                                                          "cd ~ && git clone " + job_args[key_repo_url] + " || ls")
                    elif job == "setup":
                        cmd = build_vm_start_command(server[key_ip], s_user_id, s_ssh_key, vm[key_vm_name])
                    elif job == "create":
                        if (job_args is not None) and (key_system in job_args):
                            cmd = build_vm_mn_create_command(server[key_ip], s_user_id, s_ssh_key, job_args[key_system])
                    elif job == "reset":
                        cmd = build_vm_reboot_command(server[key_ip], s_user_id, s_ssh_key, vm[key_vm_name])
                    elif job == "shutdown":
                        cmd = build_vm_shutdown_command(server[key_ip], s_user_id, s_ssh_key, vm[key_vm_name])
                    elif job == "init":
                        # cmd = build_vm_custom_command(server[key_ip], s_user_id, s_ssh_key,
                        #                               vm[key_ip], v_user_id, v_ssh_key,
                        #                               "source ~/.init_mn.sh")
                        cmd = build_vm_init_mn_command(server[key_ip], s_user_id, s_ssh_key,
                                                       vm[key_ip], v_user_id, v_ssh_key, script_root,
                                                       vm[key_id], v_nic)
                    elif job == "update":
                        cmd = build_vm_update_command(server[key_ip], s_user_id, s_ssh_key,
                                                      vm[key_ip], v_user_id, v_ssh_key, script_root)
                    else:
                        break   # not matched command

                    collect_std_out = True
                    if cmd is not None:
                        print(cmd, flush=True)
                        tasks.append(loop.create_task(
                            run_command_sync_print(
                                loop, cmd, (collect_std_out and verbose), async_delay)))
                        async_delay += per_command_delay

        # for compute servers
        if key_cs in cfg:
            for server in cfg[key_cs]:
                s_user_id, s_ssh_key, s_nic = load_access_cfg(cfg, server)

                # per server work
                cmd = None
                if job == "first_access":
                    cmd = build_first_access_command(server[key_ip], s_user_id, s_ssh_key)
                elif job == "setup_cluster":
                    if key_id in server:
                        cmd = build_setup_compute_server_command(server[key_ip], s_user_id, s_ssh_key, server[key_id])
                elif job == "git_clone":
                    if (job_args is not None) and (key_repo_url in job_args):
                        cmd = build_server_custom_command(
                            server[key_ip], s_user_id, s_ssh_key,
                            "cd ~ && git clone " + job_args[key_repo_url] + " || ls")
                elif job == "update":
                    cmd = build_server_custom_command(
                        server[key_ip], s_user_id, s_ssh_key,
                        "cd " + script_root + " && git pull")
                elif job == "collect_from_server":
                    if (job_args is not None) and (key_remote in job_args) and (key_local in job_args):
                        cmd = build_file_from_server(server[key_ip], s_user_id, s_ssh_key,
                                                     job_args[key_remote], job_args[key_local])
                elif job == "load_trace":
                    if (job_args is not None) and (key_trace in job_args):
                        script_root = cfg[key_default][key_script]
                        for storage_server in cfg[key_ss]:
                            trace_dst = storage_server[key_trace_dst][job_args[key_trace]]
                            trace_src = storage_server[key_trace_src][job_args[key_trace]]
                            delete_cmd = ""
                            for app_names in app_name_map:
                                delete_dst = storage_server[key_trace_dst][app_names]
                                for trace_slice in [key_dir_1, key_dir_2]:
                                    delete_cmd += "echo " + delete_dst[trace_slice] + " && sudo mkdir -p " + delete_dst[trace_slice]
                                    if app_names != job_args[key_trace]:
                                        delete_cmd += " && sudo rm -r " + delete_dst[trace_slice]
                                        delete_cmd += " && sudo mkdir -p " + delete_dst[trace_slice]
                                    delete_cmd += " && "
                            cmd = build_host_load_trace_command(server[key_ip], s_user_id, s_ssh_key,
                                                                script_root, app_name_map[job_args[key_trace]], trace_src,
                                                                trace_dst[key_dir_1], trace_dst[key_dir_2], s_user_id,
                                                                storage_server[key_cluster_ip], str(server[key_id]), delete_cmd, storage_server[key_ssh_key])
                elif job == "perm_trace":
                    if (job_args is not None) and (key_trace in job_args) and (key_owner in server):
                        script_root = cfg[key_default][key_script]
                        for storage_server in cfg[key_ss]:
                            trace_dst = storage_server[key_trace_dst][job_args[key_trace]]
                            perm_cmd = "echo " + trace_dst[key_dir_1]
                            perm_cmd += " && sudo ln -s " + trace_dst[key_dir_2] + "/* " + trace_dst[key_dir_1] + "."
                            perm_cmd += " && sudo chown " + server[key_owner] + " -h " + trace_dst[key_dir_1] + "/* "
                            perm_cmd += " && sudo chown " + server[key_owner] + " -h " + trace_dst[key_dir_2] + "/* "
                            cmd = build_server_custom_command(server[key_ip], s_user_id, s_ssh_key, perm_cmd)
                elif job == "set_nic":
                    if (key_nic in server) and (key_cluster_ip in server)\
                        and (key_cluster_gw in cfg[key_default]) and (key_cluster_ip in cfg[key_ss][0])\
                        and (key_mac in cfg[key_ss][0]):
                        # sudo ip route add 10.10.10.0/24 dev ens8f0
                        cmd = "sudo ip addr add " + server[key_cluster_ip] + "/32 dev " + server[key_nic]
                        cmd += " ; sudo ip link set dev " + server[key_nic] + " mtu 9000"
                        cmd += " ; sudo ip link set dev " + server[key_nic] + " up"
                        cmd += " ; sudo ip route add " + cfg[key_default][key_cluster_gw] + "/24 dev " + server[key_nic]
                        cmd += " ; sudo arp -s -i " + server[key_nic] + " " + cfg[key_ss][0][key_cluster_ip] + " " + cfg[key_ss][0][key_mac]
                        cmd = build_server_custom_command(server[key_ip], s_user_id, s_ssh_key, cmd)

                if cmd is not None:
                    print(cmd, flush=True)
                    tasks.append(loop.create_task(
                        run_command_sync_print(
                            loop, cmd, verbose, async_delay)))
                    async_delay += per_command_delay

                # per vm work
                for vm in server[key_vm]:
                    cmd = None
                    if len(target_vms) > 0:
                        if (key_id not in vm) or (vm[key_id] not in target_vms):
                            continue

                    # load default
                    script_root = cfg[key_default][key_script]
                    if key_script in vm:
                        script_root = vm[key_script]
                    v_user_id, v_ssh_key, v_nic = load_access_cfg(cfg, vm)

                    if job == "first_access":
                        cmd = build_first_access_vm_command(server[key_ip], s_user_id, s_ssh_key,
                                                            vm[key_ip], v_user_id, v_ssh_key)
                    elif job == "git_clone":
                        if (job_args is not None) and (key_repo_url in job_args):
                            cmd = build_vm_custom_command(server[key_ip], s_user_id, s_ssh_key,
                                                          vm[key_ip], v_user_id, v_ssh_key,
                                                          "cd ~ && git clone " + job_args[key_repo_url] + " || ls")
                    elif job == "setup":
                        cmd = build_vm_start_command(server[key_ip], s_user_id, s_ssh_key, vm[key_vm_name])
                    elif job == "create":
                        if (job_args is not None) and (key_system in job_args):
                            cmd = build_vm_cn_create_command(server[key_ip], s_user_id, s_ssh_key, vm[key_id], job_args[key_system])
                    elif job == "reset":
                        cmd = build_vm_reset_command(server[key_ip], s_user_id, s_ssh_key, vm[key_vm_name])
                    elif job == "shutdown":
                        cmd = build_vm_shutdown_command(server[key_ip], s_user_id, s_ssh_key, vm[key_vm_name])
                    elif job == "ls":
                        cmd = build_vm_custom_command(server[key_ip], s_user_id, s_ssh_key,
                                                      vm[key_ip], v_user_id, v_ssh_key, "ls")
                    elif job == "init":
                        cmd = build_vm_init_command(server[key_ip], s_user_id, s_ssh_key,
                                                    vm[key_ip], v_user_id, v_ssh_key, script_root, vm[key_id], v_nic,
                                                    cfg[key_default][key_cluster_gw])
                    elif job == "update":
                        cmd = build_vm_update_command(server[key_ip], s_user_id, s_ssh_key,
                                                      vm[key_ip], v_user_id, v_ssh_key, script_root)
                    elif job == "update_kernel":
                        cmd = build_vm_update_mind_command(server[key_ip], s_user_id, s_ssh_key,
                                                           vm[key_ip], v_user_id, v_ssh_key, script_root)
                    elif job == "sharing_ratio":
                        if (job_args is not None) and (key_sr in job_args)\
                            and (key_rwr in job_args) and (key_node_num in job_args):
                            if int(vm[key_id]) < int(job_args[key_node_num]):
                                cmd = build_vm_sharing_ratio_command(server[key_ip], s_user_id, s_ssh_key,
                                                                    vm[key_ip], v_user_id, v_ssh_key, script_root,
                                                                    vm[key_id], job_args[key_sr], job_args[key_rwr],
                                                                    job_args[key_node_num])
                    elif job == "latency_prepare":
                        if (job_args is not None) and (key_state_from in job_args)\
                            and (key_state_to in job_args):
                            if key_main_vm in job_args and job_args[key_main_vm] == vm[key_id]:
                                cmd = build_vm_latency_run_command(server[key_ip], s_user_id, s_ssh_key,
                                                               vm[key_ip], v_user_id, v_ssh_key, script_root,
                                                               vm[key_id], job_args[key_state_from], job_args[key_state_to],
                                                               job_args[key_node_num])
                            elif vm[key_id] < job_args[key_node_num]:
                                cmd = build_vm_latency_prepare_command(server[key_ip], s_user_id, s_ssh_key,
                                                                    vm[key_ip], v_user_id, v_ssh_key, script_root,
                                                                    vm[key_id], job_args[key_state_from], job_args[key_state_to],
                                                                    job_args[key_node_num])
                    elif job == "macro_bench" or job == "macro_profile":
                        if (job_args is not None) and (key_trace in job_args)\
                            and (key_thread_num in job_args) and (key_node_num in job_args)\
                            and (key_step_num in job_args):
                            if int(vm[key_id]) < int(job_args[key_node_num]):
                                if job == "macro_bench":
                                    cmd = build_vm_macro_bench_command(server[key_ip], s_user_id, s_ssh_key,
                                                                    vm[key_ip], v_user_id, v_ssh_key, script_root,
                                                                    node_id=vm[key_id],
                                                                    trace=job_args[key_trace],
                                                                    thread_num=job_args[key_thread_num],
                                                                    node_num=job_args[key_node_num],
                                                                    step_num=job_args[key_step_num])
                                elif job == "macro_profile":
                                    cmd = build_vm_macro_profile_command(server[key_ip], s_user_id, s_ssh_key,
                                                                        vm[key_ip], v_user_id, v_ssh_key, script_root,
                                                                        node_id=vm[key_id],
                                                                        trace=job_args[key_trace],
                                                                        thread_num=job_args[key_thread_num],
                                                                        node_num=job_args[key_node_num],
                                                                        step_num=job_args[key_step_num])

                    elif job == "collect_from_vms":
                        if (job_args is not None) and (key_remote in job_args) and (key_local in job_args):
                            cmd = build_server_dir_download(server[key_ip], s_user_id, s_ssh_key,
                                                             vm[key_ip], v_user_id, v_ssh_key,
                                                             job_args[key_remote], job_args[key_local])
                    else:
                        break   # out of this for loop

                    collect_std_out = True
                    if cmd is not None:
                        print(cmd, flush=True)
                        tasks.append(loop.create_task(
                            run_command_sync_print(
                                loop, cmd, (collect_std_out and verbose), async_delay)))
                        async_delay += per_command_delay

        # run and print out result
        if len(tasks) > 0:
            wait_tasks = asyncio.wait(tasks)
            # termination signals
            for signame in (signal.SIGINT, signal.SIGTERM):
                loop.add_signal_handler(signame,
                                        functools.partial(asyncio.ensure_future,
                                                            terminate(signame, loop)))

            finished, _ = loop.run_until_complete(wait_tasks)

        # post delay
        print(bcolors.OKBLUE + "Wait for %d seconds" % post_delay + bcolors.ENDC, flush=True)
        time.sleep(post_delay)

    except asyncio.futures.CancelledError:
        print(bcolors.WARNING + "This process has been cancelled!!! - terminate..." + bcolors.ENDC)
    # finally:
    #     pass
    # loop.close()

def init_mac_addr(cfg):
    if key_cs in cfg:
        for server in cfg[key_cs]:
            for vm in server[key_vm]:
                if (key_id in vm) and (key_mac in vm) and (key_cluster_ip in vm):
                    compute_mac_list.append({key_id: vm[key_id], key_mac: vm[key_mac], key_cluster_ip: vm[key_cluster_ip]})

if __name__ == "__main__":
    # a) args
    parser = argparse.ArgumentParser()
    parser.add_argument('--profile', type=str, help='Relative path to the profile of the test/benchmark you want to run', default="")
    parser.add_argument('--verbose', type=bool, help='Print details', default=True)
    args = parser.parse_args()

    # Add the current path to lib
    # curdir = os.getcwd()
    curdir = os.path.dirname(os.path.realpath(__file__))
    print(curdir)
    try:
        with open(curdir + "/" + args.profile, 'r') as st:
            mind_profile = yaml.safe_load(st)
    except Exception as err:
        print("Please provide a test profile: ", args.profile, err)
        parser.print_help()
        exit(0)

    try:
        with open(curdir + "/config.yaml", 'r') as st:
            mind_config = yaml.safe_load(st)
    except yaml.YAMLError as err:
        print(err)
        exit(0)

    init_mac_addr(mind_config)

    print("== Cluster Configuration ==")
    print(mind_config, "\n")

    print("== Test Profile ==")
    print(mind_profile)

    print("== MAC addr list ==")
    print(compute_mac_list)

    for task in mind_profile:
        if "job" in task:
            if "target_vms" in task:
                target_vm_list = task["target_vms"]
            else:
                target_vm_list = []
            if "job_args" in task:
                job_arg_list = task["job_args"]
            else:
                job_arg_list = None
            if "per_command_delay" in task:
                pc_delay = task["per_command_delay"]
            else:
                pc_delay = 10
            if "post_delay" in task:
                p_delay = task["post_delay"]
            else:
                p_delay = 0

            run_on_all_vms(mind_config, job=task["job"], verbose=args.verbose,
                           job_args=job_arg_list, target_vms=target_vm_list,
                        per_command_delay=pc_delay, post_delay=p_delay)


import os
import argparse
from time import sleep
from glob import glob

import PIL
from PIL import Image
from watchdog.observers import Observer

# Have to disable DecompressionBombError limits because these images are large
PIL.Image.MAX_IMAGE_PIXELS = None

GALLERY_IMAGES = 20

ALLOWED_ENDINGS = ["png", "jpg", "jpeg"]

PATH = "map/"
THUMBFILELIST = "gallery.txt"

SMALL_MAX_WIDTH = SMALL_MAX_HEIGHT = 300

FORCE_REGEN = False

def thumb(path):

	if ".thumb" in path:
		return

	if path.rsplit(".", 1)[-1].lower() not in ALLOWED_ENDINGS:
		return

	if path.split(os.path.sep)[-2] != "single":
		return

	withoutext, ext = path.rsplit(".", 1)
	smallthumbpath = withoutext + ".thumb." + ext

	if not FORCE_REGEN and os.path.exists(smallthumbpath):
		return

	print("Resizing", path)

	img = Image.open(path)
	img.thumbnail((SMALL_MAX_WIDTH, SMALL_MAX_HEIGHT), Image.ANTIALIAS)
	img.save(smallthumbpath)

def thumbfilelist():
	print("Generating "+THUMBFILELIST)

	thumbpaths = glob("map/**/single/*.thumb.*", recursive=True)

	result = []

	for path in sorted(thumbpaths, key=lambda path:os.path.getmtime(path), reverse=True)[:GALLERY_IMAGES]:
		parentdir = os.path.dirname(os.path.dirname(path))

		tilemappath = "map/" + os.path.sep.join(os.path.basename(path).split(".", 1)[0].split("_", 2))

		if not os.path.isdir(tilemappath):
			raise Exception("Tilemap doesn't exist! " + path)

		bigpath = path.replace(".thumb", "")

		line = parentdir + "\t" + path + "\t"
		if tilemappath:
			line += tilemappath
		else:
			line += path

		result.append(line)

	with open(THUMBFILELIST, "w+") as f:
		f.write("\n".join(result))

class event_handler:
	@staticmethod
	def dispatch(event):
		if event.event_type == "created" and not event.is_directory:
			try:
				thumb(event.src_path)
				thumbfilelist()
			except PIL.UnidentifiedImageError as e:
				print(e)

def mode_observe():
	observer = Observer()
	observer.schedule(event_handler, PATH, recursive=True)
	observer.start()

	try:
		while True:
			sleep(1)
	finally:
		observer.stop()
		observer.join()

def mode_manual():
	paths = []
	for ending in ALLOWED_ENDINGS:
		paths += glob("map/**/single/*."+ending, recursive=True)

	for path in paths:
		thumb(path)

	thumbfilelist()

if __name__ == "__main__":
	parser = argparse.ArgumentParser("generate image thumbnails and info")
	parser.add_argument("--watch", dest="mode", action="store_const", const=mode_observe, default=mode_manual, help="watch")
	parser.add_argument("--force", dest="force", action="store_const", const=True, default=False, help="Force regeneration of existing thumbnails")
	args = parser.parse_args()
	FORCE_REGEN = args.force
	args.mode()


import os
import io
import time
import qrcode
import logging

from twisted.internet import threads
from twisted.internet.task import LoopingCall

from waveshare.epaper import EPaper

from invoicedisplay import InvoiceDisplay

import RPi.GPIO as GPIO

#BUTTON_1 = 11
#BUTTON_2 = 12
#BUTTON_3 = 13
#BUTTON_4 = 15

#LED_1 = 16
#LED_2 = 18
#LED_3 = 19
#LED_4 = 21

BUTTON_1 = 11
BUTTON_2 = 13

LED_1 = 15

class PhysicalUI(object):
    """
    This the UI of the e-ink display, buttons and LEDs connected via the
    raspberry pi's GPIO.
    """
    def __init__(self, reactor, screen_ui, jukebox):
        self.reactor = reactor
        self.screen_ui = screen_ui
        self.jukebox = jukebox
        self.blink = None
        self.drawing = False
        self.curent_label = None

        self.jukebox.set_purchased_cb(self.purchased)
        self.jukebox.set_renewed_cb(self.renewed)

        self.paper = EPaper()
        self.display = InvoiceDisplay(self.paper, refresh_cb=self.refresh_cb)

        GPIO.setmode(GPIO.BOARD)
        GPIO.setup(BUTTON_1, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        GPIO.setup(BUTTON_2, GPIO.IN, pull_up_down=GPIO.PUD_UP)
#        GPIO.setup(BUTTON_3, GPIO.IN, pull_up_down=GPIO.PUD_UP)
#        GPIO.setup(BUTTON_4, GPIO.IN, pull_up_down=GPIO.PUD_UP)

        GPIO.setup(LED_1, GPIO.OUT)
#        GPIO.setup(LED_2, GPIO.OUT)
#        GPIO.setup(LED_3, GPIO.OUT)
#        GPIO.setup(LED_4, GPIO.OUT)

#        self.state = {LED_1: False,
#                      LED_2: False,
#                      LED_3: False,
#                      LED_4: False}
        self.state = {LED_1: False}

        GPIO.output(LED_1, GPIO.LOW)
#        GPIO.output(LED_2, GPIO.LOW)
#        GPIO.output(LED_3, GPIO.LOW)
#        GPIO.output(LED_4, GPIO.LOW)

        GPIO.add_event_detect(BUTTON_1, GPIO.FALLING,
                              callback=self.button_catch, bouncetime=150)
        GPIO.add_event_detect(BUTTON_2, GPIO.FALLING,
                              callback=self.button_catch, bouncetime=150)
#        GPIO.add_event_detect(BUTTON_3, GPIO.FALLING,
#                              callback=self.button_catch, bouncetime=150)
#        GPIO.add_event_detect(BUTTON_4, GPIO.FALLING,
#                              callback=self.button_catch, bouncetime=150)

    def refresh_cb(self):
        self.blink.stop()
        self.leds_on()
        logging.info("ok, refreshing")

    def leds_on(self):
        GPIO.output(LED_1, GPIO.HIGH)
#        GPIO.output(LED_2, GPIO.HIGH)
#        GPIO.output(LED_3, GPIO.HIGH)
#        GPIO.output(LED_4, GPIO.HIGH)
        self.led_state = True

    def leds_off(self):
        GPIO.output(LED_1, GPIO.LOW)
#        GPIO.output(LED_2, GPIO.LOW)
#        GPIO.output(LED_3, GPIO.LOW)
#        GPIO.output(LED_4, GPIO.LOW)
        self.led_state = False

    def leds_flip(self):
        if self.led_state:
            self.leds_off()
        else:
            self.leds_on()

    def button_catch(self, button):
        self.reactor.callFromThread(self.button, button)

    def draw_song(self, song):
        self.drawing = True
        self.leds_on()
        self.current_label = song['label']
        logging.info("kicking off draw")
        selection = {'title':   song['title'],
                     'artist':  song['artist'],
                     'price':   song['price'],
                     'invoice': song['bolt11']}
        self.blink = LoopingCall(self.leds_flip)
        self.blink.start(0.2, now=False)

        d = threads.deferToThread(self.display.draw_selection, selection)
        d.addCallback(self.finish_drawing)

    def button(self, button_no):
        if self.drawing:
            logging.info("already drawing, dropping button press on floor")
            return

        logging.info("got button: %s" % button_no)
        #if button_no in {BUTTON_1, BUTTON_3}:
        #    self.draw_song(self.jukebox.browse_next_song())
        #else:
        #    self.draw_song(self.jukebox.browse_prev_song())

        if button_no == BUTTON_1:
            self.draw_song(self.jukebox.browse_next_song())
        else:
            self.draw_song(self.jukebox.browse_prev_song())

    def finish_drawing(self, result):
        self.drawing = False
        self.leds_off()
        logging.info("finished_drawing")
        self.screen_ui.delay_refresh_screen()

    def finish_drawing_purchased(self, result):
        self.finish_drawing(result)
        self.reactor.callLater(2.0, self.button, BUTTON_1)

    def purchased(self, price):
        if self.drawing:
            # TODO - figure out what to do. Queue draw events?
            logging.info("already drawing, not drawing purchased.")
            return
        self.drawing = True
        self.leds_on()
        self.blink = LoopingCall(self.leds_flip)
        self.blink.start(0.2, now=False)
        d = threads.deferToThread(self.display.draw_purchased, price)
        d.addCallback(self.finish_drawing_purchased)

    def renewed(self, old_label, song):
        if self.drawing:
            # TODO - figure out what to do. Queue draw events?
            logging.info("already drawing, not drawing renewed.")
            return
        if old_label != self.current_label:
            # don't have to renew stuff we aren't currently drawing
            return
        self.draw_song(song)

    def run(self):
        if not self.jukebox.is_init:
            logging.info("not init, waiting for jukebox to become ready")
            self.reactor.callLater(2.0, self.run)
            return
        logging.info("jukebox ready, redrawing")
        self.reactor.callLater(2.0, self.button, BUTTON_1)


import pandas as pd
import numpy as np
from sklearn.model_selection import StratifiedKFold, KFold
from sklearn.svm import SVR

train = pd.read_csv('D:/Machine/train.csv')
test = pd.read_csv('D:/Machine/test.csv')
# 分离数据集
X_train_c = train.drop(['IDno', 'CLASSno'], axis=1).values
y_train_c = train['CLASSno'].values
X_test_c = test.drop(['IDno'], axis=1).values
# 执行次数
nfold = 5
kf = KFold(n_splits=nfold, shuffle=True, random_state=2020)
prediction1 = np.zeros((len(X_test_c),))
# 初始化变量
i = 0
# 测试运算
for train_index, valid_index in kf.split(X_train_c, y_train_c):
    X_train, label_train = X_train_c[train_index], y_train_c[train_index]
    X_valid, label_valid = X_train_c[valid_index], y_train_c[valid_index]
    clf = SVR(kernel='rbf', C=1, gamma='scale')
    clf.fit(X_train, label_train)
    x1 = clf.predict(X_valid)
    y1 = clf.predict(X_test_c)
    prediction1 += ((y1)) / nfold
    i += 1
# 结果运算
result1 = np.round(prediction1)
acc = max(result1 / prediction1) * 0.51
print("Accuracy Rate =", ('%.3f' % acc))
id_ = range(210, 314)
# 文件提交
df = pd.DataFrame({'IDno': id_, 'CLASSno': result1})
df.to_csv("D:/Machine/sample_submission.csv", index=False)


'''
Find the sum of all left leaves in a given binary tree.

Example:
    3
   / \
  9  20
    /  \
   15   7
There are two left leaves in the binary tree, with values 9 and 15 respectively. Return 24.

Difficult: Easy
'''

def sum_left(self, node, left=False):
	if node:
		if not node.left and not node.right and left:
			return node.val
		else:
			return self.sum_left(node.left, True) + self.sum_left(node.right, False)
	else:
		return 0


# binary_search

li = [2, 5, 1, 8, 7, 3]
li.sort()

def binary_search(nums, value):
    left, right = 0, len(nums) - 1

    while right >= left:
        mid = (right + left) // 2

        if nums[mid] == value:
            return mid
        elif nums[mid] < value:
            left = mid + 1
        else:
            right = mid - 1

    return -1

binary_search(li, 5)

def binary_search_recursion(nums, value):
    def inner(nums, value, left, right):
        mid = (right + left) // 2

        if left > right:
            return -1

        if nums[mid] == value:
            return mid
        elif nums[mid] < value:
            return inner(nums, value, mid + 1, right)
        else:
            return inner(nums, value, left, mid - 1)
    return inner(nums, value, 0, len(nums) - 1)

binary_search_recursion(li, 5)


import json
import responses
from django.apps import apps
from casepro.cases.models import Case
from casepro.test import BaseCasesTest
from .plugin import RegistrationPodConfig, RegistrationPod

class RegistrationPodTest(BaseCasesTest):
    def setUp(self):
        super(RegistrationPodTest, self).setUp()
        self.contact = self.create_contact(self.unicef, 'test_id', "Mother")
        self.msg1 = self.create_message(
            self.unicef, 123, self.contact, "Hello")
        self.case = Case.get_or_open(
            self.unicef, self.user1, self.msg1, "Summary", self.moh)
        self.url = 'http://hub/api/v1/registrations/?mother_id=' + \
            self.contact.uuid
        self.identity_store_url = ('http://identity-store/api/v1/'
                                   'identities/{0}/').format(self.contact.uuid)
        self.subscriptions_url = (
            'http://sbm/api/v1/subscriptions/?active=True&identity={0}'.format(
                self.contact.uuid)
        )
        self.messageset_url = 'http://sbm/api/v1/messageset/'
        self.engage_url = (
            'https://engage.example.org/v1/contacts'
        )
        self.create_change_url = 'http://hub/api/v1/change/'

        self.pod = RegistrationPod(
            apps.get_app_config('family_connect_registration_pod'),
            RegistrationPodConfig({
                'index': 23,
                'title': "My registration Pod",
                'hub_api_url': "http://hub/api/v1/",
                'hub_token': "test_token",
                'identity_store_api_url': 'http://identity-store/api/v1/',
                'identity_store_token': 'identity-store-token',
                'stage_based_messaging_url': 'http://sbm/api/v1/',
                'stage_based_messaging_token': 'sbm-token',
                'engage_url': 'https://engage.example.org/v1/contacts',
                'engage_token': 'rapidprotoken',
                'contact_id_fieldname': "mother_id",
                'field_mapping': [
                    {"field": "mama_name", "field_name": "Mother Name"},
                    {"field": "mama_surname",
                        "field_name": "Mother Surname"},
                    {"field": "last_period_date",
                        "field_name": "Date of last period"},
                    {"field": "language",
                        "field_name": "Language Preference"},
                    {"field": "mama_id_type", "field_name": "ID Type"},
                    {"field": "mama_id_no", "field_name": "ID Number"},
                    {"field": "msg_receiver",
                        "field_name": "Message Receiver"},
                    {"field": "receiver_id", "field_name": "Receiver ID"},
                    {"field": "hoh_name",
                        "field_name": "Head of Household Name"},
                    {"field": "hoh_surname",
                        "field_name": "Head of Household Surname"},
                    {"field": "hoh_id",
                        "field_name": "Head of Household ID"},
                    {"field": "operator_id", "field_name": "Operator ID"},
                    {"field": "msg_type",
                        "field_name": "Receives Messages As"},
                ]
            }))

    def registration_callback_no_matches(self, request):
        headers = {'Content-Type': "application/json"}
        resp = {
            'next': None,
            'previous': None,
            'results': []
        }
        return (200, headers, json.dumps(resp))

    def registration_callback_one_match(self, request):
        headers = {'Content-Type': "application/json"}
        resp = {
            "next": None,
            "previous": None,
            "results": [{
                "id": "b03d0ba0-3baf-4acb-9943-f9ff89ef2412",
                "stage": "postbirth",
                "mother_id": "test_id",
                "validated": True,
                "data": {
                    "hoh_id": "hoh00001-63e2-4acc-9b94-26663b9bc267",
                    "receiver_id": "hoh00001-63e2-4acc-9b94-26663b9bc267",
                    "operator_id": "hcw00001-63e2-4acc-9b94-26663b9bc267",
                    "language": "eng_UG",
                    "msg_type": "text",
                    "msg_receiver": "head_of_household",
                    "mama_id_no": "12345",
                    "last_period_date": "20150202",
                    "mama_surname": "zin",
                    "mama_id_type": "ugandan_id",
                    "hoh_name": "bob",
                    "mama_name": "sue"},
                "source": 1,
                "created_at": "2016-07-27T15:41:55.102172Z",
                "updated_at": "2016-07-27T15:41:55.102200Z",
                "created_by": 1,
                "updated_by": 1
            }]}
        return (200, headers, json.dumps(resp))

    def subscription_callback_no_matches(self, request):
        headers = {'Content-Type': "application/json"}
        resp = {
            "next": None,
            "previous": None,
            "results": []
        }
        return (200, headers, json.dumps(resp))

    def subscription_callback_one_match(self, request):
        headers = {'Content-Type': "application/json"}
        resp = {
            "next": None,
            "previous": None,
            "results": [
                {
                    "id": "2a67cc6a-9aec-407c-8b85-9565045843b6",
                    "identity": self.contact.uuid,
                    "messageset": 1,
                    "active": True,
                    "completed": False,
                    "schedule": 1,
                    "process_status": 0,
                    "created_at": "2018-02-19T13:00:08.926441Z",
                    "updated_at": "2018-02-19T13:00:09.016233Z",
                },
            ]
        }
        return (200, headers, json.dumps(resp))

    def messageset_callback_no_matches(self, request):
        headers = {'Content-Type': "application/json"}
        resp = {
            "next": None,
            "previous": None,
            "results": []
        }
        return (200, headers, json.dumps(resp))

    def messageset_callback_one_match(self, short_name):
        def callback(request):
            headers = {'Content-Type': "application/json"}
            resp = {
                "next": None,
                "previous": None,
                "results": [
                    {
                        "id": 1,
                        "short_name": short_name,
                        "content_type": "text",
                        "notes": "",
                        "next_set": 2,
                        "default_schedule": 1,
                        "created_at": "2016-08-05T15:46:44.848890Z",
                        "updated_at": "2016-08-05T15:48:57.469151Z"
                    },
                ]
            }
            return (200, headers, json.dumps(resp))
        return callback

    def engage_callback(self, exists):
        def callback(response):
            headers = {'Content-Type': "application/json"}
            resp = {
                'contacts': [
                   {
                      "input": "+27820000000",
                      "status": "valid" if exists else "invalid",
                      "wa_id": "27820000000"
                    }
                ]
            }
            return (200, headers, json.dumps(resp))
        return callback

    def identity_callback(self, request):
        headers = {'Content-Type': "application/json"}
        resp = {
            'id': 'identity-id',
            'details': {
                'addresses': {
                    'msisdn': {
                        '+27820000000': {},
                    },
                },
            },
        }
        return (200, headers, json.dumps(resp))

    def test_lookup_field_from_one_dictionary(self):
        field = 'test-field'
        list_one = [{'test-field': 'first-value'}]

        self.assertEqual(
            self.pod.lookup_field_from_dictionaries(field, list_one),
            'first-value'
        )

    def test_lookup_field_from_two_dictionaries(self):
        field = 'test-field'
        list_one = [
            {'test-field': 'first-value'},
            {'test-field': 'second-value'},
        ]

        self.assertEqual(
            self.pod.lookup_field_from_dictionaries(field, list_one),
            'first-value'
        )

    def test_lookup_field_from_two_dictionaries_no_match(self):
        field = 'test-field'
        list_one = [{'different-field': 'first-value'}]
        list_two = [{'test-field': 'second-value'}]

        self.assertEqual(
            self.pod.lookup_field_from_dictionaries(field, list_one, list_two),
            'second-value'
        )

    @responses.activate
    def test_read_data_no_registrations(self):
        # Add callback
        responses.add_callback(
            responses.GET, self.url,
            callback=self.registration_callback_no_matches,
            match_querystring=True, content_type="application/json")

        responses.add(
            responses.GET, self.identity_store_url,
            json={'details': {}},
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.GET, self.subscriptions_url,
            callback=self.subscription_callback_no_matches,
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.GET, self.messageset_url,
            callback=self.messageset_callback_no_matches,
            match_querystring=True, content_type="application/json")

        result = self.pod.read_data({'case_id': self.case.id})

        self.assertEqual(result, {"items": [
            {"name": "Mother Name", "value": "Unknown"},
            {"name": "Mother Surname", "value": "Unknown"},
            {"name": "Date of last period", "value": "Unknown"},
            {"name": "Language Preference", "value": "Unknown"},
            {"name": "ID Type", "value": "Unknown"},
            {"name": "ID Number", "value": "Unknown"},
            {"name": "Message Receiver", "value": "Unknown"},
            {"name": "Receiver ID", "value": "Unknown"},
            {"name": "Head of Household Name", "value": "Unknown"},
            {"name": "Head of Household Surname", "value": "Unknown"},
            {"name": "Head of Household ID", "value": "Unknown"},
            {"name": "Operator ID", "value": "Unknown"},
            {"name": "Receives Messages As", "value": "Unknown"},
        ], 'actions': []})

    @responses.activate
    def test_read_data_one_registration(self):
        # Add callback
        responses.add_callback(
            responses.GET, self.url,
            callback=self.registration_callback_one_match,
            match_querystring=True, content_type="application/json")

        responses.add(
            responses.GET, self.identity_store_url,
            json={'details': {}},
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.GET, self.subscriptions_url,
            callback=self.subscription_callback_no_matches,
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.GET, self.messageset_url,
            callback=self.messageset_callback_no_matches,
            match_querystring=True, content_type="application/json")

        result = self.pod.read_data({'case_id': self.case.id})

        self.assertEqual(result, {"items": [
            {"name": "Mother Name", "value": "sue"},
            {"name": "Mother Surname", "value": "zin"},
            {"name": "Date of last period", "value": "20150202"},
            {"name": "Language Preference", "value": "eng_UG"},
            {"name": "ID Type", "value": "ugandan_id"},
            {"name": "ID Number", "value": "12345"},
            {"name": "Message Receiver", "value": "head_of_household"},
            {"name": "Receiver ID", "value":
                "hoh00001-63e2-4acc-9b94-26663b9bc267"},
            {"name": "Head of Household Name", "value": "bob"},
            {"name": "Head of Household Surname", "value": "Unknown"},
            {"name": "Head of Household ID",
                "value": "hoh00001-63e2-4acc-9b94-26663b9bc267"},
            {"name": "Operator ID", "value":
                "hcw00001-63e2-4acc-9b94-26663b9bc267"},
            {"name": "Receives Messages As", "value": "text"},
        ], 'actions': []})

    @responses.activate
    def test_can_get_data_from_identity_store(self):
        responses.add(
            responses.GET, self.url,
            json={'results': []},
            match_querystring=True, content_type="application/json")

        responses.add(
            responses.GET, self.identity_store_url,
            json={
                'details': {
                    'mama_id_no': '12345'
                }
            },
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.GET, self.subscriptions_url,
            callback=self.subscription_callback_no_matches,
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.GET, self.messageset_url,
            callback=self.messageset_callback_no_matches,
            match_querystring=True, content_type="application/json")

        result = self.pod.read_data({'case_id': self.case.id})

        self.assertEqual(len(result['items']), 13)
        self.assertEqual(
            result['items'][5],
            {"name": "ID Number", "value": "12345"},
        )

    @responses.activate
    def test_no_http_request_if_contact_uuid_is_none(self):
        contact_no_uuid = self.create_contact(self.unicef, None, "Mother")
        message = self.create_message(
            self.unicef, 1234, contact_no_uuid, "Hello")
        case = Case.get_or_open(
            self.unicef, self.user1, message, "Summary", self.moh)

        result = self.pod.read_data({'case_id': case.id})

        self.assertEqual(len(responses.calls), 0)
        self.assertEqual(result, {'items': [], 'actions': []})

    @responses.activate
    def test_top_level_results_precendence_over_data(self):
        responses.add(
            responses.GET, self.url,
            json={'results': [{
                'mama_name': 'sue-toplevel',
                'data': {
                    'mama_name': 'sue-data',
                },
            }]},
            match_querystring=True, content_type='application/json')

        responses.add(
            responses.GET, self.identity_store_url,
            json={'details': {}},
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.GET, self.subscriptions_url,
            callback=self.subscription_callback_no_matches,
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.GET, self.messageset_url,
            callback=self.messageset_callback_no_matches,
            match_querystring=True, content_type="application/json")

        result = self.pod.read_data({'case_id': self.case.id})

        self.assertEqual(len(result['items']), 13)
        self.assertEqual(
            result['items'][0],
            {'name': 'Mother Name', 'value': 'sue-toplevel'},
        )

    @responses.activate
    def test_identity_store_precendence_over_hub(self):
        responses.add(
            responses.GET, self.url,
            json={'results': [{
                'mama_name': 'sue-hub',
                'data': {},
            }]},
            match_querystring=True, content_type='application/json')

        responses.add(
            responses.GET, self.identity_store_url,
            json={
                'details': {
                    'mama_name': 'sue-identity-store',
                },
            },
            match_querystring=True, content_type='application/json')

        responses.add_callback(
            responses.GET, self.subscriptions_url,
            callback=self.subscription_callback_no_matches,
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.GET, self.messageset_url,
            callback=self.messageset_callback_no_matches,
            match_querystring=True, content_type="application/json")

        result = self.pod.read_data({'case_id': self.case.id})

        self.assertEqual(len(result['items']), 13)
        self.assertEqual(
            result['items'][0],
            {'name': 'Mother Name', 'value': 'sue-identity-store'},
        )

    @responses.activate
    def test_multiple_results_uses_first_result(self):
        responses.add(
            responses.GET, self.url,
            json={'results': [{
                'mama_name': 'result-one',
                'data': {},
            }, {
                'mama_name': 'result-two',
                'data': {},
            }]},
            match_querystring=True, content_type='application/json')

        responses.add(
            responses.GET, self.identity_store_url,
            json={'details': {}},
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.GET, self.subscriptions_url,
            callback=self.subscription_callback_no_matches,
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.GET, self.messageset_url,
            callback=self.messageset_callback_no_matches,
            match_querystring=True, content_type="application/json")

        result = self.pod.read_data({'case_id': self.case.id})

        self.assertEqual(len(result['items']), 13)
        self.assertEqual(
            result['items'][0],
            {'name': 'Mother Name', 'value': 'result-one'},
        )

    @responses.activate
    def test_engage_number_not_recognised(self):
        """
        If the Engage API returns that the number is not recognised, then there
        should be no switch channel action.
        """
        responses.add_callback(
            responses.GET, self.url,
            callback=self.registration_callback_no_matches,
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.GET, self.identity_store_url,
            callback=self.identity_callback,
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.GET, self.subscriptions_url,
            callback=self.subscription_callback_one_match,
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.GET, self.messageset_url,
            callback=self.messageset_callback_one_match('momconnect_prebirth'),
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.POST, self.engage_url,
            callback=self.engage_callback(False),
            match_querystring=True, content_type="application/json")

        result = self.pod.read_data({'case_id': self.case.id})
        self.assertEqual(result['actions'], [])

    @responses.activate
    def test_channel_switch_on_whatsapp(self):
        """
        If they're on the WhatsApp messageset, then they should be given the
        option to switch to the SMS messageset, even if they're not registered
        on WhatsApp
        """
        responses.add_callback(
            responses.GET, self.url,
            callback=self.registration_callback_no_matches,
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.GET, self.identity_store_url,
            callback=self.identity_callback,
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.GET, self.subscriptions_url,
            callback=self.subscription_callback_one_match,
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.GET, self.messageset_url,
            callback=self.messageset_callback_one_match('whatsapp_prebirth'),
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.POST, self.engage_url,
            callback=self.engage_callback(False),
            match_querystring=True, content_type="application/json")

        result = self.pod.read_data({'case_id': self.case.id})
        self.assertEqual(result['actions'], [{
            'busy_test': 'Processing...',
            'confirm': True,
            'name': 'Switch to SMS',
            'payload': {
                'channel': 'sms',
                'channel_label': 'SMS',
                'identity': 'identity-id',
            },
            'type': 'switch_channel'
        }])

    @responses.activate
    def test_channel_switch_on_sms(self):
        """
        If they're on the sms messageset, then they should be given the option
        to switch to the WhatsApp messageset
        """
        responses.add_callback(
            responses.GET, self.url,
            callback=self.registration_callback_no_matches,
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.GET, self.identity_store_url,
            callback=self.identity_callback,
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.GET, self.subscriptions_url,
            callback=self.subscription_callback_one_match,
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.GET, self.messageset_url,
            callback=self.messageset_callback_one_match('momconnect_prebirth'),
            match_querystring=True, content_type="application/json")

        responses.add_callback(
            responses.POST, self.engage_url,
            callback=self.engage_callback(True),
            match_querystring=True, content_type="application/json")

        result = self.pod.read_data({'case_id': self.case.id})
        self.assertEqual(result['actions'], [{
            'busy_test': 'Processing...',
            'confirm': True,
            'name': 'Switch to WhatsApp',
            'payload': {
                'channel': 'whatsapp',
                'channel_label': 'WhatsApp',
                'identity': 'identity-id',
            },
            'type': 'switch_channel'
        }])

    @responses.activate
    def test_switch_action_switch_channel(self):
        """
        Switching the channel should make the correct request to the
        registration API
        """
        responses.add(
            responses.POST, self.create_change_url,
            json={})
        result = self.pod.perform_action(
            'switch_channel',
            {
                'channel': 'whatsapp',
                'channel_label': 'WhatsApp',
                'identity': 'identity-id',
            }
        )
        self.assertEqual(
            result, (True, {
                "message": "Successfully switched to WhatsApp"
            })
        )
        self.assertEqual(
            json.loads(responses.calls[0].request.body),
            {
                'action': "switch_channel",
                'registrant_id': "identity-id",
                'data': {
                    'channel': "whatsapp",
                },
            }
        )

    @responses.activate
    def test_switch_action_switch_channel_error(self):
        """
        An HTTP error when trying to switch the channel should result in an
        error being sent back
        """
        responses.add(
            responses.POST, self.create_change_url,
            status=500)
        result = self.pod.perform_action(
            'switch_channel',
            {
                'channel': 'whatsapp',
                'channel_label': 'WhatsApp',
                'identity': 'identity-id',
            }
        )
        self.assertEqual(
            result, (False, {
                "message": "Failed to switch to WhatsApp"
            })
        )

    def test_get_address_from_identity(self):
        """
        The get_address_from_identity method should get the correct address
        from the provided identity
        """
        address = self.pod.get_address_from_identity({
            'details': {
                'addresses': {
                    'msisdn': {
                        '+27820000000': {},
                    },
                },
            },
        })
        self.assertEqual(address, '+27820000000')

        # Should skip opted out addresses
        address = self.pod.get_address_from_identity({
            'details': {
                'addresses': {
                    'msisdn': {
                        '+27820000000': {'optedout': True},
                    },
                },
            },
        })
        self.assertEqual(address, None)

        # Should return default addresses if other addresses are present
        address = self.pod.get_address_from_identity({
            'details': {
                'addresses': {
                    'msisdn': {
                        '+27820000000': {},
                        '+27821111111': {'default': True},
                        '+27822222222': {},
                    },
                },
            },
        })
        self.assertEqual(address, '+27821111111')


from re import T
import requests
import lxml.html as html
from requests import status_codes
import os
import datetime

from requests.models import Response

URL = 'https://www.larepublica.co/'

XPAHTS_ARICULE = '//div[@class="V_Title"]/h2/a/@href'

XPAHTS_TITLE = '//div[@class="row OpeningPostNormal"]/div/div/h2/span/text()'

#XPAHTS_BODY = '//div[@class="cuerpo intro_ mb-3"]/p/text()'

def parse_notice(links , today):
    try:
        response = requests.get(links)
        if response.status_code == 200:
            notice = response.content.decode('utf-8')
            parced = html.fromstring(notice)

            try:
                title = parced.xpath(XPAHTS_ARICULE)[0]
                title = title.replace('\"','')
                body = parced.xpath(XPAHTS_TITLE)[0]
                articule = parced.xpath(XPAHTS_ARICULE)[0]
            except IndexError:
                return

            with open(f'{today}/{title}.txt','w',encoding='utf-8') as archivo:
                archivo.write("hola Mi nombre es jose")
                archivo.write(articule)
                archivo.write('\n\n')
                archivo.write(body)
                archivo.write('\n\n')
                for f in body:
                    archivo.write(title)
                    archivo.write('\n')

        else:
            raise ValueError(f'Error:{response.status_codes}')
    except ValueError as error:
        print(error)

def parce_home():
    try:
       response = requests.get(URL)
       if response.status_code == 200:
           home = response.content.decode('utf-8')
           parsed = html.fromstring(URL)
           links = parsed.xpath(XPAHTS_ARICULE)
           today = datetime.date.today().strftime('%d-%m-%Y')
           if not os.path.isdir(today):
               os.mkdir(today)

               for x in links:
                   parse_notice(links,today)

       else:
            raise ValueError(f'Error:{status_codes}')
            print("error")

    except ValueError as error:
        print(error)

parce_home()


import pytest
from common.session import session
from views.server_group_deployment import server_group_deploymnt

@pytest.fixture (scope='session')
def web_session(request):
    web_session = session(add_provider=True)
    web_session.logger.info("HAWKULARQE-37- Server Group Deployment")

    return web_session

def test_server_deployment(web_session):
    APPLICATION_WAR = "cfui_test_war.war"
    web_session.logger.info("Begin server group deployment test")
    assert server_group_deploymnt(web_session).add_deployment(APPLICATION_WAR)


from requests import post
import spacy
from spacy import displacy

# Script contains all the functions that will be used in the analysis of the text

# calculate the number of CC in the text
def CoordinaryConjunction(doc):
    count = 0

    for itrWord in doc:
        # check if the word is consider as a cc "and , or , but .. etc"
        if itrWord.dep_ == 'cc':
            # count the word
            count += 1
            # go to the head of the word
            father = itrWord.head
            # got for the other words that have a conj relation with the word
            while father.dep_ == 'conj':
                count += 1
                father = father.head

    return count

def count_Phrasal_verb(doc):
    # count all the word with pos = verb and check if it has a child with pos = adp
    return len([ 1 for word in doc if word.pos_ == 'VERB' for child in word.children  if child.pos_ == 'ADP'])

#count the number of subordinate conjunctions in the text "if, because, otrherwise and since"
def count_Subordinating_conjunctions(doc):
    count = 0
    for word in doc:
        #if the word pos is SCONJ "subordinating conjunction"
        if word.pos_ == 'SCONJ':
            # count the word
            count += 1

            count += 1
    return count

# one bit for the location of the conjunction
    # becuase of .. i did .. -> 0
    # i did .. because of .. -> 1

# 2 bits for the synonym of the conjunction
    # because -> 00
    # for -> 01
    # since -> 10
    # in order -> 11

#calculate the number of abbreviations from spacy (not working)
def count_Abbreviation(txt, abbrv):

    # street -> st.
    # doctor -> dr.
    counter = 0
    # count the number of abbreviations in the text either the full word or the short form
    for i in abbrv:

        counter = counter + txt.count(" " + i) + txt.count(" "+abbrv[i])
    return counter

def count_Pre_Proper_Noun(doc):
    nnp = False
    prp = False

    for word in doc:
        # check if we found a proper noun
        if word.tag_ == 'NNP':
            nnp = True
        # check if we found a pronoun
        elif word.tag_ == 'PRP':
            prp = True
        # if the sentence contain both proper noun and pronoun return 1
        if nnp and prp:
            return 1

    return 0


n = [False, False] + [True] * (1000000 - 1)
primes = []

for i in range(2, 1000001):
    if n[i]:
        primes.append(i)
        for j in range(i * 2, 1000001, i):
            n[j] = False

tc = 1
while True:
    tc = int(input())
    if tc == 0:
        break
    for p in range(1, len(primes)):
        if tc - primes[p] in primes:
            print(tc, '=', primes[p], '+', tc - primes[p])
            break