from typing import Optional, Dict, Set

def solve_single(letters: str, result: Dict[str, int],
                 base: int, summed: int, no_zero: Set[str]) -> Optional[bool]:

    if len(letters) == 0 and summed == 0:
        return True

    elif len(letters) == 0:
        return None

    letter = letters[0]

    if letter == '=':
        r = result.get(letters[1])

        if r is not None:
            if r == summed % base and not (r == 0 and letters[1] in no_zero):
                return solve_single(letters[2:], result, base,
                                    0 + summed // base, no_zero)
            elif r != summed % base:
                return None

        else:
            if summed % base in result.values() or \
                   (summed % base == 0 and letters[1] in no_zero):
                return None
            else:
                result[letters[1]] = summed % base
                if solve_single(letters[2:], result, base,
                                0 + summed // base, no_zero):
                    return True

                result.pop(letters[1])
                return None

    if result.get(letter) is not None:
        summed += result[letter]
        letter = letters[0]

        if solve_single(letters[1:], result, base, summed, no_zero):
            return True
    else:

        for num in range(base):
            if num == 0 and letter in no_zero:
                continue

            if num in result.values():
                continue

            result[letter] = num

            if solve_single(letters[1:], result, base, summed + num, no_zero):
                return True

            result.pop(letter)

    return None

def solve(equation: str, base: int) -> Optional[Dict[str, int]]:

    result: Dict[str, int] = {}

    left_side = equation.split(" = ")[0].split(" + ")
    right_side = equation.split(" = ")[1]

    no_zero = set([word[0] for word in left_side]) | set([right_side[0]])
    equation = ""

    for i in range(len(right_side)):
        for word in left_side:

            if i < len(word):
                equation += (word[(-i - 1) % len(word)])

        equation += "=" + right_side[-i - 1]

    solve_single(equation, result, base, 0, no_zero)
    return result if result else None

def main() -> None:

    assert solve("SEND + MORE = MONEY", 10) \
        == {'S': 9, 'E': 5, 'N': 6, 'D': 7, 'M': 1, 'O': 0, 'R': 8, 'Y': 2}

    for base in range(2, 27):
        result = solve("XY + XY = YX", base)

        if base == 2 or base % 3 != 2:
            assert result is None
        else:
            x = base // 3
            y = 2 * x + 1
            assert result == {'X': x, 'Y': y}

if __name__ == '__main__':
    main()


## by nwx

class IPError(Exception):
	pass

def dotted_to_decimal(ipaddr):
	if not isinstance(ipaddr,str):
		raise IPError('dotted IP addresses must be strings')
	try:
		octets = [int(i) for i in ipaddr.split('.')]
	except:
		raise IPError('octets must be numbers')
	for i in octets:
		if i > 255 or i < 0:
			raise IPError('octets must be between 0 and 255, inclusive')
	if len(octets) != 4:
		raise IPError('IP addresses must have 4 octets')
	number = octets[3] + octets[2]*256 + octets[1]*65536 + octets[0]*16777216
	return number

def decimal_to_dotted(ipnum):
	if not isinstance(ipnum,int):
		raise IPError('IP address numbers must be ints')
	oc3 = ipnum % 256
	ipnum = ipnum/256
	oc2 = ipnum % 256
	ipnum = ipnum/256
	oc1 = ipnum % 256
	ipnum = ipnum/256
	oc0 = ipnum
	return "{}.{}.{}.{}".format(oc0,oc1,oc2,oc3)

def subnet_mask(prefixlen):
	if not isinstance(prefixlen,int) or prefixlen > 32 or prefixlen < 0:
		raise IPError('invalid prefix length')
	return decimal_to_dotted(int('1'*prefixlen + '0'*(32-prefixlen), 2))

def host_mask(prefixlen):
	if not isinstance(prefixlen,int) or prefixlen > 32 or prefixlen < 0:
		raise IPError('invalid prefix length')
	return decimal_to_dotted(int('0'*prefixlen + '1'*(32-prefixlen), 2))

def get_prefixlen(subnetmask):
	pass # have to figure this out later

def and_ip_addresses(ip1,ip2):
	if isinstance(ip1,str):
		ip1 = dotted_to_decimal(ip1)
	if isinstance(ip2,str):
		ip2 = dotted_to_decimal(ip2)
	return decimal_to_dotted(ip1 & ip2)

def or_ip_addresses(ip1,ip2):
	if isinstance(ip1,str):
		ip1 = dotted_to_decimal(ip1)
	if isinstance(ip2,str):
		ip2 = dotted_to_decimal(ip2)
	return decimal_to_dotted(ip1 | ip2)

def network_address(ip,prefixlen):
	return and_ip_addresses(ip,subnet_mask(prefixlen))

def broadcast_address(ip,prefixlen):
	return or_ip_addresses(ip,host_mask(prefixlen))

def is_in_network(network,prefixlen,ip):
	return network_address(network,prefixlen) == network_address(ip,prefixlen)

def num_hosts(prefixlen):
	return 2**(32-prefixlen) - 2

def iterate_ip_network(ip,prefixlen):
	network = network_address(ip,prefixlen)
	for i in range(1,num_hosts(prefixlen)-1):
		yield or_ip_addresses(network,i)

def iterate_ip_mask(mask): ## iterator for CIDR networks: 192.168.0.1/24
	ip,prefixlen = mask.split('/')
	prefixlen = int(prefixlen)
	network = network_address(ip,prefixlen)
	for i in range(1,num_hosts(prefixlen)-1):
		yield or_ip_addresses(network,i)

def iterate_port_mask(mask): ## iterator for simple port lists: 22,45-47,88,100-1000
	for i in mask.split(','):
		if '-' in i: #range
			a = i.split('-')
			for z in range(int(a[0]),int(a[-1])+1):
				yield z
		else:
			yield int(i)


import streamlit as st
import altair as alt
import folium
from streamlit_folium import st_folium
import pandas as pd
from pathlib import Path

alojamiento_csv = Path(__file__).parents[1] / "data/alojamiento.csv"
ocupacion_csv = Path(__file__).parents[1] / "data/ocupacion.csv"
ibera_coord_csv = Path(__file__).parents[1] / "data/ibera coordenadas.csv"
APN_csv = Path(__file__).parents[1] / "data/parques_visitantes.csv"

st.set_page_config(page_title="Datathon 2023", layout="wide", page_icon=":bar_chart:")

@st.cache_data
def read_alojamientos():
    df = pd.read_csv(alojamiento_csv)
    return df

@st.cache_data
def read_ocupacion():
    df = pd.read_csv(ocupacion_csv)
    return df

@st.cache_data
def read_ibera_coord():
    df = pd.read_csv(ibera_coord_csv)
    return df

@st.cache_data
def read_ibera():
    df = pd.read_csv(APN_csv)
    ibera = df[df["name"] == "Iberá"]
    return ibera

alojamiento = read_alojamientos()
ocupacion = read_ocupacion()
ibera_coord = read_ibera_coord()
ibera = read_ibera()

def create_esteros_map(ibera_coord):
    # Coordinates of 5 provinces in Esteros del Ibera, Corrientes
    lat = list(ibera_coord["lat"])
    lon = list(ibera_coord["lon"])
    names = list(ibera_coord["Nombre"])

    # Create a folium map centered around Esteros del Ibera
    esteros_center = (
        -28.32641799784776,
        -57.34674731559198,
    )  # Esteros del Ibera coordinates
    # Create a Streamlit app
    st.markdown("### Esteros del Iberá")

    # Create a map
    m = folium.Map(location=esteros_center, zoom_start=8, tiles="openstreetmap")

    # Add markers for each province
    for i, row in ibera_coord.iterrows():
        folium.Marker(
            location=[float(row["lat"]), float(row["lon"])],
            popup=row["Nombre"],
            icon=folium.Icon(color="blue"),
        ).add_to(m)
    return m

## PAGE FORMAT ##

st.markdown("# Datos Abiertos de Corrientes")
st.write(
    """A continuación, presentaremos un breve análisis sobre alojamientos disponibles, ocupación
      hotelera y turismo en base a datos abiertos proporcionados por el Municpio de Corrientes y la Administración de Parques Nacionales.
        """
)
st.markdown("----")
st.markdown(
    "##### Cantidad de Habitaciones de Alojamientos (Hoteles y para-Hoteles) en la Ciudad de Corrientes"
)

st.line_chart(
    data=alojamiento, x="Fecha", y="Habitaciones Total", use_container_width=True
)

st.write(
    """A simple vista, es evidente que la cantidad de habitaciones en hoteles y establecimientos similares se
    mantuvo relativamente constante hasta el año 2020, momento en el cual se produjo una marcada disminución en
    la cantidad de alojamientos disponibles. Presumimos que este descenso se debe a la crisis desencadenada por la
    pandemia de COVID-19 y su impacto significativo en la industria turística."""
)
st.write(
    """También se observa que, a partir de la mitad del año 2020, la cantidad de habitaciones disponibles ha ido en aumento,
      **aunque aún no ha logrado recuperar el nivel previo a la crisis del COVID-19**. Esto podría representar una
     oportunidad del sector."""
)

###
st.markdown("----")

st.markdown("##### Cantidad de Habitaciones Disponibles por Tipo de Alojamiento")
st.line_chart(
    data=alojamiento,
    x="Fecha",
    y=["Habitaciones Hoteles", "Habitaciones Para-Hoteles"],
    use_container_width=True,
)
st.write(
    """
Aunque la crisis derivada de la pandemia de COVID-19 ha tenido un impacto significativo en el sector del hospedaje,
al analizarlo detenidamente, resulta evidente que la industria hotelera ha sido la más perjudicada. Esto lo atribuimos,
en gran medida, a que los costos asociados con la operación de alojamientos alternativos, como pequeños establecimientos
 o alquileres de corta duración, son considerablemente menores en comparación con los gastos de mantener un hotel en funcionamiento.
 Esto permite a los establecimientos alternativos resistir las épocas de crisis con mayor resiliencia que los grandes hoteles."""
)

###
st.markdown("----")

percentage_hoteles = sum(
    alojamiento["Habitaciones Hoteles"] / alojamiento["Habitaciones Total"]
) / len(alojamiento)
percentage_para_hoteles = sum(
    alojamiento["Habitaciones Para-Hoteles"] / alojamiento["Habitaciones Total"]
) / len(alojamiento)

alojamiento_pie = pd.DataFrame(
    {
        "Tipo de Alojamiento": ["Hoteles", "Otros"],
        "Porcentaje": [percentage_hoteles, percentage_para_hoteles],
    }
)
tipo_alojamiento = (
    alt.Chart(alojamiento_pie)
    .mark_arc()
    .encode(theta="Porcentaje", color="Tipo de Alojamiento")
)
st.markdown(
    "##### Porcentaje de Habitaciones de Cada Tipo de Alojamiento Sobre Total de Habitaciones Disponibles"
)
col1, col2 = st.columns(2)
with col1:
    st.altair_chart(tipo_alojamiento, use_container_width=True)
with col2:
    st.write(
        """Teniendo en cuenta las fechas correspondientes a los datos analizados, las habitaciones disponibles
        en alojamientos alternativos constituyen, en promedio, el 10% del total de habitaciones disponibles en Corrientes.
        Este dato pone de manifiesto la notable dependencia del turismo en Corrientes respecto a la industria hotelera,
        y la reciente disminución en estas cifras podría presentar una oportunidad para que los alojamientos alternativos
        ganen presencia en el mercado
        """
    )
    st.write(
        """Sin embargo, el lento crecimiento de los alojamientos alternativos durante los años también nos brinda una señal sobre
        la demanda del mercado turístico de corrientes: quizás exista alguna razón por la cuál no han tenido un mayor éxito.
        """
    )

###
st.markdown("----")

st.markdown(
    "##### Porcentaje de Ocupacion de Hoteles en la Ciudad de Corrientes Durante el Año"
)

ciclo_ocupacion = (
    alt.Chart(ocupacion)
    .mark_line()
    .encode(x="Mes", y="Porcentaje Ocupacion", color="Año:N")
)
st.altair_chart(ciclo_ocupacion, use_container_width=True)
st.write(
    """Basándonos en el gráfico de ciclos, como era previsible, se evidencia una estacionalidad
    en la ocupación hotelera en la ciudad de Corrientes. Esta tiende a aumentar durante el verano
    (enero y febrero), disminuir al punto más bajo en los meses subsiguientes (de marzo a junio),
    experimentar un notorio incremento durante el período de vacaciones de invierno (junio y julio),
    para luego mantenerse en un nivel constante, generalmente por debajo del 50% de ocupación.
        """
)

###
st.markdown("----")
st.markdown(
    "##### Estacia Promedio Mensual en Hoteles de la Ciudad de Corrientes (2016-2022)"
)
st.bar_chart(data=ocupacion, x="Fecha", y="Estadia Promedio", use_container_width=True)
st.write(
    """También se puede notar que la duración media de la estancia en hoteles de la Ciudad de Corrientes
     se mantiene en torno a los dos días. Con un promedio total de 1.84 días de estancia, consideramos que
    este factor influye considerablemente en la preferencia de los turistas por los hoteles en Corrientes
    frente a otros tipos de alojamiento. Los alojamientos alternativos suelen ser más atractivos para viajeros
    con estancias prolongadas, pero dado que Corrientes es principalmente un destino de tránsito, los servicios
    ofrecidos por los hoteles parecen ser la elección ideal.
    """
)

###
st.markdown("----")

st.write(
    """No obstante, en la provincia de Corrientes contamos con un atractivo turístico internacional
    de gran envergadura: el Parque Nacional Iberá. A continuación, se destacan las principales ciudades
    cercanas al parque que consideramos representan una oportunidad dada su proximidad a algunos de los portales de acceso y su desarrollo urbano,
    y presentamos un breve análisis acerca de los visitantes al parque.
    """
)

ibera_map = create_esteros_map(ibera_coord)
st_map = st_folium(ibera_map, width=700, height=450)

###
st.markdown("----")

st.markdown("##### Visitantes del Parque por Tipo de Residencia desde 2017-2020")

residentes = ibera[ibera["categoria"] == "Residentes"]["visitantes"].sum()
extranjeros = ibera[ibera["categoria"] == "Extranjeros"]["visitantes"].sum()
visitante_pie = pd.DataFrame(
    {
        "Visitante": ["Residente", "Extranjero"],
        "Cantidad": [residentes, extranjeros],
    }
)
tipo_visitante = (
    alt.Chart(visitante_pie).mark_arc().encode(theta="Cantidad:Q", color="Visitante")
)

st.altair_chart(tipo_visitante, use_container_width=True)
st.write(
    """Podemos observar que el total de visitantes al Parque Nacional Iberá desde el año 2017 hasta el año 2020 fue de 31854,
    y el 12% (3884) de estos visitantes provienen del extranjero.
    """
)

###
st.markdown("----")

st.markdown("##### Total de Visitantes del Parque por Año  (2017-2020)")

residentes_por_ano = ibera.groupby("ano")["visitantes"].sum()
st.bar_chart(data=residentes_por_ano, use_container_width=True)

st.write(
    """La cantidad de visitantes iba en aumento hasta el 2020, cuándo la crisis del COVID golpeó más duramente. Sería interesante poder
    analizar los datos de los años posteriores para ver si el crecimiento sigue vigente.
    """
)

st.markdown("##### Total de Visitantes del Parque Agrupados por Mes Durante 2017-2020")

residentes_por_mes = ibera.groupby("mes")["visitantes"].sum()
st.bar_chart(data=residentes_por_mes, use_container_width=True)

st.write(
    """Se observa que la cantidad de visitantes al Parque Nacional tiene un idéntico patrón de estacionalidad que el porcentaje de ocupación
    hotelera de la ciudad de Corrientes.
    """
)


import os
import json
import sys
import datetime
import time
from NucleiDataset import NucleiDataset
from seglib import SEG_ALGS
import segml
import segutils
import numpy as np
import pandas as pd

if __name__ == "__main__":

    timestamp = datetime.datetime.fromtimestamp(time.time()).strftime("%Y-%m-%d-%H-%M-%S")

    config_filename = sys.argv[1]
    with open(config_filename) as json_config_file:
        config = json.load(json_config_file)

    paths_config = config.get("paths")
    data_path = paths_config.get("input_path")
    output_path = paths_config.get("output_path")

    actions_config = config.get("actions")
    explore = actions_config.get("explore")
    preprocess = actions_config.get("preprocess")
    evaluate = actions_config.get("evaluate")
    test = actions_config.get("test")
    visualize = actions_config.get("visualize")

    action = "collecting images details"
    start_time = segutils.start_action(action)
    imgs_details = segutils.collect_imgs_details(data_path)
    segutils.complete_action(action, start_time)

    action = "creating train dataset"
    start_time = segutils.start_action(action)
    train_labels_file = os.path.join(data_path, 'train_labels.csv')
    train_dataset = NucleiDataset('train', imgs_df=imgs_details,
                                  labels_file=train_labels_file)
    print("set size: {}".format(len(train_dataset)))
    segutils.complete_action(action, start_time)

    if explore:
        for i in xrange(5):
            sample = train_dataset[i]
            for cls in xrange(len(SEG_ALGS)):
                segutils.plot_sample_segmentation(sample, cls, SEG_ALGS)
        sys.exit(0)

    labels = {"ImageId":[], "Class":[], "Name":[], "IoU":[]}
    if preprocess:
        action = "assigning best segmentation class"
        start_time = segutils.start_action(action)
        best_segs = segml.assign_best_seg(train_dataset, SEG_ALGS)
        segutils.complete_action(action, start_time)

        n_imgs_to_plot = 5
        i = 0
        n_seg_candidates = len(SEG_ALGS)
        sum_seg_ious = np.zeros(n_seg_candidates)
        n_seg_chosen = np.zeros(n_seg_candidates)
        for img_id, best_seg in best_segs.items():
            cls = best_seg.get('cls')
            iou = best_seg.get('iou')
            sum_seg_ious[cls] = sum_seg_ious[cls] + iou
            n_seg_chosen[cls] = n_seg_chosen[cls] + 1
            labels.get('ImageId').append(img_id)
            labels.get('Class').append(cls)
            labels.get('Name').append(str(SEG_ALGS.get(cls)))
            labels.get('IoU').append(iou)
            if visualize and i < n_imgs_to_plot:
                sample = train_dataset[i]
                segutils.plot_sample_segmentation(sample, cls, SEG_ALGS, iou)
            i = i+1

        print("IOUs for segmentation algorithms (by class): {}".format(sum_seg_ious/n_seg_chosen))
        print("mean IoU for train set: {}".format(sum_seg_ious.sum()/(i-1)))
        labels = pd.DataFrame.from_dict(labels)
        labels.to_csv(output_path+"train_seg_assignment_"+timestamp+".csv", index=False)
    else:
        seg_cls_labels_file = paths_config.get("seg_cls_labels_file")
        labels = pd.DataFrame.from_csv(seg_cls_labels_file)

    action = "training classifier"
    start_time = segutils.start_action(action)
    model = segml.train_seg_classifier(train_dataset, best_segs)
    segutils.complete_action(action, start_time)

    if evaluate:
        action = "creating validation  dataset"
        start_time = segutils.start_action(action)
        validation_labels_file = os.path.join(data_path, 'validation_labels.csv')
        validation_dataset = NucleiDataset('validation', imgs_df=imgs_details,
                                           labels_file=validation_labels_file)
        print("set size: {}".format(len(validation_dataset)))
        segutils.complete_action(action, start_time)

        action = "making predictions for the validation set"
        start_time = segutils.start_action(action)
        predictions, examples = segml.test(model, validation_dataset, SEG_ALGS)
        segutils.complete_action(action, start_time)

        action = "evaluating predictions"
        start_time = segutils.start_action(action)
        mean_avg_precision_iou = segml.evaluate(predictions, validation_dataset, examples=examples)
        print("IoU for validation dataset: {}".format(mean_avg_precision_iou))
        segutils.complete_action(action, start_time)
        if visualize:
            # visually evaluate a few images by comparing images and masks
            segutils.plot_predicted_masks(examples, (22, 27))

    if test:

        test_dataset = NucleiDataset('test', imgs_df=imgs_details)

        action = "making predictions for the test set"
        start_time = segutils.start_action(action)
        predictions, examples = segml.test(model, test_dataset, SEG_ALGS)
        segutils.complete_action(action, start_time)
        # visually evaluate a few images by comparing images and masks
        if visualize:
            segutils.plot_predicted_masks(examples, (7, 12), plot_true_mask=False)

        action = "writing the predictions to submission format"
        start_time = segutils.start_action(action)
        submission_df = segutils.to_submission_df(predictions)
        submission_filename = output_path + "model_predictions_" + timestamp + ".csv"
        submission_df.to_csv(submission_filename, columns=('ImageId','EncodedPixels'), index=False)
        print("predictions on tess set written to: {}".format(submission_filename))
        segutils.complete_action(action, start_time)


import unittest
import tempfile
import os
import json
from mock import patch
from ..utilities import DataStoreUtilities, JsonParser, FileNotFound, NonParsableFile, DeviceUtilities

class TestUtilities(unittest.TestCase):
    def setUp(self):
        pass

    def test_tail_file(self):
        temp_file = tempfile.NamedTemporaryFile("w", delete=False)
        temp_file.write("""aligator;;
bat;;
cat;;
dog;;
elephant;;
flamingo;;
gorilla;;""")
        temp_file.close()
        result = DataStoreUtilities.tail_file(temp_file.name, 100)
        self.assertEqual(7, len(result))

        result = DataStoreUtilities.tail_file(temp_file.name, 5)
        self.assertEqual(5, len(result))

        result = DataStoreUtilities.tail_file(temp_file.name, 0)
        self.assertEqual(0, len(result))

        def only_dogs(line):
            print(line)
            return str(line) == "dog" or str(line) == "Dog"

        result = DataStoreUtilities.tail_file(temp_file.name, 100, None, only_dogs)
        self.assertEqual(1, len(result))

        def change_to_capitalized(line):
            return line.capitalize()

        result = DataStoreUtilities.tail_file(temp_file.name, 100, change_to_capitalized, only_dogs)
        self.assertEqual(1, len(result))

        os.remove(temp_file.name)

    def test_json_read_file(self):
        temp_file = tempfile.NamedTemporaryFile("w", delete=False)
        temp_file.write("""{}""")
        temp_file.close()
        result = JsonParser.read_file(temp_file.name)
        self.assertEqual(result, {})
        os.remove(temp_file.name)

        with self.assertRaises(FileNotFound):
            temp_file = tempfile.NamedTemporaryFile("w", delete=True)
            temp_file.close()
            JsonParser.read_file(temp_file.name)

        temp_file = tempfile.NamedTemporaryFile("w", delete=False)
        temp_file.write("""foo""")
        temp_file.close()
        with self.assertRaises(NonParsableFile):
            JsonParser.read_file(temp_file.name)
        os.remove(temp_file.name)

    def test_json_not_parsable(self):
        temp_file = tempfile.NamedTemporaryFile("w", delete=False)
        temp_file.write("")
        temp_file.close()
        try:
            result = JsonParser.read_file(temp_file.name)
            self.fail()
        except NonParsableFile as npf:
            self.assertEqual(str(npf), "'File {} cannot be parsed.'".format(temp_file.name))

        os.remove(temp_file.name)

    @patch.object(json, "dumps", side_effect=ValueError())
    def test_json_not_parseable2(self, mock_json):
        temp_file = tempfile.NamedTemporaryFile("w", delete=False)
        temp_file.write("")
        temp_file.close()
        try:
            JsonParser.write_file(temp_file.name, "")
            self.fail()
        except NonParsableFile:
            pass

        os.remove(temp_file.name)

    def test_json_write(self):
        temp_file = tempfile.NamedTemporaryFile("w", delete=False)
        temp_file.close()
        JsonParser.write_file(temp_file.name, "{}")
        os.remove(temp_file.name)

        temp_file = tempfile.NamedTemporaryFile("w", delete=False)
        temp_file.close()
        # with self.assertRaises(NonParsableFile):
        #     JsonParser.write_file(temp_file.name, "{[")
        os.remove(temp_file.name)

        with self.assertRaises(FileNotFound):
            JsonParser.write_file('/root/not-allowed', "")

        try:
            JsonParser.write_file('/root/not-allowed', "")
        except FileNotFound as fnf:
            self.assertEqual(str(fnf), "'File /root/not-allowed not found.'")

    def test_json_get_string(self):
        result = JsonParser.get_file_content_string({"one": 1, "two": "two"})
        self.assertEqual('{\n  "one": 1,\n  "two": "two"\n}', result)


import argparse
import os
import json

import numpy as np
from scipy.spatial.transform import Rotation as R

def parse_args():
    parser = argparse.ArgumentParser(description="Create camera path from transforms.json")

    parser.add_argument("--scene", "--training_data", default="", help="The scene to load. Can be the scene's name or a full path to the training data.")

    args = parser.parse_args()
    return args

if __name__ == "__main__":
    args = parse_args()
    path = os.getcwd().replace("\\","/")
    path = os.path.join(path, args.scene)
    path = path.replace("\\","/")
    # path = path.replace("/","\\")

    def nerf_to_ngp(xf):
        mat = np.copy(xf)
        mat = mat[:-1,:]
        mat[:,1] *= -1 # flip axis
        mat[:,2] *= -1
        mat[:,3] *= 0.33 #scale
        mat[:,3] += [0.5, 0.5, 0.5] #offset

        mat = mat[[1,2,0], :] # swap axis

        rm = R.from_matrix(mat[:,:3])

        # quaternion (x, y, z, w) and translation
        #  + 0.025
        return rm.as_quat(), mat[:,3]

    def smooth_camera_path(path_to_transforms, ):
        out = {"path":[], "time":1.0}
        with open(path_to_transforms + '/transforms.json') as f:
            data = json.load(f)

        n_frames = len(data['frames'])
        # fov = 85.0
        fov = data["camera_angle_y"] * 180 / np.pi
        print(fov)
        xforms = {}
        for i in range(n_frames):
            # file = int(data['frames'][i]['file_path'].split('/')[-1][:-4])
            file = int(data['frames'][i]['file_path'].split('/')[-1][-7:-4])
            xform = data['frames'][i]['transform_matrix']
            xforms[file] = xform

        xforms = dict(sorted(xforms.items()))
        indexes = list(xforms.keys())

        # linearly take n (4) transformation from transforms.json
        for ind in np.linspace(0, n_frames - 1, 4, endpoint=True, dtype=int):

            q, t = nerf_to_ngp(np.array(xforms[indexes[ind]]))

            out['path'].append({
                "R": list(q),
                "T": list(t),
                "aperture_size":0.0,
                "fov":fov,
                "glow_mode":0,
                "glow_y_cutoff":0.0,
                "scale":1.25,
                "slice":0.0
            })

        with open(path_to_transforms+'/base_cam_script.json', "w") as outfile:
            json.dump(out, outfile, indent=2)

    smooth_camera_path(path)


import numpy as np
import functions as fn
import random
from tqdm import tqdm

def setting_inputs():
    npri = 100
    nst = 20
    kp2 = 50
    ncool = 200
    kp = 50
    f = 1.4 #minimum of the potential
    n = 800 #lattice points
    a = 0.05 #lattice spacing
    neq = 100 #number of equilibration sweeps
    nmc = 100 #number of MonteCarlo sweeps
    dx = 0.5 #width of updates
    n_p = 20 #number max of points in the correlation functions
    nc = 5 #number of correlator measurements in a configuration
    kp = 50 #number of sweeps between writeout of complete configuration
    mode = 1 # ih=0: cold start, x_i=-f; ih=1: hot start, x_i=random
    seed = 597
    return f, n, a, neq, nmc, dx, n_p, nc, kp, mode, seed, npri, nst, kp2, ncool

f, n, a, neq, nmc, dx, n_p, nc, kp, mode, seed, npri, nst, kp2, ncool = setting_inputs()
random.seed(seed)
#----------- setting constants--------------------------------------------------|
pi  = np.pi
s0  = 4.0/3.0*f**3     #instanton action
de  = 8*np.sqrt(2.0/pi)*f**2.5*np.exp(-s0)
de2 = de*(1.0-71.0/72.0/s0)
tmax = n*a
#------------output files-------------------------------------------------------|
config1 = open('config1.dat', 'w')
config1.write('configuration, S_tot, T_tot, V_tot\n')

config2 = open('config2.dat', 'w')
config2.write('i*a, x[i]\n')

config_cool = open('config_cool.dat', 'w')
config_cool.write('i*a\t xs[i]\n')

averages = open('averages.dat', 'w')
averages.write('\tStot_av, S_tot_err, V_av, Verr,T_av, T_err, TV_av, TV_err\n')

correlations = open('correlations_qm.dat', 'w')
correlations.write("x correlation function\n")

correlations_cool = open('correlations_cool.dat', 'w')
correlations_cool.write("x correlation function(cool)\n ip*a, xcool_av[ip], xcool_er[ip], dx, dxe\n")

correlations2 = open('correlations2_qm.dat', 'w')
correlations2.write("x2 correlation function\n")

correlations2_cool = open('correlations2_cool.dat', 'w')
correlations2_cool.write("x2 correlation function(cool)\n ip*a, xcool_av[ip], xcool_er[ip], dx, dxe\n")

correlations3 = open('correlations3_qm.dat', 'w')
correlations3.write("x3 correlation function\n")

correlations3_cool = open('correlations3_cool.dat', 'w')
correlations3_cool.write("x3 correlation function (cool)\n ip*a, x3cool_av[ip], x3cool_er[ip], dx, dxe\n")

wavefunction = open('wavefunction_qm.dat', 'w')
wavefunction.write('xx, histo_x[i]/xnorm\n')

instdensity = open('instdensity.dat', 'w')
instdensity.write('number of instantons\n ic, nin_av[ic], nin_er[ic], de*tmax, de2*tmax\n')

coolingsweeps = open('coolingsweeps.dat', 'w')
coolingsweeps.write(' action vs cooling sweeps\n ic, scool_av[ic], scool_er[ic], sin\n')

inst_action = open('inst_action.dat', 'w')
inst_action.write('Action per instanton, S0 = ' + str(4.0/3.0*f**3) +'\n ic, si_av, si_er, s0\n' )

histz = open('hist_z.dat', 'w')
histz.write('xx iz[i]')
#-----histograms parameters-----------------------------------------|
nxhist = 50
xhist_min = -2.0*f
stxhist   = -2*xhist_min/nxhist
nzhist = 40
stzhist = 4.01 / float(nzhist)
#-------counter variables-------------------------------------------|
nconf = 0 #it counts the number of randomly generated configurations
ncor = 0 #it counts the number of correlations taken
ncoolconf = 0
ncoolcor  = 0
#-------variable definitions----------------------------------------|
S_sum = 0.0
S2_sum = 0.0
T_sum = 0.0
T2_sum = 0.0
V_sum = 0.0
V2_sum = 0.0
TV_sum = 0.0
TV2_sum = 0.0
x_sum = 0
x2_sum = 0
x4_sum = 0
x8_sum = 0
#-----Array defnitions-----------------------------------------------|
x = np.zeros(n)
xcor_sum   = np.zeros(n_p)
xcor2_sum  = np.zeros(n_p)
x2cor_sum  = np.zeros(n_p)
x2cor2_sum = np.zeros(n_p)
x3cor_sum  = np.zeros(n_p)
x3cor2_sum = np.zeros(n_p)
xcor_av    = np.zeros(n_p)
x2cor_av   = np.zeros(n_p)
x3cor_av   = np.zeros(n_p)
xcor_er    = np.zeros(n_p)
x2cor_er   = np.zeros(n_p)
x3cor_er   = np.zeros(n_p)
histo_x    = np.zeros(nxhist)
ipa        = np.zeros(nc)
xs         = np.zeros(n+1)
z = np.zeros(n)
nin_sum    = np.zeros(ncool+1)
nin2_sum   = np.zeros(ncool+1)
scool_sum  = np.zeros(ncool+1)
scool2_sum = np.zeros(ncool+1)
ix         = np.zeros(nxhist)
iz         = np.zeros(nzhist)
xi         = np.zeros(n)
xa         = np.zeros(n)
ix          = np.zeros(nxhist)
iz          = np.zeros(nzhist)
nin_av      = np.zeros(ncool+1)
nin_er      = np.zeros(ncool+1)
scool_av    = np.zeros(ncool+1)
scool_er    = np.zeros(ncool+1)
xcool_sum  = np.zeros(n_p)
xcool2_sum = np.zeros(n_p)
xcool_av   = np.zeros(n_p)
xcool_er   = np.zeros(n_p)
x2cool_sum    = np.zeros(n_p)
x2cool2_sum   = np.zeros(n_p)
x2cool_av     = np.zeros(n_p)
x2cool_er     = np.zeros(n_p)
x2cool_sub_av = np.zeros(n_p)
x2cool_sub_er = np.zeros(n_p)
x3cool_sum  = np.zeros(n_p)
x3cool2_sum = np.zeros(n_p)
x3cool_av   = np.zeros(n_p)
x3cool_er   = np.zeros(n_p)
#starting configuration-----------------------------------------|
x = fn.periodic_starting_conf(x, n, f, mode)
#---------montecarlo generations--------------------------------|
for i in tqdm(range(nmc)):
    nconf += 1
    if i == neq:       #when we reach equilibrium all is set to zero
        nconf = 0
        ncor = 0
        ncoolconf = 0
        ncoolcor = 0
        S_sum = 0
        S2_sum = 0
        V_sum = 0 #Potential
        V2_sum = 0
        T_sum = 0 #Kinetic
        T2_sum = 0
        Tvir_sum = 0
        T2vir_sum = 0
        x_sum = 0
        x2_sum = 0
        x4_sum = 0
        x8_sum = 0
        xcor_sum  = np.zeros(n_p)
        x2cor_sum = np.zeros(n_p)
        x3cor_sum = np.zeros(n_p)
        histo_x   = np.zeros(nxhist)

        xcool_sum  = np.zeros(n_p)
        xcool2_sum = np.zeros(n_p)
        xcool_av   = np.zeros(n_p)
        xcool_er   = np.zeros(n_p)
        x2cool_sum    = np.zeros(n_p)
        x2cool2_sum   = np.zeros(n_p)
        x2cool_av     = np.zeros(n_p)
        x2cool_er     = np.zeros(n_p)
        x2cool_sub_av = np.zeros(n_p)
        x2cool_sub_er = np.zeros(n_p)
        x3cool_sum  = np.zeros(n_p)
        x3cool2_sum = np.zeros(n_p)
        x3cool_av   = np.zeros(n_p)
        x3cool_er   = np.zeros(n_p)
        nin_sum     = np.zeros(ncool+1)
        nin2_sum    = np.zeros(ncool+1)
        ix          = np.zeros(nxhist)
        iz          = np.zeros(nzhist)
        nin_av      = np.zeros(ncool+1)
        nin_er      = np.zeros(ncool+1)
        scool_av    = np.zeros(ncool+1)
        scool_er    = np.zeros(ncool+1)
    x = fn.update_periodic(x,n,a,f, dx)  #metropolis algorithm implementation with periodic boundary conditions
    xs = x
    #computation of action, kinetic energy, potential and virial for the current configuration
    S, V, T, TV = fn.compute_energy(x, n, a, f)
    S_sum += S
    S2_sum += S**2
    T_sum += T
    T2_sum += T**2
    V_sum += V
    V2_sum += V**2
    TV_sum += TV
    TV2_sum += TV**2
    for ic in range(nc):
        ncor += 1
        xcor = fn.correlations_functions(x, n, n_p)
        for ip in range(n_p):
            xcor_sum[ip]   += xcor[ip]
            xcor2_sum[ip]  += xcor[ip]**2
            x2cor_sum[ip]  += xcor[ip]**2
            x2cor2_sum[ip] += (xcor[ip]**2)**2
            x3cor_sum[ip]  += xcor[ip]**3
            x3cor2_sum[ip] += (xcor[ip]**3)**2
    for k in range(n):
         x_sum  += x[k]
         x2_sum += x[k]**2
         x4_sum += x[k]**4
         x8_sum += x[k]**8
    fn.histogramarray(x, n,  xhist_min, stxhist, nxhist, histo_x)
    #output configuration
    if i % kp == 0:
        config1.write("{}\t{:.4f}\t{:.4f}\t{:.4f}\n".format(i, S, T, V))
        for j in range(n):
            config2.write("{:.4f}\t{:.4f}\n".format(j*a, x[j]))
        config2.write("------------------\n")
    #cooling sweeps
    if i % kp2 == 0:
        ncoolconf += 1
        ni, na     = fn.instantons(f, a, n, xs, xi, xa, z)
        S, V, T, TV = fn.compute_energy(xs, n, a, f)
        nin = ni + na
        nin_sum[0]   += nin
        nin2_sum[0]  += nin**2
        scool_sum[0] += S
        scool2_sum[0]+= S**2
        for icool in range(1,ncool+1):
           nhit2 = 10
           delxp= 0.1*dx
           for i in range(nhit2):
               xs = fn.cooling_update(xs, n, a, f, delxp)
           ni, na     = fn.instantons(f, a, n, xs, xi, xa, z)
           S, V, T, TV = fn.compute_energy(xs, n, a, f)
           nin = ni + na
           nin_sum[0]   += nin
           nin2_sum[0]  += nin**2
           scool_sum[0] += S
           scool2_sum[0]+= S**2
        #--------------cooled configuration: instanton distribution  -------------|
        fn.instanton_distribution(z, nin, tmax, stzhist, nzhist, iz)
        #--------------cooled correlator------------------------------------------|
        for ic in range(nc):
           ncoolcor += 1
           xcor = fn.correlations_functions(xs, n, n_p)
           for ip in range(n_p):
               xcool_sum[ip]   += xcor[ip]
               xcool2_sum[ip]  += xcor[ip]**2
               x2cool_sum[ip]  += xcor[ip]**2
               x2cool2_sum[ip] += (xcor[ip]**2)**2
               x3cool_sum[ip]  += xcor[ip]**3
               x3cool2_sum[ip] += (xcor[ip]**3)**2
       #----------------output cooled configurations------------------------------|
        for j in range(n):
               config_cool.write("{:.4f}\t{:.4f}\n".format(j*a, xs[j]))
        config_cool.write("------------------\n")
#----------Averages and error computations----------------------|
stot_av,stot_err = fn.dispersion(nconf,S_sum,S2_sum)
vtot_av,vtot_err = fn.dispersion(nconf,V_sum,V2_sum)
ttot_av,ttot_err = fn.dispersion(nconf,T_sum,T2_sum)
tvir_av,tvir_err = fn.dispersion(nconf,TV_sum,TV2_sum)
x_av,x_err       = fn.dispersion(nconf*n,x_sum,x2_sum)
x2_av,x2_err     = fn.dispersion(nconf*n,x2_sum,x4_sum)
x4_av,x4_err     = fn.dispersion(nconf*n,x4_sum,x8_sum)
for ip in range(n_p):
    xcor_av[ip],xcor_er[ip]   = fn.dispersion(ncor,xcor_sum[ip],xcor2_sum[ip])
    x2cor_av[ip],x2cor_er[ip] = fn.dispersion(ncor,x2cor_sum[ip],x2cor2_sum[ip])
    x3cor_av[ip],x3cor_er[ip] = fn.dispersion(ncor,x3cor_sum[ip],x3cor2_sum[ip])
    xcool_av[ip] , xcool_er[ip]  = fn.dispersion(ncoolcor, xcool_sum[ip] , xcool2_sum[ip])
    x2cool_av[ip], x2cool_er[ip] = fn.dispersion(ncoolcor, x2cool_sum[ip], x2cool2_sum[ip])
    x3cool_av[ip], x3cool_er[ip] = fn.dispersion(ncoolcor, x3cool_sum[ip], x3cool2_sum[ip])
#   instanton density, cooled action
#------------------------------------------------------------------------------
for ic in range(ncool + 1):
    nin_av[ic], nin_er[ic] = fn.dispersion(ncoolconf, nin_sum[ic]  , nin2_sum[ic])
    scool_av[ic], scool_er[ic] = fn.dispersion(ncoolconf, scool_sum[ic], scool2_sum[ic])

#continuum averages
v_av   = vtot_av/tmax
v_err  = vtot_err/tmax
t_av   = ttot_av/tmax
t_err  = ttot_err/tmax
tv_av  = tvir_av/tmax
tv_err = tvir_err/tmax
e_av   = v_av + tv_av
e_err  = np.sqrt(v_err**2 + tv_err**2)

#output vari
averages.write("\t{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\n".format(stot_av,stot_err, v_av, v_err, t_av,tv_av,tv_err))
averages.write('\t e_av, e_err, x_av, x_err, x2_av,x2_err, x4_av, x4_err\n')
averages.write("\t{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}".format(e_av, e_err, x_av, x_err, x2_av, x2_err, x4_av, x4_err))
#----------log derivatives------------------------------------------------------------|
dx, dxe = fn.log_derivatives(xcor_av, xcor_er, a, n_p)
x2sub_av, x2sub_er = fn.substract(x2cor_av, x2cor_er, n_p) #substracting
dx2, dxe2 = fn.log_derivatives(x2sub_av, x2sub_er, a, n_p)
dx3, dxe3 = fn.log_derivatives(x3cor_av, x3cor_er, a, n_p)

dxc, dxec = fn.log_derivatives(xcool_av, xcool_er, a, n_p)
x2subc_av, x2subc_er = fn.substract(x2cool_av, x2cool_er, n_p) #substracting
dx2c, dxe2c = fn.log_derivatives(x2subc_av, x2subc_er, a, n_p)
dx3c, dxe3c = fn.log_derivatives(x3cool_av, x3cool_er, a, n_p)

#output log derivatives
for ip in range(n_p-1):
    correlations.write("{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\n".format(ip*a, xcor_av[ip], xcor_er[ip], dx[ip], dxe[ip]))
    correlations2.write("{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\n".format(ip*a, x2sub_av[ip], x2sub_er[ip], dx2[ip], dxe2[ip]))
    correlations3.write("{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\n".format(ip*a, x3cor_av[ip], x3cor_er[ip], dx3[ip], dxe3[ip]))
    correlations_cool.write("{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\n".format(ip*a, xcool_av[ip], xcool_er[ip], dxc[ip], dxec[ip]))
    correlations2_cool.write("{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\n".format(ip*a, x2sub_av[ip], x2sub_er[ip], dx2c[ip], dxe2c[ip]))
    correlations3_cool.write("{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\n".format(ip*a, x3cool_av[ip], x3cool_er[ip], dx3c[ip], dxe3c[ip]))

for ic in range(ncool+1):
    instdensity.write("{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\n".format(ic, nin_av[ic], nin_er[ic], de*tmax, de2*tmax))

for ic in range(ncool+1):
    sin = nin_av[ic]*s0
    coolingsweeps.write("{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\n".format(ic, scool_av[ic], scool_er[ic], sin))

for ic in range(ncool+1):
    si_av= scool_av[ic]/nin_av[ic]
    del2 =(scool_er[ic]/scool_av[ic])**2+(nin_er[ic]/nin_av[ic])**2
    si_er= si_av*np.sqrt(del2)
    inst_action.write("{:.4f}\t{:.4f}\t{:.4f}\t{:.4f}\n".format(ic, si_av, si_er, s0))
#----------wave function---------------------------------------------------------------|
position, wave_function = fn.building_wavefunction(histo_x, nxhist, stxhist, xhist_min)
for i in range(nxhist):
    wavefunction.write("{:.4f}\t{:.4f}\n".format(position[i], wave_function[i]))

for i in range(nzhist):
    xx = (i+0.5)*stzhist
    histz.write("{:.4f}\t{:.4f}\n".format(xx, iz[i]))

#closing files
config1.close()
config2.close()
config_cool.close()
averages.close()
correlations.close()
correlations_cool.close()
correlations2.close()
correlations2_cool.close()
correlations3.close()
correlations3_cool.close()
wavefunction.close()
instdensity.close()
coolingsweeps.close()
inst_action.close()
histz.close()


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

import argparse
import itertools
import os
import json
import codecs
import operator
import cPickle
import numpy as np

def parse_args():
    parser = argparse.ArgumentParser(
        description="Translate using existing NMT models",
        usage="translator.py [<args>] [-h | --help]"
    )

    # input files
    # parser.add_argument("--input", type=str, required=True,
    #                     help="Path of input file")

    # input files
    parser.add_argument("--source", type=str, default= None, required=False,
                        help="Path of source corpus length")
    parser.add_argument("--target", type=str, default= None, required=False,
                        help="Path of target corpus length")
    parser.add_argument("--rev_align", type=str, default=None, required=False,
                        help="Path of reverse alignment")
    return parser.parse_args()

def main(args):
    # 读取src tgt的句长
    src_lens = None
    with open(args.source + '.len', "r") as len_file:
        src_lens = [int(line) for line in len_file]

    tgt_lens = None
    with open(args.target + '.len', "r") as len_file:
        tgt_lens = [int(line) for line in len_file]

    align_pos = []
    with open(args.rev_align, "r") as align_file:
        # i = 1
        for i, line in enumerate(align_file):
            # print(i)
            tgt_align_list = line.split()
            sen_align_src = []
            sen_align_tgt = []
            tgt_pos_set = set()
            for word_align in tgt_align_list:
                src_pos, tgt_pos = word_align.split('-')
                sen_align_src.append(src_pos)
                sen_align_tgt.append(tgt_pos)
                tgt_pos_set.add(int(tgt_pos))
            # aligning missed tgt word to eos
            for xpos in range(tgt_lens[i] + 1):  # +3 to add eos--eos
                if xpos not in tgt_pos_set:
                    sen_align_src.append(str(src_lens[i]))  # eos positon
                    sen_align_tgt.append(str(xpos))
            align_pos_mask = ['1'] * len(sen_align_tgt)  # 产生mask以便GPU处理
            align_pos.append([' '.join(sen_align_tgt), ' '.join(sen_align_src), ' '.join(align_pos_mask)])

    mask_file = open(args.target+'.align_mask', "w")
    src_align_pos_file = open(args.source + '.align_pos', "w")
    tgt_align_pos_file = open(args.target + '.align_pos', "w")
    for tgt_align_line, src_align_line, align_mask_line in align_pos:
        tgt_align_pos_file.write(tgt_align_line)
        tgt_align_pos_file.write('\n')
        src_align_pos_file.write(src_align_line)
        src_align_pos_file.write('\n')
        mask_file.write(align_mask_line)
        mask_file.write('\n')
    mask_file.close()
    src_align_pos_file.close()
    tgt_align_pos_file.close()

if __name__ == "__main__":
    main(parse_args())


#
# ts.py
#
# Read the time series file and store the data.

import numpy as np

class readTs:
    """
    readTs -- Holds the time series data.
    """

    def __init__(self, dataDir = 'data', fileName = 'time_series.dat'):
        """
        Reads and stores the data in 'time_series.dat'.

        call signature:

          readTs(dataDir = 'data', filename = 'time_series.dat')

        Keyword arguments:

         *dataDir*:
            Data directory.

         *fileName*:
            Name of the time series file.
        """

        try:
            data = np.loadtxt(dataDir + '/' + fileName)
            fd = open(dataDir + '/' + fileName, "r")
            firstLine = fd.readline()
            fd.close()
        except IOError:
            return -1

        # create keys for dictionary
        keys = firstLine.split()[1:]

        # create attributes and assign data values
        for i in range(len(keys)):
            setattr(self, keys[i], data[:,i])


import os
import sys
import time
import subprocess
from argparse import ArgumentParser
from pipeline_modules import import_assemblies, check_dir, write_job_script

def parse_arguments():
    parser = ArgumentParser(description = "Submit Prokka jobs to the HPC for annotating bacterial genomes")

    # Annotation parameters
    parser.add_argument('--assemblies', '-a', dest = 'assemblies', type = str, required = True, help = "A tab-delimited, header-free file of two columns ID\\tFile_path")
    parser.add_argument('--conda', '-c', dest = 'conda', type = str, required = True, help = "Name of the conda environment for Prokka")
    parser.add_argument('--genus', '-g', dest = 'genus', type = str, required = True, help = "Genus name")
    parser.add_argument('--species', '-sp', dest = 'species', type = str, required = True, help = "Species name")
    parser.add_argument('--strain', '-st', dest = 'strain', type = str, required = False, default = '', help = "Strain name (default: none)")
    parser.add_argument('--proteins', '-p', dest = 'proteins', type = str, required = True, help = "A FASTA or GenBank file to use for first-priority annotation searches")
    parser.add_argument('--mincontiglen', '-l', dest = 'mincontiglen', type = str, required = False, default = '200', help = "Minimum length of contigs to keep (default: 200 bp)")
    parser.add_argument('--rna', '-r', dest = 'rna', action = 'store_true', help = "Enable annotation of tRNA and rRNA")

    # Job parameters
    parser.add_argument('--outdir', '-o', dest = 'outdir', type = str, required = False, default = 'output', help = "Absolute path to the parental output directory")
    parser.add_argument('--ncpus', '-n', dest = 'ncpus', type = str, required = False, default = '8', help = "Number of computational cores to be requested (default: 8)")
    parser.add_argument('--mem', '-m', dest = 'mem', type = str, required = False, default = '16', help = "Memory size (GB) to be requested (default: 16)")
    parser.add_argument('--queue', '-q', dest = 'queue', type = int, required = False, default = 20, help = "Size of each serial job queue (default: 20)")
    parser.add_argument('--scheduler', '-s', dest = 'scheduler', type = str, required = False, default = 'SGE', help = "Job scheduler (SGE/PBS/bash) (default: SGE)")
    parser.add_argument('--debug', '-d', dest = 'debug', action = 'store_true', help = "Only generate job script but do not submit it")
    return parser.parse_args()

def main():
    args = parse_arguments()
    assemblies = import_assemblies(args.assemblies)  # Dictionary {i : path}
    submit = (not args.debug) and (args.scheduler in ['SGE', 'PBS'])
    check_dir(args.outdir)
    queue = list()
    scripts = list()
    k = 0  # Counter of genomes of a queue
    n = 0  # Number of scripts to be written
    for i in assemblies.keys():  # Create and submit scripts of serial jobs based on args.queue
        k += 1
        queue.append(i)
        if k == args.queue:
            n += 1
            scripts.append(write_job_script(create_job_script({genome : assemblies[genome] for genome in queue}, args.conda, args.genus, args.species, args.strain,\
                                                              args.proteins, args.mincontiglen, args.rna, args.ncpus, args.mem, args.outdir, args.scheduler),\
                                            k, n, args.outdir, args.scheduler))  # Append the path of the new script to list 'scripts'
            queue = list()
            k = 0
    if k > 0:  # When there are remaining tasks in the last queue.
        n += 1
        scripts.append(write_job_script(create_job_script({genome : assemblies[genome] for genome in queue}, args.conda, args.genus, args.species, args.strain,\
                                                          args.proteins, args.mincontiglen, args.rna, args.ncpus, args.mem, args.outdir, args.scheduler),\
                                        k, n, args.outdir, args.scheduler))
    if submit:
        for s in scripts:
            print("Submit job script " + s, file = sys.stdout)
            p = subprocess.Popen(['qsub', s])  # Do not use parameters 'shell = True, stdin = None, stdout = None, stderr = None, close_fds = True', or the job will not be submitted successfully.
            time.sleep(1)
    else:
        print("Debugging/bash mode: no job is submitted.", file = sys.stdout)
    return

def create_job_script(assemblies, conda_env, genus, species, strain, proteins, mincontiglen, rna, ncpus, mem, outdir, scheduler):
    outdir = os.path.abspath(outdir)
    rna_conf = '--quiet' if rna else '--norrna --notrna --quiet'
    strain_conf = f'--strain {strain} --force' if strain != '' else '--force'
    if scheduler == 'SGE':
        script = f"""#!/bin/bash
# SGE configurations
#$ -N Prokka
#$ -S /bin/bash
#$ -pe multithread {ncpus}
#$ -l h_vmem={mem}G

# Environmental settings
source $HOME/.bash_profile
source /etc/profile.d/modules.sh
module purge
module load anaconda/5.3.1_python3
conda activate {conda_env}
cd {outdir}

# Prokka jobs"""
    elif scheduler == 'PBS':  # PBS job script
        script = f"""#!/bin/bash
# PBS configurations
#PBS -N Prokka
#PBS -l select=1:ncpus={ncpus}:mem={mem}gb:ompthreads={ncpus}
#PBS -l walltime=24:00:00

# Environmental settings
module load anaconda3/personal
source activate {conda_env}
cd {outdir}

# Prokka jobs"""
    else:
        script = f"""#!/bin/bash\nsource activate {conda_env}"""

    for g in assemblies.keys():
        fasta = assemblies[g]
        subdir = os.path.join(outdir, g)  # Do not need to run check_dir(subdir) as SPAdes creates an output directory if it does not exist.
        script += f"""\nprokka --outdir {subdir} --prefix {g} --locustag {g} --increment 1 --kingdom Bacteria --genus {genus} --species {species} {strain_conf} --gcode 11 --addgenes --proteins {proteins} --cpus {ncpus} --mincontiglen {mincontiglen} {rna_conf} {fasta}"""
    return script

if __name__ == '__main__':
    main()


from django.forms import ModelForm
from bank.system.models import Category

class AdminAddCategoryForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(AdminAddCategoryForm, self).__init__(*args, **kwargs)

        self.fields['name'].widget.attrs.update(
            {'class': 'form-control', 'maxlength': 50}
        )

    class Meta:
        model = Category
        fields = ('name',)


import math

from mvt.utils.parallel_util import get_dist_info
from ..core_module import is_module_wrapper
from ..core_hook import HOOKS, Hook

@HOOKS.register_module()
class EMAHook(Hook):
    r"""Exponential Moving Average Hook.
    Use Exponential Moving Average on all parameters of model in training
    process. All parameters have a ema backup, which update by the formula
    as below. EMAHook takes priority over EvalHook and CheckpointSaverHook.
        .. math::
            \text{Xema_{t+1}} = (1 - \text{momentum}) \times
            \text{Xema_{t}} +  \text{momentum} \times X_t
    Args:
        momentum (float): The momentum used for updating ema parameter.
            Defaults to 0.0002.
        interval (int): Update ema parameter every interval iteration.
            Defaults to 1.
        warm_up (int): During first warm_up steps, we may use smaller momentum
            to update ema parameters more slowly. Defaults to 100.
        resume_from (str): The checkpoint path. Defaults to None.
    """

    def __init__(self, momentum=0.0002, interval=1, warm_up=100, resume_from=None):
        assert isinstance(interval, int) and interval > 0
        self.warm_up = warm_up
        self.interval = interval
        assert momentum > 0 and momentum < 1
        self.momentum = momentum ** interval
        self.checkpoint = resume_from

    def before_run(self, runner):
        """To resume model with it's ema parameters more friendly.
        Register ema parameter as ``named_buffer`` to model
        """
        model = runner.model
        if is_module_wrapper(model):
            model = model.module
        self.param_ema_buffer = {}
        self.model_parameters = dict(model.named_parameters(recurse=True))
        for name, value in self.model_parameters.items():
            # "." is not allowed in module's buffer name
            buffer_name = f"ema_{name.replace('.', '_')}"
            self.param_ema_buffer[name] = buffer_name
            model.register_buffer(buffer_name, value.data.clone())
        self.model_buffers = dict(model.named_buffers(recurse=True))
        if self.checkpoint is not None:
            runner.resume(self.checkpoint)

    def after_train_iter(self, runner):
        """Update ema parameter every self.interval iterations."""
        curr_step = runner.iter
        # We warm up the momentum considering the instability at beginning
        momentum = min(self.momentum, (1 + curr_step) / (self.warm_up + curr_step))
        if curr_step % self.interval != 0:
            return
        for name, parameter in self.model_parameters.items():
            buffer_name = self.param_ema_buffer[name]
            buffer_parameter = self.model_buffers[buffer_name]
            buffer_parameter.mul_(1 - momentum).add_(momentum, parameter.data)

    def after_train_epoch(self, runner):
        """We load parameter values from ema backup to model before the
        EvalHook."""
        self._swap_ema_parameters()

    def before_train_epoch(self, runner):
        """We recover model's parameter from ema backup after last epoch's
        EvalHook."""
        self._swap_ema_parameters()

    def _swap_ema_parameters(self):
        """Swap the parameter of model with parameter in ema_buffer."""
        for name, value in self.model_parameters.items():
            temp = value.data.clone()
            ema_buffer = self.model_buffers[self.param_ema_buffer[name]]
            value.data.copy_(ema_buffer.data)
            ema_buffer.data.copy_(temp)

@HOOKS.register_module()
class StateEMAHook(Hook):
    r"""Exponential Moving Average Hook.

    Use Exponential Moving Average on all parameters of model in training
    process. All parameters have a ema backup, which update by the formula
    as below. EMAHook takes priority over EvalHook and CheckpointSaverHook.

        .. math::

            \text{Xema_{t+1}} = (1 - \text{momentum}) \times
            \text{Xema_{t}} +  \text{momentum} \times X_t

    Args:
        momentum (float): The momentum used for updating ema parameter.
            Defaults to 0.0002.
        interval (int): Update ema parameter every interval iteration.
            Defaults to 1.
        warm_up (int): During first warm_up steps, we may use smaller momentum
            to update ema parameters more slowly. Defaults to 100.
        resume_from (str): The checkpoint path. Defaults to None.
    """

    def __init__(
        self,
        momentum=0.9999,
        interval=None,
        nominal_batch_size=None,
        warm_up=2000,
        resume_from=None,
    ):
        self.interval = 1
        self.nominal_batch_size = None
        self.warm_up = warm_up
        if interval is not None:
            assert isinstance(interval, int) and interval > 0
            self.interval = interval
        elif nominal_batch_size is not None:
            self.interval = None
            self.nominal_batch_size = nominal_batch_size

        assert momentum > 0 and momentum < 1
        self.momentum = momentum
        if resume_from == "":
            self.checkpoint = None
        else:
            self.checkpoint = resume_from

    def before_run(self, runner):
        """To resume model with it's ema parameters more friendly.

        Register ema parameter as ``named_buffer`` to model
        """
        model = runner.model
        if is_module_wrapper(model):
            model = model.module
        self.param_ema_mapping = {}
        for name, value in model.state_dict().items():
            # "." is not allowed in module's buffer name
            buffer_name = f"ema_{name.replace('.', '_')}"
            self.param_ema_mapping[name] = buffer_name
            model.register_buffer(buffer_name, value.data.clone())

        if self.checkpoint is not None:
            runner.resume(self.checkpoint)

    def after_train_iter(self, runner):
        """Update ema parameter every self.interval iterations."""
        if (runner.iter + 1) % self.interval != 0:
            return
        model = runner.model
        if is_module_wrapper(model):
            model = model.module
        state_dict = model.state_dict()
        for name, buffer_name in self.param_ema_mapping.items():
            online_value = state_dict[name]
            ema_buffer = state_dict[buffer_name]

            momentum = self.momentum * (
                1 - math.exp(-runner.iter / (self.warm_up * self.interval))
            )

            if online_value.dtype.is_floating_point:
                ema_buffer.mul_(momentum).add_(
                    online_value.data.float(), alpha=1 - momentum
                )
            else:
                ema_buffer.data.copy_(online_value.data.float())

    def after_train_epoch(self, runner):
        """We load parameter values from ema backup to model before the
        EvalHook."""
        self._swap_ema_parameters(runner)

    def before_train_epoch(self, runner):
        """We recover model's parameter from ema backup after last epoch's
        EvalHook."""
        if self.interval is None:
            assert self.nominal_batch_size is not None
            samples_per_gpu = runner.data_loader.sampler.samples_per_gpu
            _, word_size = get_dist_info()
            self.interval = math.ceil(
                self.nominal_batch_size / (samples_per_gpu * word_size)
            )
        self._swap_ema_parameters(runner)

    def _swap_ema_parameters(self, runner):
        """Swap the parameter of model with parameter in ema_buffer."""
        model = runner.model
        if is_module_wrapper(model):
            model = model.module
        state_dict = model.state_dict()
        for name, buffer_name in self.param_ema_mapping.items():
            online_value = state_dict[name]
            online_dtype = online_value.dtype
            temp = online_value.data.clone().float()
            ema_buffer = state_dict[buffer_name]
            online_value.data.copy_(ema_buffer.data.to(online_dtype))
            # re-register buffer to force it to be fp32
            model.register_buffer(buffer_name, temp)


'''
Given folders containing runs of algorithms on a benchmark over a set of random seeds,
plots their oracle performances on the same graph (test.png)
and records their corresponding final values (output.txt).
'''

import matplotlib.pyplot as plt
import numpy as np
import argparse
import os, json

if __name__ == "__main__":

    parser = argparse.ArgumentParser()

    parser.add_argument('--output', type=str, default='test')
    parser.add_argument('--num_comps', type=int, default=6)
    parser.add_argument('--seeds', type=str, default='1,2,3,4,5')
    parser.add_argument('--iters', type=int, default=100)
    parser.add_argument('--folder0', type=str)
    parser.add_argument('--folder1', type=str)
    parser.add_argument('--folder2', type=str)
    parser.add_argument('--folder3', type=str)
    parser.add_argument('--folder4', type=str)
    parser.add_argument('--folder5', type=str)

    args = parser.parse_args()
    arg_dict = vars(args)

    outdir = arg_dict["output"]
    if not os.path.exists(outdir):
        os.makedirs(outdir)

    seeds = [int(item) for item in arg_dict["seeds"].split(',')]
    colors = ['tab:red', 'k', 'tab:orange', 'tab:blue', 'tab:purple', 'tab:brown']

    plt.rc('axes', titlesize=16)
    plt.rc('axes', labelsize=16)
    plt.rc('xtick', labelsize=16)
    plt.rc('ytick', labelsize=16)

    f1 = plt.figure()
    ax1 = f1.gca()
    f2 = plt.figure()
    ax2 = f2.gca()

    for i in range(arg_dict["num_comps"]):
        job_dir = arg_dict["folder"+str(i)]
        with open(os.path.join(outdir, 'members.txt'), 'a') as record:
            record.write(job_dir+' '+colors[i])
            record.write('\n')

        test_mean = [[] for r in range(arg_dict["iters"])]
        test_stderr = [[] for r in range(arg_dict["iters"])]
        train_mse = [[] for r in range(arg_dict["iters"])]
        for s in range(len(seeds)):
            log_dir = os.path.join(job_dir, 'seed_'+str(seeds[s]))
            training_file = os.path.join(log_dir, 'train.json')
            evaluation_file = os.path.join(log_dir, 'test.json')

            # Testing results
            results = []
            with open(evaluation_file, 'r') as test:
                for line in test:
                    results.append(json.loads(line))
            for data in results:
                r = data['round']
                test_mean[r].append(data['loss_est'])
                test_stderr[r].append(data['loss_stderr'])

            # Training results
            train_obj = []
            with open(training_file, 'r') as train:
                for line in train:
                    train_obj.append(json.loads(line))
            for data in train_obj:
                r = data['round']
                train_mse[r].append(data['mse'])

        compiled_rounds = np.arange(arg_dict["iters"])
        compiled_test_mean = np.asarray([np.mean(np.asarray(test_mean[r])) for r in range(arg_dict["iters"])])
        compiled_test_var = np.asarray([(np.var(np.asarray(test_mean[r]))
            +np.mean(np.asarray(test_stderr[r])**2))/len(test_mean[r]) for r in range(arg_dict["iters"])])
        compiled_train_mse = np.asarray([np.mean(np.asarray(train_mse[r])) for r in range(arg_dict["iters"])])
        compiled_mse_stderr = np.asarray([np.std(np.asarray(train_mse[r]))/np.sqrt(10*len(seeds)) for r in range(arg_dict["iters"])])
        with open(os.path.join(outdir, 'output.txt'), 'a') as printout:
            printout.write('For folder {}, the final test performance is {} with standard error {}'.format(i, compiled_test_mean[-1], np.sqrt(compiled_test_var[-1])))
            printout.write('\n')

        ax1.plot(compiled_rounds, compiled_test_mean, colors[i])
        ax1.fill_between(compiled_rounds, compiled_test_mean-np.sqrt(compiled_test_var),
                compiled_test_mean+np.sqrt(compiled_test_var), facecolor=colors[i], alpha=0.25)
        ax2.plot(compiled_rounds, compiled_train_mse, colors[i])
        ax2.fill_between(compiled_rounds, compiled_train_mse-compiled_mse_stderr,
                compiled_train_mse+compiled_mse_stderr, facecolor=colors[i], alpha=0.25)

    ax1.set_xlabel('Round')
    ax1.set_ylabel('Test loss')
    f1.savefig(os.path.join(outdir, 'test.png'), bbox_inches = 'tight')
    plt.close(f1)

    ax2.set_xlabel('Round')
    ax2.set_ylabel('Gradient MSE')
    f2.savefig(os.path.join(outdir, 'train_mse.png'), bbox_inches = 'tight')
    plt.close(f2)


import pandas as pd
import numpy as np
from io import StringIO

f = open("day4.txt", "r")
numbers = list(map(int, ''.join(f.readline()).strip().split(",")))
print("Sample:", numbers[:5])

boards = []
while True:
    board = ''.join(f.readline() for _ in range(6)).strip().replace("  ", " ").replace("\n ", "\n")
    if not board:
        break
    boards.append(pd.read_csv(StringIO(board), sep=" ", header=None))

print("Sample:\n", boards[3])

stop = False
for x in numbers:
    if stop:
        break
    for df in boards:
        df.replace(x, -1, inplace=True)
        if any((df == -1).sum(axis=0) == 5) or any((df == -1).sum(axis=1) == 5):
            print("Winning board:\n", df)
            print("x=", x)
            unmarked = df.sum().sum() + (df == -1).sum().sum()
            print("Sum of unmarked numbers:", unmarked)
            print("Product is:", x * unmarked)
            stop = True

stop_df = None
stop_x = None
for x in numbers:
    for i, df in enumerate(boards):
        if df is not None:
            df.replace(x, -1, inplace=True)
            if any((df == -1).sum(axis=0) == 5) or any((df == -1).sum(axis=1) == 5):
                stop_df = df
                stop_x = x
                boards[i] = None
print("Last winning board:\n", stop_df)
print("x=", stop_x)
unmarked = stop_df.sum().sum() + (stop_df == -1).sum().sum()
print("Sum of unmarked numbers:", unmarked)
print("Product is:", stop_x * unmarked)


from cgitb import small
import heapq

# https://leetcode.com/problems/find-median-from-data-stream/
class MedianFinder(object):

    def __init__(self):
        self.small=[] # min geap
        self.large=[] # max heap

    def addNum(self, num):
        """
        :type num: int
        :rtype: None
        """
        # check the num
        if num<self.small[0]:
            heapq.heappush(self.small,num)
        else:
            heapq.heappush(self.large,num*-1)

        if abs(len(self.small)-len(self.large))>1:
            # we need balencing
            if len(self.small)<len(self.large):
                # small has more elements pop one and add to large
                heapq.heappop(self.large)

    def findMedian(self):
        """
        :rtype: float
        """
        pass

# Your MedianFinder object will be instantiated and called as such:
medianFinder=MedianFinder()
medianFinder.addNum(1)
medianFinder.addNum(2)
medianFinder.findMedian()
medianFinder.addNum(3)
medianFinder.findMedian()
# obj = MedianFinder()
# obj.addNum(num)
# param_2 = obj.findMedian()


import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
from torch.distributions import Categorical

from collections import OrderedDict
from maml_rl.policies.policy import Policy, weight_init

A_DIM = 6

class CriticNet(Policy):
    """Policy network based on a multi-layer perceptron (MLP), with a
    `Categorical` distribution output. This policy network can be used on tasks
    with discrete action spaces (eg. `TabularMDPEnv`). The code is adapted from
    https://github.com/cbfinn/maml_rl/blob/9c8e2ebd741cb0c7b8bf2d040c4caeeb8e06cc95/sandbox/rocky/tf/policies/maml_minimal_categorical_mlp_policy.py
    """

    def __init__(self, input_size, output_size, learning_rate=0.001):
        super(CriticNet, self).__init__(input_size=input_size, output_size=output_size)

        # for i in range(1, self.num_layers + 1):
        #     self.add_module('layer{0}'.format(i),
        #         nn.Linear(layer_sizes[i - 1], layer_sizes[i]))
        self.add_module('layer0-fc0', nn.Linear(1, 128))
        self.add_module('layer0-fc1', nn.Linear(1, 128))
        self.add_module('layer0-cv0', nn.Conv1d(1, 128, 4))
        self.add_module('layer0-cv1', nn.Conv1d(1, 128, 4))
        self.add_module('layer0-cv2', nn.Conv1d(1, 128, 4))
        self.add_module('layer0-fc2', nn.Linear(1, 128))

        self.add_module('layer1-fc', nn.Linear(2048, 128))  # 输入维度待定~~~~~~~~~~~~~~~
        self.add_module('layer2-fc', nn.Linear(128, 1))

        self.apply(weight_init)

        self.learning_rate = learning_rate
        self.opt = torch.optim.RMSprop(self.parameters(), lr=learning_rate)

    def forward(self, input, params=None):
        if params is None:
            params = OrderedDict(self.named_parameters())
        # output = torch.tensor(input)
        output = torch.tensor(input)
        output = output.float()
        state_size0, state_size1, state_size2, state_size3 = output.size()

        state_size = state_size0 * state_size1
        output = output.reshape(state_size, state_size2, state_size3)

        # bit_rate, buffer_size, next_chunk_size, bandwidth_measurement(throughput and time), chunk_til_video_end
        # print(output[:, 0, -1].size())
        split0 = F.linear(output[:, 0, -1].view(state_size, 1),
                          weight=params['layer0-fc0.weight'],
                          bias=params['layer0-fc0.bias'])
        split0 = F.relu(split0)

        split1 = F.linear(output[:, 1, -1].view(state_size, 1),
                          weight=params['layer0-fc1.weight'],
                          bias=params['layer0-fc1.bias'])
        split1 = F.relu(split1)

        split2 = F.conv1d(output[:, 2, :].view(state_size, 1, -1),
                          weight=params['layer0-cv0.weight'],
                          bias=params['layer0-cv0.bias'])
        split2 = split2.view(state_size, -1)
        split2 = F.relu(split2)

        split3 = F.conv1d(output[:, 3, :].view(state_size, 1, -1),
                          weight=params['layer0-cv1.weight'],
                          bias=params['layer0-cv1.bias'])
        split3 = split3.view(state_size, -1)
        split3 = F.relu(split3)

        split4 = F.conv1d(output[:, 4, :A_DIM].view(state_size, 1, -1),
                          weight=params['layer0-cv2.weight'],
                          bias=params['layer0-cv2.bias'])
        split4 = split4.view(state_size, -1)
        split4 = F.relu(split4)

        split5 = F.linear(output[:, 5, -1].view(state_size, 1),
                          weight=params['layer0-fc2.weight'],
                          bias=params['layer0-fc2.bias'])
        split5 = F.relu(split5)

        merge = torch.cat([split0, split1, split2, split3, split4, split5], 1)
        merge = F.relu(merge)

        output = F.linear(merge,
                          weight=params['layer1-fc.weight'],
                          bias=params['layer1-fc.bias'])
        output = F.relu(output)

        output = F.linear(output,
            weight=params['layer2-fc.weight'],
            bias=params['layer2-fc.bias'])

        output = output.reshape(state_size0, state_size1, 1)

        return output

    def fit(self, episodes, learning_rate=0.001, isnew=False):
        if isnew:  # start a new optimizer for meta-training
            self.opt = torch.optim.RMSprop(self.parameters(), lr=learning_rate, alpha=0.9)

        returns = episodes.returns
        loss_func = torch.nn.MSELoss()

        loss_list = []
        for i in range(returns.size()[1]):
            values = self.forward(episodes.observations[:, i:i+1, :, :]).view(-1)
            loss = loss_func(values, returns[:, i])
            self.opt.zero_grad()
            loss.backward()
            self.opt.step()
            loss_list.append(float(loss))

        loss_list = np.array(loss_list)
        return loss_list.mean()


'''
Created on 24 nov 2021

@author: migueltoro
'''

from us.lsi.tools.Iterable import str_iter
from us.lsi.tools.File import lineas_de_fichero,absolute_path
import sys
import calendar
from sortedcontainers.sorteddict import SortedDict # type: ignore
import random

d = {0:'a',3:'b',2:'c'}
print(list(d.values()))
r2 = "La respuesta es correcta"

def pp(file:str)->float:
    ls: list[str] = lineas_de_fichero(file)
    ls2: list[str] = ls [1:]
    n:int = 0
    s:float = 0.
    for e in ls2:
        s = s + float(e.split(',')[1])
        n = n+1
    m = s/n
    return m

def pp2(file:str)->float:
    ls: list[str] = lineas_de_fichero(file)
    ls2: list[str] = ls [1:]
    n:int = 0
    s:float = 0.
    for e in ls2:
        _,v,_ = e.split(',')
        s = s + float(v)
        n = n+1
    m = s/n
    return m

numeros = [7, 3, 5, 1, 3, 1, 7]

if __name__ == '__main__':
    print(str_iter(sys.path,sep='\n'))
    print(list(calendar.day_name))
    print(d)
    r = sorted(d.items(),reverse=True)
    random.shuffle(r)
    print(r)
    print(SortedDict(r))
    print(len(r2))
    print(r2[23])
    num = 29
    print(num % 3 == 0 or 20 <= num <= 30)
    print(4+1.)
    print(pp(absolute_path('/resources/pp.txt')))
    print(pp2(absolute_path('/resources/pp.txt')))
    print(numeros[8-2])


import os
import xlrd
from airflow import DAG
from airflow.contrib.hooks.wasb_hook import WasbHook
from airflow.operators.dummy_operator import DummyOperator
from airflow.operators.python_operator import PythonOperator
from airflow.operators.mssql_operator import MsSqlOperator
from datetime import datetime, timedelta
from datetime import date
import pandas as pd
from pandas import read_excel
from variables import sql_connid,sql_connid_gomedisys
from utils import sql_2_df,open_xls_as_xlsx,load_df_to_sql,search_for_file_prefix, get_files_xlsx_contains_name, get_files_with_prefix_args,search_for_file_contains, respond, read_csv, move_to_history_for_prefix,  get_files_xlsx_with_prefix, get_files_xlsx_with_prefix_args,file_get

#  Se nombran las variables a utilizar en el dag

db_table = "factMedicalScales"
db_tmp_table = "tmp_factMedicalScales"
dag_name = 'dag_' + db_table

# Función de extracción del archivo del blob al servidor, transformación del dataframe y cargue a la base de datos mssql
def func_get_factMedicalScales ():

    now = datetime.now()
    last_week = now - timedelta(days=15)
    last_week = last_week.strftime('%Y-%m-%d %H:%M:%S')
    print(now)
    print(last_week)

    # LECTURA DE DATOS
    query = f"""
        select fms.*, EMD.idDiagnostic from (
        select
            EVE.idEHREvent,EVE.idPatient,EVE.idPractitioner, EVE.actionRecordedDate
            ,EMS.idEvaluation
            ,GA.idAction
            ,GS.idSpecialty,GS.name as specialityName
            ,CSV.[idScale],CSV.[name] as evaluationName--,CSV.minValue,CSV.maxValue
            ,sum(EMSQ.[value]) value

        from
            dbo.encounters EN
            ,dbo.encounterRecords ENR
            ,dbo.EHREvents EVE
            ,dbo.generalActions GA
            ,dbo.generalSpecialties GS
            ,dbo.EHREventMedicalScales EMS
            ,dbo.EHREventMedicalScaleQuestions EMSQ
            ,dbo.EHRConfScaleValorations CSV
        where
            EN.idEncounter = EVE.idEncounter
            and EN.dateStart > '{last_week}'
            and EN.idEncounter = ENR.idEncounter
            and EVE.idEHREvent = EMS.idEHREvent
            and EVE.idEHREvent = EMSQ.idEHREvent
            and GA.idAction = EVE.idAction
            and GS.idSpecialty = EVE.idSpeciality
            and CSV.[idScale] = 11
            and EMS.idScale = EMSQ.idScale
            and CSV.idScale = EMS.idScale
            and EMS.idEvaluation = CSV.[idRecord]
        group by
            EMS.idEvaluation
            ,EVE.idEHREvent
            ,EVE.idPatient
            ,EVE.idPractitioner
            ,EVE.actionRecordedDate
            ,GA.idAction
            ,GS.idSpecialty
            ,GS.name
            ,CSV.[idScale]
            ,CSV.[name]
            ,CSV.minValue
            ,CSV.maxValue
            ) FMS LEFT JOIN (SELECT idDiagnostic, idEHREvent FROM EHREventMedicalDiagnostics WHERE isPrincipal = 1) EMD ON FMS.idEHREvent = EMD.idEHREvent
    """
    df = sql_2_df(query, sql_conn_id=sql_connid_gomedisys)
    # print(df.columns)
    # print(df.dtypes)
    # print(df)

    # PROCESAMIENTO
    df['actionRecordedDate'] = pd.to_datetime(df['actionRecordedDate'], errors='coerce')
    df['actionRecordedDate'] = df['actionRecordedDate'].astype(str)

    # convert to int
    cols_int = ['idDiagnostic']
    for col in cols_int:
        df[col] = df[col].astype(str).str.replace('.0','')
        df[col] = df[col].replace('','nan')
        # df[col] = pd.to_numeric(df[col], errors='coerce', downcast='integer')

    df = df.drop_duplicates(subset=['idEHREvent','idPatient','idPractitioner','idEvaluation','idAction','idSpecialty','idScale'])

    print(df.columns)
    print(df.dtypes)
    print(df)

    print(df[df['idEHREvent']==2214900])

    # CARGA A BASE DE DATOS
    if ~df.empty and len(df.columns) >0:
        load_df_to_sql(df, db_tmp_table, sql_connid)

# Se declara un objeto con los parámetros del DAG
default_args = {
    'owner': 'clinicos',
    'depends_on_past': False,
    'start_date': datetime(2015, 6, 1),
}
# Se declara el DAG con sus respectivos parámetros
with DAG(dag_name,
    catchup=False,
    default_args=default_args,
    # Se establece la ejecución del dag a las 10:40 am (hora servidor) todos los Jueves
    schedule_interval= '40 10 * * 04',
    max_active_runs=1
    ) as dag:

    # Se declara la función que sirve para denotar el inicio del DAG a través de DummyOperator
    start_task = DummyOperator(task_id='dummy_start')

    #Se declara y se llama la función encargada de traer y subir los datos a la base de datos a través del "PythonOperator"
    get_factMedicalScales_python_task = PythonOperator(task_id = "get_factMedicalScales",
                                                        python_callable = func_get_factMedicalScales,
                                                        email_on_failure=True,
                                                        email='BI@clinicos.com.co',
                                                        dag=dag
                                                        )

    # Se declara la función encargada de ejecutar el "Stored Procedure"
    load_factMedicalScales = MsSqlOperator(task_id='Load_factMedicalScales',
                                            mssql_conn_id=sql_connid,
                                            autocommit=True,
                                            sql="EXECUTE sp_load_factMedicalScales",
                                            email_on_failure=True,
                                            email='BI@clinicos.com.co',
                                            dag=dag
                                       )

    # Se declara la función que sirva para denotar la Terminación del DAG, por medio del operador "DummyOperator"
    task_end = DummyOperator(task_id='task_end')

start_task >> get_factMedicalScales_python_task >> load_factMedicalScales >> task_end


from threading import Lock
from time import sleep
from time import time
from typing import Callable
from typing import List
from typing import Optional

from paho.mqtt import client as mqtt

from wolk_gateway_module.connectivity.connectivity_service import (
    ConnectivityService,
)
from wolk_gateway_module.logger_factory import logger_factory
from wolk_gateway_module.model.message import Message

class MQTTConnectivityService(ConnectivityService):
    """Responsible for exchanging data with WolkGateway through MQTT."""

    def __repr__(self) -> str:
        """
        Make string representation of MQTTConnectivityService.

        :returns: representation
        :rtype: str
        """
        return (
            f"MQTTConnectivityService(host='{self.host}', "
            f"port='{self.port}', "
            f"client_id='{self.client_id}', "
            f"topics='{self.topics}', "
            f"qos='{self.qos}', "
            f"lastwill_message='{self.lastwill_message}', "
            f"inbound_message_listener='{self.inbound_message_listener}', "
            f"connected='{self._connected}')"
        )

    def __init__(
        self,
        host: str,
        port: int,
        client_id: str,
        qos: int,
        lastwill_message: Message,
        topics: list,
    ) -> None:
        """
        Prepare MQTT connectivity service for connecting to WolkGateway.

        :param host: Address of WolkGateway
        :type host: str
        :param port: TCP/IP port of WolkGateway used for MQTT connection
        :type port: int
        :param client_id: Unique module identifier
        :type client_id: str
        :param qos: MQTT Quality of Service level (0, 1, 2)
        :type qos: int
        :param lastwill_message: Last will message
        :type lastwill_message: Message
        :param topics: List of topics to subscribe to
        :type topics: list
        """
        self.log = logger_factory.get_logger(str(self.__class__.__name__))

        self.host = host
        self.port = port
        self.client_id = client_id
        self.topics = topics
        self.qos = qos
        self.lastwill_message = lastwill_message
        self.inbound_message_listener: Callable[
            [Message], None
        ] = lambda message: print("\n\nNo inbound message listener set!\n\n")
        self._connected = False
        self.connected_rc: Optional[int] = None

        self.client = mqtt.Client(client_id=self.client_id)
        self.client.on_connect = self._on_mqtt_connect
        self.client.on_disconnect = self._on_mqtt_disconnect
        self.client.on_message = self._on_mqtt_message
        self.client.username_pw_set(self.client_id)
        self.client.will_set(
            self.lastwill_message.topic, self.lastwill_message.payload
        )

        self.mutex = Lock()

        self.log.debug(self.__repr__())

    def set_inbound_message_listener(
        self, on_inbound_message: Callable[[Message], None]
    ) -> None:
        """
        Set the callback function ot handle inbound messages.

        :param on_inbound_message: Callable that handles inbound messages
        :type on_inbound_message: Callable[[Message], None]
        """
        self.log.debug(f"Set inbound message listener to {on_inbound_message}")
        self.inbound_message_listener = on_inbound_message

    def set_lastwill_message(self, message: Message) -> None:
        """Send offline state for module devices on disconnect."""
        self.log.debug(f"Set lastwill message: {message}")
        if self._connected:
            self.log.debug("Reconnecting to set lastwill")
            self.disconnect()
            self.lastwill_message = message
            self.connect()
        else:
            self.lastwill_message = message

    def add_subscription_topics(self, topics: List[str]) -> None:
        """
        Add subscription topics.

        Adding these topics will not subscribe to them immediately,
        a new connection needs to happen to subscribe to them.

        :param topics: List of topics
        :type topics: List[str]
        """
        self.log.debug(f"Adding {topics} to {self.topics}")
        self.topics.extend(topics)

    def remove_topics_for_device(self, device_key: str) -> None:
        """
        Remove topics for device from subscription topics.

        :param device_key: Device identifier
        :type device_key: str
        """
        self.log.debug(f"Removing topics for device {device_key}")
        if len(self.topics) == 0:
            return

        for topic in self.topics:
            if device_key in topic:
                self.topics.remove(topic)

    def connected(self) -> bool:
        """
        Return if currently connected.

        :returns: connected
        :rtype: bool
        """
        return self._connected

    def connect(self) -> bool:
        """
        Establish connection with WolkGateway.

        :returns: result
        :rtype: bool
        """
        if self._connected:
            self.log.info("Already connected")
            return True

        self.mutex.acquire()

        self.client.connect(self.host, self.port)
        self.client.loop_start()

        self.log.info(f"Connecting to {self.host}:{self.port} ...")

        timeout = round(time()) + 5

        while True:

            if round(time()) > timeout:
                self.log.warning("Connection timed out!")
                self.mutex.release()
                return False

            if self._connected is not True:
                sleep(0.1)
                continue

            if self.connected_rc == 0:
                break

            elif self.connected_rc == 1:
                self.log.error(
                    "Connection refused - incorrect protocol version"
                )
                self.mutex.release()
                return False

            elif self.connected_rc == 2:
                self.log.error(
                    "Connection refused - invalid client identifier"
                )
                self.mutex.release()
                return False

            elif self.connected_rc == 3:
                self.log.error("Connection refused - server unavailable")
                self.mutex.release()
                return False

            elif self.connected_rc == 4:
                self.log.error("Connection refused - bad username or password")
                self.mutex.release()
                return False

            elif self.connected_rc == 5:
                self.log.error("Connection refused - not authorized")
                self.mutex.release()
                return False

        self.log.debug(f"Subscribing to topics: {self.topics}")
        for topic in self.topics:
            self.client.subscribe(topic, 2)

        self.mutex.release()
        self._connected = True

        return True

    def reconnect(self) -> bool:
        """
        Terminate existing and create new connection with WolkGateway.

        :returns: result
        :rtype: bool

        :raises RuntimeError: Reason for connection being refused
        """
        self.log.debug("Attempting reconnect")
        if self._connected:
            self.client.loop_stop()
            self.client.disconnect()

        return self.connect()

    def disconnect(self) -> None:
        """Terminate connection with WolkGateway."""
        self.log.debug(f"Disconnecting from {self.host} : {self.port}")
        if self._connected:
            self.client.publish(
                self.lastwill_message.topic, self.lastwill_message.payload
            )
            self.client.loop_stop()
            self.client.disconnect()

    def publish(self, message: Message) -> bool:
        """
        Publish serialized data to WolkGateway.

        :param message: Message to be published
        :type message: Message
        :returns: result
        :rtype: bool
        """
        if not self._connected:
            self.log.warning(f"Not connected, unable to publish {message}")
            return False

        self.mutex.acquire()

        info = self.client.publish(message.topic, message.payload, self.qos)

        if info.rc == mqtt.MQTT_ERR_SUCCESS:
            self.log.debug(f"Published {message}")
            self.mutex.release()
            return True
        else:
            self.mutex.release()
            return info.is_published()

    def _on_mqtt_message(
        self, client: mqtt.Client, userdata: str, message: mqtt.MQTTMessage
    ) -> None:
        """
        Parse inbound messages and pass them to message listener.

        :param client: Client that received the message
        :type client: paho.mqtt.Client
        :param userdata: Private user data set in Client()
        :type userdata: str
        :param message: Class with members: topic, payload, qos, retain.
        :type message: paho.mqtt.MQTTMessage
        """
        self.log.debug(f"Received message on topic: {message.topic}")
        self.inbound_message_listener(Message(message.topic, message.payload))

    def _on_mqtt_connect(
        self, client: mqtt.Client, userdata: str, flags: int, rc: int
    ) -> None:
        """
        Handle when the client receives a CONNACK response from the server.

        :param client: Client that received the message
        :type client: paho.mqtt.Client
        :param userdata: private user data set in Client()
        :type userdata: str
        :param flags: Response flags sent by the broker
        :type flags: int
        :param rc: Connection result
        :type rc: int
        """
        self.log.debug(f"CONNACK: {rc}")
        if rc == 0:  # Connection successful
            self.connected_rc = 0
            self._connected = True
            # Subscribing in on_mqtt_connect() means if we lose the connection
            # and reconnect then subscriptions will be renewed.
            if self.topics:
                self.mutex.acquire()
                for topic in self.topics:
                    self.client.subscribe(topic, 2)
                self.mutex.release()
        elif rc == 1:  # Connection refused - incorrect protocol version
            self.connected_rc = 1
        elif rc == 2:  # Connection refused - invalid client identifier
            self.connected_rc = 2
        elif rc == 3:  # Connection refused - server unavailable
            self.connected_rc = 3
        elif rc == 4:  # Connection refused - bad username or password
            self.connected_rc = 4
        elif rc == 5:  # Connection refused - not authorized
            self.connected_rc = 5

    def _on_mqtt_disconnect(
        self, client: mqtt.Client, userdata: str, rc: int
    ) -> None:
        """
        Handle when the client disconnects from the broker.

        :param client: Client that received the message
        :type client: paho.mqtt.Client
        :param userdata: private user data set in Client()
        :type userdata: str
        :param rc: Disconnection result
        :type rc: int
        """
        self.log.debug(f"Disconnect return code: {rc}")
        self._connected = False
        if rc != 0:
            self.log.warning(
                f"Unexpected disconnect on {self.host}:{self.port}!"
            )


from archfinch.settings_local import *

import djcelery
djcelery.setup_loader()

ADMINS = (
    ('drx', 'luke@archfinch.com'),
)

MANAGERS = ADMINS

# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# If running in a Windows environment this must be set to the same as your
# system time zone.
TIME_ZONE = 'America/Los_Angeles'

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'

SITE_ID = 1

# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = False

# Absolute path to the directory that holds media.
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = '/var/django/archfinch/media'

# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash if there is a path component (optional in other cases).
# Examples: "http://media.lawrence.com", "http://example.com/media/"
MEDIA_URL = '/media/'

WEB_ROOT = '/var/www/archfinch/cache/'

# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
# trailing slash.
# Examples: "http://foo.com/media/", "/media/".
ADMIN_MEDIA_PREFIX = '/adminmedia/'

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.load_template_source',
    'django.template.loaders.app_directories.load_template_source',
#     'django.template.loaders.eggs.load_template_source',
)

MIDDLEWARE_CLASSES = (
    'django.middleware.gzip.GZipMiddleware',
    'archfinch.main.middleware.NofollowMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'archfinch.main.middleware.SearchEngineReferrerMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'archfinch.main.middleware.ShortenerMiddleware',
)

ROOT_URLCONF = 'archfinch.urls'

TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    '/var/django/archfinch/templates',
)

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.humanize',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.admin',
    'django.contrib.admindocs',
    'django.contrib.markup',
    'archfinch.main',
    'archfinch.account',
    'archfinch.links',
    'archfinch.lists',
    'archfinch.wiki',
    'archfinch.users',
    'archfinch.search',
    'archfinch.comments',
    'archfinch.sync',
    'djcelery',
    'lazysignup',
    'reversetag',
    'django_js_utils',
)
if DEBUG:
    INSTALLED_APPS += (
        'devserver',
        'django_extensions',
    )
    DEVSERVER_MODULES = (
        'devserver.modules.sql.SQLRealTimeModule',
        'devserver.modules.sql.SQLSummaryModule',
        'devserver.modules.profile.ProfileSummaryModule',

        # Modules not enabled by default
        'devserver.modules.ajax.AjaxDumpModule',
        #'devserver.modules.profile.MemoryUseModule',
        'devserver.modules.cache.CacheSummaryModule',
    )
    DEVSERVER_TRUNCATE_SQL = False

    STATIC_URL = 'media'
else:
    INSTALLED_APPS += (
        'sentry',
        'sentry.client',
    )

AUTHENTICATION_BACKENDS = (
    'archfinch.users.auth_backends.ModelBackend',
    'lazysignup.backends.LazySignupBackend',
)

LOGIN_REDIRECT_URL = '/'
LOGIN_URL = '/account/login'

USER_MODEL = 'users.User'
LAZYSIGNUP_USER_MODEL = USER_MODEL

LAZYSIGNUP_USER_AGENT_BLACKLIST = (
    'slurp',
    'googlebot',
    'yandex',
    'msnbot',
    'baiduspider',
    'pingdom',
    'cloudkick',
    'facebook',
)

DOMAIN = 'archfinch.com'
SHORT_DOMAIN = 'arfn.ch'


#! /usr/bin/python3.6

# -*- coding: utf-8 -*-

import colorsys
import datetime
import dill
import gzip
import os
import shutil
import string
import subprocess
import sys
import time
import traceback

import numpy as np

import matplotlib.pyplot as plt

from dotmap import DotMap

from indexed import IndexedOrderedDict
from collections import OrderedDict
from dotmap import DotMap
from PIL import Image, ImageDraw, ImageFont

all_symbols_16 = np.array(list("0123456789ABCDEF"))
def get_random_string_base_16(n):
    l = np.random.randint(0, 16, (n, ))
    return "".join(all_symbols_16[l])

def get_date_time_str():
    dt = datetime.datetime.now()
    return "Y{:04}_m{:02}_d{:02}_H{:02}_M{:02}_S{:02}_f{:06}".format(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond)
    # return "{:Y%Ym%md%dH%HM%MS%Sf%f}".format(datetime.datetime.now())

def check_create_folders(folder_path):
    if not os.path.exists(folder_path):
        os.makedirs(folder_path)

if __name__ == "__main__":
    main_folder = "images/"
    check_create_folders(main_folder)

    max_length = 20.
    modulo = 10.
    n = 400
    xs = np.arange(0, n)/n*max_length-max_length/2
    ys = np.arange(0, n)/n*max_length-max_length/2

    # print("xs: {}".format(xs))

    funcs = [
        lambda x, y: x*y*np.cos(y)+1+np.sin(x),
    ]

    hsv_to_rgb_vectorized = np.vectorize(colorsys.hsv_to_rgb)

    def get_random_func():
        params = np.random.random((3, 9))-0.5
        cols_value = [10, 2, 2, 1, 0.2, 0.2, 0.1, 0.1, 0.05]
        # for i, v in enumerate(cols_value):
        #     params[:, i] = params[:, i]*v
        # params *= cols_value

        return lambda x, y: (
            params[0][0]+params[0][1]*np.sin(x)+params[0][2]*np.sin(y)+np.sin(x*params[0][3]+y*params[0][4]+params[0][6])*(x*params[0][7]+y*params[0][8]), # +x*y*params[0][3]+x**2*params[0][4]+y**2*params[0][5]+x**2*y*params[0][6]+x*y**2*params[0][7]+x**2*y**2*params[0][8],
            params[1][0]+params[1][1]*np.sin(x)+params[1][2]*np.sin(y)+np.sin(x*params[1][3]+y*params[1][4]+params[1][6])*(x*params[1][7]+y*params[1][8]), # +x*y*params[1][3]+x**2*params[1][4]+y**2*params[1][5]+x**2*y*params[1][6]+x*y**2*params[1][7]+x**2*y**2*params[1][8],
            params[2][0]+params[2][1]*np.sin(x)+params[2][2]*np.sin(y)+np.sin(x*params[2][3]+y*params[2][4]+params[2][6])*(x*params[2][7]+y*params[2][8]), # +x*y*params[2][3]+x**2*params[2][4]+y**2*params[2][5]+x**2*y*params[2][6]+x*y**2*params[2][7]+x**2*y**2*params[2][8],
        )

        # return lambda x, y: (
        #     params[0][0]+x*params[0][1]+y*params[0][2]+x*y*params[0][3]+x**2*params[0][4]+y**2*params[0][5]+x**2*y*params[0][6]+x*y**2*params[0][7]+x**2*y**2*params[0][8],
        #     params[1][0]+x*params[1][1]+y*params[1][2]+x*y*params[1][3]+x**2*params[1][4]+y**2*params[1][5]+x**2*y*params[1][6]+x*y**2*params[1][7]+x**2*y**2*params[1][8],
        #     params[2][0]+x*params[2][1]+y*params[2][2]+x*y*params[2][3]+x**2*params[2][4]+y**2*params[2][5]+x**2*y*params[2][6]+x*y**2*params[2][7]+x**2*y**2*params[2][8],
        # )

        # return lambda x, y: (
        #     x,
        #     y+2,
        #     x+y-3,
        # )

    rgb_func = get_random_func()
        # x+y*4+3,
        # -x+np.sin(y)-x*np.cos(y+x)
    # )

    arr_x = np.zeros((ys.shape[0], xs.shape[0]))
    arr_y = np.zeros((ys.shape[0], xs.shape[0]))

    arr_x[:] = xs
    arr_y[:] = ys.reshape((-1, 1))

    # rgb_floats = np.vectorize(funcs[0])(arr_x, arr_y)
    rgb_floats = np.dstack(np.vectorize(rgb_func)(arr_x, arr_y))
    print("rgb_floats.shape: {}".format(rgb_floats.shape))
    print("rgb_floats.dtype: {}".format(rgb_floats.dtype))

    # r_channel = rgb_floats[:, :, 0]
    # g_channel = rgb_floats[:, :, 1]
    # b_channel = rgb_floats[:, :, 2]

    # rgb_floats %= 1.
    argmax = np.argmax(np.sum(rgb_floats**2, axis=1))
    print("argmax: {}".format(argmax))

    mins = np.min(np.min(rgb_floats, axis=0), axis=0)
    maxs = np.max(np.max(rgb_floats, axis=0), axis=0)
    print("mins: {}".format(mins))
    print("maxs: {}".format(maxs))

    arr_hsv_1 = (rgb_floats-mins)/(maxs-mins)
    arr_rgb_1 = np.dstack(hsv_to_rgb_vectorized(arr_hsv_1[:, :, 0], arr_hsv_1[:, :, 1], arr_hsv_1[:, :, 2]))

    pix = (arr_rgb_1*255.9).astype(np.uint8)

    img = Image.fromarray(pix)
    img.show()

    # make a pseudo complex function plot!
    # np.

    imgs = []
    axises = [(0, 1), (0, 2), (1, 2)]

    for ax1, ax2 in axises:
        arr_rg = 1j * rgb_floats[:, :, ax2] + rgb_floats[:, :, ax1]
        arr_angle = np.angle(arr_rg)
        arr_abs = np.abs(arr_rg)
        arr_abs
        idx = arr_angle < 0
        arr_angle[idx] = arr_angle[idx]+np.pi*2
        # arr_angle /= np.max(arr_angle)
        arr_angle /= (np.pi*2)

        arr_hsv = np.dstack((arr_angle, np.ones(arr_angle.shape), np.ones(arr_angle.shape)))

        arr_rgb = (np.dstack(hsv_to_rgb_vectorized(arr_hsv[:, :, 0], arr_hsv[:, :, 1], arr_hsv[:, :, 2]))*255.9).astype(np.uint8)

        img2 = Image.fromarray(arr_rgb)
        # img2.show()
        imgs.append(img2)

    for img in imgs:
        img.show()


import PIL
from PIL import ImageGrab
from PIL import Image
from PIL import ImageOps
from PIL import ImageStat
import time
import serial
import json

arduinoSerial = serial.Serial("/dev/cu.usbmodem143301") #Create Serial port object called arduinoSerial
time.sleep(2) #wait for 2 secounds for the communication to get established

maxAngle = 40
stepsPerRev = 4096
maxSteps = stepsPerRev / 360 * maxAngle

def image2Data():
    originalImage = PIL.ImageGrab.grab((1200, 100, 2200, 1600))
    bnwImage = PIL.ImageOps.grayscale(originalImage)
    bnwImage.save("result.png")

    grads = {}
    cropHeight = round(1500 / 3 + 0.5)
    cropWidth = round(1000 / 3 + 0.5)
    tileCount = 1
    for top in range(0, 1500, cropHeight):
        for left in range(0, 1000, cropWidth):
            crop = bnwImage.crop((left, top, left + cropWidth, top + cropHeight))
            stat = PIL.ImageStat.Stat(crop)
            statAvg = stat.sum[0] / stat.count[0]
            angle = round(maxSteps - statAvg / 255 * maxSteps)
            grads[tileCount] = angle
            tileCount += 1
    #print(grads)
    return grads

isOn = True

while isOn:
    grads = image2Data()
    gradsJson = json.dumps(grads)
    arduinoSerial.write(gradsJson.encode('ascii'))
    #arduinoSerial.flush()
    time.sleep(0.5)