import xml.etree.ElementTree as ET
import glob
import os
import os.path
import shutil
from datetime import datetime

'''LIST VARIABLE'''
ORDER = ['wheelchair','stroller','power_controller','traffic_light_controller','table','kiosk','carrier','dog','fire_hydrant','stop','barricade','bench','chair','bus','bicycle','motorcycle','potted_plant','movable_signage','truck','traffic_light','traffic_sign','bollard','pole','person','tree_trunk','car']
used_img = []
# 'scooter',

'''INT VARIABLE'''
INSTANCE_THRESHOLD = 1700
folder_number = 2480

'''DICTIONARY VARIABLE'''
Class_index = {'bicycle' : 0
    ,'bus':1
    ,'car':2
    ,'carrier':3
    ,'cat':4
    ,'dog':5
    ,'motorcycle':6
    ,'movable_signage':7
    ,'person':8
    ,'scooter':9
    ,'stroller':10
    ,'truck':11
    ,'wheelchair':12
    ,'barricade':13
    ,'bench':14
    ,'bollard':15
    ,'chair':16
    ,'fire_hydrant':17
    ,'kiosk':18
    ,'parking_meter':19
    ,'pole':20
    ,'potted_plant':21
    ,'power_controller':22
    ,'stop':23
    ,'table':24
    ,'traffic_light':25
    ,'traffic_light_controller':26
    ,'traffic_sign':27
    ,'tree_trunk':28} #Class Annotation을 위한 {클래스 이름 : 라벨 넘버} 1:1 대응 Dictionary
Class_num = {} #Instance 개수를 구하기 위한 {인스턴스(클래스) 이름 : 인스턴스(클래스) 갯수} 1:1 대응 Dictionary
                                            #Class_num의 해당되는 int 값들은 전부 0으로 설정되어 있는 상태.
                                            #Class_num은 전역변수로 사용해야 업데이트에 용이함. 함수 인자로 받지 않고 바깥에 그대로 냅둠.

'''STRING VARIABLE'''

location = "/home/zetstream/Dataset/train/"
new_location = "home/zetstream/Dataset_Equal/train/"

location_win = "C:/Users/dldjw/OneDrive/바탕 화면/Test/"
new_location_win = "C:/Users/dldjw/OneDrive/바탕 화면/Test2/"

image_Bbox = "images/Bbox_"
label_Bbox = "labels/Bbox_"

log_dir = "/home/zetstream/Data_equal_Sampling_LOG.txt"
log_dir_win = "C:/Users/dldjw/OneDrive/바탕 화면/Data_equal_Sampling_LOG.txt"

for name in enumerate(Class_index):
    # print(name)
    Class_num[name[1]] = 0

# 우선순위 적용. 인스턴스 개수가 적은 순서로, 오름차순으로 정렬함.
# 크게 3가지 과정이 필요함

# 첫번째 : Order 배열을 순서대로 읽으면서 각 해당되는 값의 box 가 있는 이미지를 찾음

# 두번째 : 이미지를 찾았으면 그 이미지 파일을 옮기고 해당되는 박스의 라벨을 동시에 옮긴 폴더에 생성함.
#         라벨을 생성함과 동시에 Class_num에 그 개수를 업데이트 함. 이때 옮긴 파일의 이름을 used_img 배열에 담음.

# 세번째 : 과정을 반복하다가 정해진 instance_THRESHOLD 개수를 채우면 옮김을 중지. Order의 다음 인스턴스와 Class_num의 그 인스턴스의 개수를 확인.
#                       만약 Class_num(해당되는 인스턴스) < instance_THRESHOLD 이면 그 차이만큼 채움 시작. 이 과정을 반복함.

# 추가적인 사항 : 각 Iteration 마다 Log를 기록하여 txt로 남기면 디버깅 편리할 듯.

def Count_instance_num(Class_num):
    sum = 0
    for i in range(Class_num):
        sum += i[Class_num[1]]
    return sum

def Progress(Order, Threshold):
    for iter, instance_selected in enumerate(Order):
        instance_number = Class_num[instance_selected]
        instance_needed = Threshold - instance_number
        print("{}th iter {} : {}, needed : {}".format(iter+1, instance_selected,instance_number,instance_needed))
        # 각 인스턴스 별로 개수 & 필요 개수 Check

        if instance_needed <= 0:
            print("Instance {} 가 기준치보다 많아 스킵, 다음 iteration 진행.".format(instance_selected)) #이건 총 두번 필요함. 이미지 전체를 훑기전에 한번, 훑으면서도 한번 계속 체크 필요.
        else:
            # 이 else문에 처리하는 코드 작성
            print("Instance {} 가 {}개 모자람. 이미지 추가 작업 진행.".format(instance_selected, instance_needed))
            for i in range(folder_number): #folder_number = 2480으로 선언된 상태
                xml_name = location_win     +    image_Bbox    +   str(i+1).zfill(4)    + "/*.xml"
                img_dir = location_win + image_Bbox    +   str(i+1).zfill(4) + "/"
                label_dir = location_win + label_Bbox + str(i + 1).zfill(4) + "/"
                xml_list = glob.glob(xml_name)

                #image 찾아서 넣는 작업 진행.
                if len(xml_list) != 0:
                    find_Bbox(xml_list, instance_selected, img_dir, label_dir)

                instance_number_mid = Class_num[instance_selected]
                instance_needed_mid = Threshold - instance_number_mid

                if instance_needed_mid <= 0:
                    print("Bbox_{} 에서 Instance 채우기 완료. 다음 Iteration 진행.".format(str(i+1).zfill(4)))
                    break

#위 부분 너무 더러우니까 image 한개 입력으로 주면 Bounding_box 출력해주는 함수 만들면?
def normalization(center_x, center_y,width,height,img_width,img_height):

    center_x = round(center_x / img_width, 6)
    center_y = round(center_y / img_height, 6)
    width = round(width / img_width, 6)
    height = round(height / img_height, 6)

    return [center_x,center_y,width,height]

def find_Bbox(xml_list, instance_selected, img_dir, label_dir):
    tree = ET.parse(xml_list[0])  # xml_list[0] 에는 xml 주소가 적혀있음.
    root = tree.getroot()
    # print("주소 : ",xml_list[0])

    for image in root.findall('image'):
        # Image 이름 불러오기
        image_fullname = image.attrib['name']
        image_name, ext = os.path.splitext(image_fullname)
        # print("파일 이름 : ", image_name, ", ext : ",ext)

        if image_fullname not in used_img and os.path.isfile(img_dir + image_fullname):
            temp_box_attrib_for_img = []

            for box in image.findall('box'):
                temp_box_attrib_for_img.append(box.attrib['label'])
            #검사를 위해 이미지에 있는 모든 Bounding Box를 가져와서 배열에 저장함.

            if instance_selected in temp_box_attrib_for_img:

                used_img.append(image_fullname) #이미지 사용하기로 했으므로 append!

                for box in image.findall('box'):
                    Class_num[box.attrib['label']] += 1
                    ''' 선택된 instance가 이미지에 있는 경우에만 그 이미지를 선택하고 Bounding Box 값을 모두 업데이트 한 뒤에 이미지 옮기고 라벨 생성해주기.'''
                selected_img = img_dir + image_fullname # selected_img는 이미지 확장자까지 포함한 주소임
                selected_label = label_dir + image_name + '.txt' #image_name은 확장자 없는 이미지 이름, image_fullname은 확장자 있는 이미지 이름임.

                print(selected_img)
                print(selected_label)

                shutil.move(selected_img, new_location_win + "images/")
                shutil.move(selected_label, new_location_win + "labels/")

if __name__ == '__main__':
    Progress(ORDER, INSTANCE_THRESHOLD)
    print("사용된 이미지 : ", used_img)
    print("중복값이 존재하는지 : {}".format(False if len(set(used_img)) == len(used_img) else True))
    print("사용된 이미지 수 : ",len(used_img))
    print("Class num : ",Class_num)
    f_log =open(log_dir_win, 'w')

    f_log.write("------------------------DATA_EQUAL_SAMPLING_LOG------------------------\n")
    f_log.write("\n사용된 이미지 배열(옮긴 순서대로) : {}".format(used_img))
    f_log.write("\n중복값이 존재하는지 : {}".format(False if len(set(used_img)) == len(used_img) else True))
    f_log.write("\n사용된 이미지 수 : {}".format(len(used_img)))
    f_log.write("\nClass num : {}".format(Class_num))
    now = datetime.now()
    f_log.write("\n완료된 시간 : {}".format(now))
    f_log.close()

#테스트 해봄
#최초 경로에 있는(Test 폴더) 내용 : 파일 1,109, 폴더 8
#업데이트 후 기존 경로에 있는 (Test 폴더) 내용 : 파일 17, 폴더 8
#업데이트 후 새 경로에 있는(Test2 폴더) 내용 : 파일 1,092, 폴더 2
#Matches!


import os,sys

filename = "zigzag_plt.py"

if len(sys.argv) > 1:
    filename = sys.argv[1]

from Klang import Kl,Klang
Klang.Klang_init()

from threading import Thread

def th_task(code):
    os.system('python3  ' + filename + " " + code + " 0")

def do_task(tasklist):
    for stock in tasklist:
        new_thread = Thread(target=th_task,args=(stock["code"],))
        new_thread.start()
    new_thread.join() #等待最后一个结束

count = 12
for index in range(0,len(Kl.stocklist),count):
    do_task(Kl.stocklist[index:index+count])


import pytest
from mc.ut.database import DBA
import os.path
import copy

first_collect_name = 'first-collection'
other_collect_name = 'other-collection'
mock_doc_first = ['a', 'b', 'c']
mock_doc_other = ['e', 'f', 'g']

class DBAMocked(DBA):
    def __init__(self, *args, **kwargs):
        super().__init__(*args,**kwargs)
        self.__data = {
            first_collect_name: {
                'test': mock_doc_first
            },
            other_collect_name: {
                'test': mock_doc_other
            },
            mock_collection: { },
        }
    @property
    def _DBA__collection(self):
        return self.__data[self.collection_name]
    def _DBA__collection_exists(self):
        return self.collection_name in [other_collect_name, first_collect_name, mock_collection]
    def _DBA__collection_update(self, new_collection):
        self.__data[self.collection_name] = new_collection

@pytest.fixture
def mock_collection():
    return '/tmp/temp-collection'

@pytest.fixture
def FakeDB():
    return DBAMocked

@pytest.fixture
def dba(mock_collection):
    return DBA(mock_collection)

@pytest.fixture
def dba_nofile(FakeDB):
    return DBAMocked(mock_collection)

@pytest.fixture
def delete_after(mock_collection):
    yield
    if os.path.exists(mock_collection):
        os.unlink(mock_collection)

@pytest.fixture
def setup_cleanup_collection(dba):
    dba.collection_create()
    yield
    dba.collection_delete()

def test_db_can_create_collection(dba, delete_after, mock_collection):
    dba.collection_create()
    assert os.path.exists(mock_collection)

def test_db_can_delete_collection(dba, delete_after, mock_collection):
    dba.collection_create()
    dba.collection_delete()
    assert os.path.exists(mock_collection) == False

def test_db_cannot_create_collection_twice(dba, delete_after):
    dba.collection_create()
    with pytest.raises(Exception):
        dba.collection_create()

def test_db_cannot_delete_twice(dba, delete_after):
    dba.collection_create()
    dba.collection_delete()
    with pytest.raises(Exception):
        dba.collection_delete()

def test_db_cannot_delete_non_existent_collection(dba, delete_after):
    with pytest.raises(Exception):
        dba.collection_delete()

def test_db_can_autocreate_collection(delete_after, mock_collection):
    dba = DBA(mock_collection, True)
    assert dba.collection_delete() is None

def test_db_allows_multiple_calls_to_same_collection(delete_after, mock_collection):
    dba = DBA(mock_collection, True)
    dba = DBA(mock_collection, True)
    assert dba.collection_delete() is None

def test_db_cannot_create_document_without_collection(dba, delete_after):
    with pytest.raises(Exception):
        dba.document_create()

def test_db_can_create_document(dba_nofile):
    doc_id = dba_nofile.document_create()
    assert doc_id != ''
    assert dba_nofile.document_find(doc_id)

def test_db_can_create_document_with_id_and_data(dba_nofile):
    data = {
        'data': 'data',
        'id': 'abc'
    }
    doc_id = dba_nofile.document_create(data)
    assert doc_id == data['id']
    assert dba_nofile.document_find(doc_id)
    del data['id']
    assert dba_nofile.document_read(doc_id) == data

def test_db_cannot_create_document_with_id_that_exists(dba_nofile):
    data = {
        'id': 'abc'
    }
    doc_id = dba_nofile.document_create(data)
    with pytest.raises(Exception):
        doc_id = dba_nofile.document_create(data)

def test_db_cannot_create_non_object_document(dba_nofile):
    class InvalidDocClass():
        pass
    def invalid_doc_function():
        pass
    with pytest.raises(Exception):
        dba_nofile.document_create('invalid doc - string')
    with pytest.raises(Exception):
        dba_nofile.document_create(['invalid doc - array'])
    with pytest.raises(Exception):
        dba_nofile.document_create(15)
    with pytest.raises(Exception):
        dba_nofile.document_create(None)
    with pytest.raises(Exception):
        dba_nofile.document_create(InvalidDocClass())
    with pytest.raises(Exception):
        dba_nofile.document_create(invalid_doc_function)

def test_db_creating_document_does_not_change_original(dba_nofile):
    data = {
        'id': 'abc',
        'name': 'cde',
    }
    original_data = copy.deepcopy(data)
    dba_nofile.document_create(data)
    assert data == original_data

def test_db_can_check_document_existence(dba_nofile):
    doc_id = dba_nofile.document_create()
    assert dba_nofile.document_find(doc_id)

def test_db_can_read_document(dba_nofile):
    expected_data = {'a': 1}
    doc_id = dba_nofile.document_create(expected_data)
    actual_data = dba_nofile.document_read(doc_id)
    assert actual_data == expected_data

def test_db_cannot_read_non_existing_document(dba_nofile):
    with pytest.raises(Exception):
        doc = dba_nofile.document_read('non-existent id')

def test_db_can_update_document(dba_nofile):
    dba = dba_nofile
    doc_id = dba.document_create()
    doc_expected = {
        'text': 'field',
        'number': 15,
        'object': [{ 'a': 'b' }]
    }
    dba.document_update(doc_id, doc_expected)
    doc_actual = dba.document_read(doc_id)
    assert doc_expected == doc_actual

def test_db_can_delete_document(dba_nofile):
    doc_id = dba_nofile.document_create()
    dba_nofile.document_delete(doc_id)
    assert dba_nofile.document_find(doc_id) == False

def test_db_can_query_collection(dba_nofile):
    items = [
        {
            'field1': 'yes',
            'field2': 'non',
        },
        {
            'field1': 'may',
            'field2': 'non',
        },
        {
            'field1': 'may',
            'field2': 'not',
        },
    ]
    for item in items:
        item_id = dba_nofile.document_create(item)
        item['id'] = item_id
    non_existent_data = dba_nofile.query({'field1': 'value'})
    assert non_existent_data == []
    expected_single_field_result = [items[1], items[2]]
    expected_field = 'field1'
    expected_value = items[1][expected_field]
    actual_data = dba_nofile.query({expected_field: expected_value})
    assert actual_data == expected_single_field_result
    expected_multiple_fields_result = [items[1]]
    actual_data = dba_nofile.query({'field1': items[1]['field1'], 'field2': items[1]['field2']})
    assert actual_data == expected_multiple_fields_result

def test_db_can_change_collection(FakeDB):
    db = FakeDB(first_collect_name)
    assert db.document_read('test') == mock_doc_first
    db.collection_change(other_collect_name)
    assert db.document_read('test') == mock_doc_other


#Filename:q6_determine_prime.py
#Author:PS
#Created:20130221
#Description:determine whether a num is prime
import math

def is_prime(n):
	if(n==1):
		return True
	for i in range(2,int(math.sqrt(n))+1):
		if(n%i==0):
			return False
	return True

c=0
i=2
while c<=1000:
	if(is_prime(i)):
		print(i," ",end="")
		i+=1
		c+=1
		if(c%10==0):
			print("\n",end="")
	else:
		i+=1


import os
import cv2
import glob
import numpy as np
from tqdm.auto import tqdm
import matplotlib.pyplot as plt

def resize_volme(path_loading: str, in_dims: tuple, out_dims: tuple, noise_crop: float):
    with open(path_loading) as f:
        vol = np.fromfile(f, dtype=np.uint8).reshape(in_dims)
    out = np.zeros(out_dims)
    for i in range(vol.shape[-1]):
        out[...,i] = cv2.resize(vol[...,i], (out_dims[1],out_dims[0]))
    # print(out.shape) #debug
    out = out-(noise_crop*out.max())
    out[out<0] = 0
    return out

def save_resized_vol(vol: np.array, path_to_volume: str) -> None:
    dims = vol.shape
    dims_str = str(dims[0]) + 'x' + str(dims[1]) + 'x' + str(dims[2])
    tail, head = os.path.split(path_to_volume)
    tmp = head.split('_')
    tmp = tmp[:-1]
    tmp = ''.join([e + '_' for e in tmp])
    full_path_saving = os.path.join(tail, 'resized', tmp + dims_str + '.bin')
    print(full_path_saving)

def average_volumes_from_list(vol_list: list, dims: tuple) -> np.array:
    out_vol = np.zeros((*dims,len(vol_list)), dtype=np.uint8)
    for i, vol in tqdm(enumerate(vol_list)):
        with open(vol) as f:
            out_vol[...,i] = np.fromfile(f, dtype=np.uint8).reshape(dims)
    return np.mean(out_vol, axis=-1)

def calculate_snr_for_nVols(vol_list: list, dims: tuple) -> np.array:
    snr = []
    out_vol = np.zeros((*dims,len(vol_list)), dtype=np.uint8)
    for i, vol in tqdm(enumerate(vol_list)):
        with open(vol) as f:
            out_vol[...,i] = np.fromfile(f, dtype=np.uint8).reshape(dims)
    return np.mean(out_vol, axis=-1)

if __name__ == '__main__':
    test_path = r"C:\Users\PhilippsLabLaptop\Desktop\20230221_110638_binaries\OctVolume_17_20230221_110638_binaries_644x391x391.bin"
    with open(test_path) as f:
        v = np.fromfile(f, dtype=np.uint8).reshape((644,391,391))


import torch
from kt_module import from_yaml

train_module = from_yaml('config.yaml')

# Encoder outputs (from Wav2Vec)
# B - batch size
# L - max seq len
# H - encoder out dim
B, L, H = 3, 10, 768
encoder_outputs = torch.rand(B, L, H, dtype=torch.float32,
                                      requires_grad=True)
mask = torch.ones(B, L, dtype=torch.bool)  # 0 value means invalid

target_sentences = [
    'привет как дела',
    'что нового',
    'давай пока'
]
assert B == len(target_sentences)

losses = train_module(encoder_outputs, mask, target_sentences)
# loss = ctc_loss + [weighted sum of these losses]
# (see eq.4 and eq.7 in paper)
print(losses)

# loss.backward()


def is_isogram(string):
    letters = dict()
    # Check each letter in the string
    for letter in string:
        if letter.isalpha():
            letters[letter.lower()] = letters.get(letter.lower(), 0) + 1
    # Check if there is one copy of each letter.
    for count in letters.values():
        if count > 1:
            return False
    return True


# Use: Check setting and getting an Attribute on a problem object

from __future__ import print_function

# Import pyCAPS module (Linux and OSx = pyCAPS.so file; Windows = pyCAPS.pyd file)
import pyCAPS

# Instantiate our CAPS problem "myProblem"
myProblem = pyCAPS.capsProblem()

# Load a *.csm file "./csmData/cfdMultiBody.csm" into our newly created problem.
myGeometry = myProblem.loadCAPS("./csmData/cfdMultiBody.csm", verbosity = "debug")

# Add attribute
myProblem.addAttribute("testAttr", [1, 2, 3])

# Add another attribute
myProblem.addAttribute("testAttr_2", "anotherAttribute")

myValue = myProblem.getAttribute("testAttr")
print("Value = ",  myValue)

myValue = myProblem.getAttribute("testAttr_2")
print("Value = ",  myValue)

# Close our problems
myProblem.closeCAPS()


import random
import os
from os import listdir
from os.path import isfile, join

def makedir(dir):
	if not os.path.exists(dir):
		os.makedirs(dir)

def createCorpusFor(task, istrain, dataset):
	if istrain:
		t = 'trainset'
	else:
		t = 'testset'
	path = t + '/' + task
	makedir(path)
	for opinion_data in dataset:
		clase = opinion_data[task]
		makedir(path + '/' + clase)

		op_path = opinion_data['opinion']
		op = open(op_path, 'r')
		filename = op_path.split('/')[-1]
		f = open(path + '/' + clase + '/' + filename, 'w')
		for l in op.readlines():
			f.write(l)
		f.close()
		op.close()

if __name__ == '__main__':

	#leer las opiniones
	opiniones = {"Deportes" : {}, "Electro" : {}, "Juegos" : {}, "Peliculas" : {}, "Vehiculos" : {},
	"Hoteles" : {}, "Libros" : {}}

	for dominio in opiniones.keys():
		path = "/home/cristian/Escritorio/experimentos/mallet-2.0.7/data/corpus_original/" +  dominio + "Ciao/Negative"
		negativas = [join(path, f) for f in listdir(path) if isfile(join(path, f))]
		path = "/home/cristian/Escritorio/experimentos/mallet-2.0.7/data/corpus_original/" +  dominio + "Ciao/Positive"
		positivas = [join(path, f) for f in listdir(path) if isfile(join(path, f))]

		opiniones[dominio] = {'positivo' : positivas, 'negativo' : negativas}

	#crear una lista de elementos que contengan dominio, sentimiento y la opinion.
	listaOpiniones = []
	for dominio in opiniones.keys():
		for sentimiento in opiniones[dominio].keys():
			for opinion in opiniones[dominio][sentimiento]:
				listaOpiniones.append({'dominio': dominio, 'sentimiento': sentimiento, 'opinion': opinion})

	#seleccionar las opiniones de training y testing
	random.shuffle(listaOpiniones)
	n = len(listaOpiniones)
	splitIndex = int(n * 0.7)
	trainset = listaOpiniones[0:splitIndex]
	testset = listaOpiniones[splitIndex:]

	#crear un corpus de entrenamiento que tenga solo positivo y negativo.

	createCorpusFor('sentimiento', True, trainset)

	#crear un corpus de entrenamiento con los dominios.

	createCorpusFor('dominio', True, trainset)

	#crear un corpus de entrenamiento por cada dominio.

	path = 'trainset/dominio_sentimiento'
	makedir(path)
	for opinion_data in trainset:
		dominio = opinion_data['dominio']
		sentimiento = opinion_data['sentimiento']
		makedir(path + '/' + dominio)

		op_path = opinion_data['opinion']
		op = open(op_path, 'r')
		filename = op_path.split('/')[-1]
		makedir(path + '/' + dominio + '/' + sentimiento)
		f = open(path + '/' + dominio + '/' + sentimiento + '/' + filename, 'w')
		for l in op.readlines():
			f.write(l)
		f.close()
		op.close()

	#crear un corpus de testing que solo tenga positivo y negativo

	createCorpusFor('sentimiento', False, testset)

	#crear un corpus de testing con los dominios.

	createCorpusFor('dominio', False, testset)

	#crear un corpus de testing por cada dominio

	path = 'testset/dominio_sentimiento'
	makedir(path)
	for opinion_data in testset:
		dominio = opinion_data['dominio']
		sentimiento = opinion_data['sentimiento']
		makedir(path + '/' + dominio)

		op_path = opinion_data['opinion']
		op = open(op_path, 'r')
		filename = op_path.split('/')[-1]
		makedir(path + '/' + dominio + '/' + sentimiento)
		f = open(path + '/' + dominio + '/' + sentimiento + '/' + filename, 'w')
		for l in op.readlines():
			f.write(l)
		f.close()
		op.close()


from bonus.converters14 import convert
from bonus.parsers import parse

feet_inches = input("Enter feet as inches: ")

feet_inches = input("Enter feet as inches: ")

parsed = parse(feet_inches)
result = convert(parsed["feet"], parsed["inches"])  # Use parsed["feet"] and parsed["inches"] to access the values.
print(f"{parsed['feet']} feet and {parsed['inches']} inches is equal to {result} meters")

if result < 1:
    print("you are too small")
else:
    print("You can use slide")


import json
import time
from collections import namedtuple
from src.utils.file_utils import read_file, write_file

Report = namedtuple('Report', 'captcha_count rejected_captcha_count spent balance '
                              'page_updates current_state uptime avg_captcha_count '
                              'avg_day_cost')

class StatData:
    def __init__(self, path='stat.txt'):
        j = json.loads(read_file(path))
        self.total_captcha_count = j.get('total_captcha_count')
        self.uptime_captcha_count = j.get('uptime_captcha_count')
        self.rejected = j.get('rejected')
        self.spent = j.get('spent')
        self.uptime_spent = j.get('uptime_spent')
        self.balance = j.get('balance')
        self.page_updates = j.get('page_updates')
        self.current_state = j.get('current_state')
        self.uptime_start = j.get('uptime_start')
        self.uptime = j.get('uptime')
        self.uptime_end = j.get('uptime_end')
        self.avg_captcha_count = j.get('avg_captcha_count')
        self.avg_day_cost = j.get('avg_day_cost')

    def save_stat(self, path):
        write_file(path, json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4))

    def get_report(self) -> Report:
        if self.current_state:
            self.current_state = "Up"
            self.uptime = round(time.time()) - self.uptime_start
        else:
            self.current_state = "Down"

        report = Report(
            self.total_captcha_count,
            self.rejected,
            self.spent,
            self.balance,
            self.page_updates,
            self.current_state,
            self.uptime,
            self.avg_captcha_count,
            self.avg_day_cost
        )
        return report


import argparse
import torch.cuda
from easydict import EasyDict
from src.utils.utils import HyperParamDict

EXP_HYPER_LIST = {'Data': {'dataset': None, 'data_aug': None, 'seq_filter_len': None,
                           'if_filter_target': None, 'max_len': None},
                  'Pretraining': {'do_pretraining': None, 'pretraining_task': None, 'pretraining_epoch': None,
                                  'pretraining_batch': None, 'pretraining_lr': None, 'pretraining_l2': None},
                  'Training': {'epoch_num': None, 'train_batch': None,
                               'learning_rate': None, 'l2': None, 'patience': None,
                               'device': None, 'num_worker': None, 'seed': None, 'SR_task': None, 'session_len': None},
                  'Evaluation': {'split_type': None, 'split_mode': None, 'eval_mode': None, 'metric': None, 'k': None,
                                 'valid_metric': None, 'eval_batch': None},
                  'Save': {'log_save': None, 'save': None, 'model_saved': None}}

def experiment_hyper_load(exp_config):
    hyper_types = EXP_HYPER_LIST.keys()
    for hyper_dict in EXP_HYPER_LIST.values():
        for hyper in hyper_dict.keys():
            hyper_dict[hyper] = getattr(exp_config, hyper)
    return list(hyper_types), EXP_HYPER_LIST

def get_device():
    return 'cuda:0' if torch.cuda.is_available() else 'cpu'

def get_default_config():
    parser = HyperParamDict()
    # Model
    parser.add_argument('--model', default='URCL4SRec')
    # Data
    parser.add_argument('--dataset', default='toys', type=str,
                        choices=['home', 'grocery', 'grocery', 'yelp_s3', 'toys'])
    parser.add_argument('--data_aug', action='store_false', help='data augmentation')
    parser.add_argument('--seq_filter_len', default=0, type=int, help='filter seq less than 3')
    parser.add_argument('--if_filter_target', action='store_true',
                        help='if filter target appearing in previous sequence')
    parser.add_argument('--separator', default=' ', type=str, help='separator to split item sequence')
    parser.add_argument('--graph_type', default='None', type=str, help='do not use graph',
                        choices=['None', 'BIPARTITE', 'TRANSITION'])
    parser.add_argument('--max_len', default=50, type=int, help='max sequence length')
    parser.add_argument('--kg_data_type', default='pretrain', type=str, choices=['pretrain', 'jointly_train', 'other'])
    # Pretraining
    parser.add_argument('--do_pretraining', default=False, action='store_true')
    parser.add_argument('--pretraining_task', default='MISP', type=str, choices=['MISP', 'MIM', 'PID'],
                        help='pretraining task:' \
                             'MISP: Mask Item Prediction and Mask Segment Prediction' \
                             'MIM: Mutual Information Maximization' \
                             'PID: Pseudo Item Discrimination'
                        )
    parser.add_argument('--pretraining_epoch', default=10, type=int)
    parser.add_argument('--pretraining_batch', default=512, type=int)
    parser.add_argument('--pretraining_lr', default=1e-3, type=float)
    parser.add_argument('--pretraining_l2', default=0., type=float, help='l2 normalization')
    # Training
    parser.add_argument('--epoch_num', default=200, type=int)
    parser.add_argument('--SR_task', default='Next-Item', type=str, choices=['Next-Item', 'Next-Session'])
    parser.add_argument('--session_len', default=3, type=int, help='next session length')
    parser.add_argument('--seed', default=-1, type=int, help="random seed, only -1 means don't set random seed")
    parser.add_argument('--train_batch', default=256, type=int)
    parser.add_argument('--learning_rate', default=1e-3, type=float)
    parser.add_argument('--l2', default=0., type=float, help='l2 normalization')
    parser.add_argument('--patience', default=5, type=int, help='early stop patience')
    parser.add_argument('--device', default=get_device(), choices=['cuda:0', 'cpu'],
                        help='training on gpu or cpu, default gpu')
    parser.add_argument('--num_worker', default=0, type=int,
                        help='num_workers for dataloader, best: 6')
    parser.add_argument('--mark', default='', type=str,
                        help='mark of this run which will be added to the name of the log')

    # Evaluation
    parser.add_argument('--split_type', default='valid_and_test', choices=['valid_only', 'valid_and_test'])
    parser.add_argument('--split_mode', default='LS', type=str,
                        help='LS: Leave-one-out splitting.'
                             'LS_R@0.2: use LS and a ratio 0.x of test data for validate if use valid_and_test.'
                             'PS: Pre-Splitting, prepare xx.train and xx.eval, also xx.test if use valid_and_test')
    parser.add_argument('--eval_mode', default='full', help='[uni100, uni200, full]')
    parser.add_argument('--metric', default=['hit', 'ndcg'], help='[hit, ndcg, mrr, recall]')
    parser.add_argument('--k', default=[5, 10], help='top k for each metric')
    parser.add_argument('--valid_metric', default='hit@10', help='specifies which indicator to apply early stop')
    parser.add_argument('--eval_batch', default=256, type=int)

    # save
    parser.add_argument('--log_save', default='log', type=str, help='log saving path')
    parser.add_argument('--save', default='save', type=str, help='model saving path')
    parser.add_argument('--model_saved', default=None, type=str)

    return parser

def config_override(model_config, cmd_config):
    default_config = get_default_config()
    command_args = set([arg for arg in vars(cmd_config)])
    # overwrite model config by cmd config
    for arg in vars(model_config):
        if arg in command_args:
            setattr(model_config, arg, getattr(cmd_config, arg))

    # overwrite default config by cmd config
    for arg in vars(default_config):
        if arg in command_args:
            setattr(default_config, arg, getattr(cmd_config, arg))

    # overwrite default config by model config
    for arg in vars(model_config):
        setattr(default_config, arg, getattr(model_config, arg))

    return default_config


#!/usr/bin/env python
# -*- coding: utf-8 -*-
import argparse
import os
import sys
#import imp
import glob
import numpy
from shutil import copyfile

parser = argparse.ArgumentParser(
    description='schedules climada runs for different parameter combinations')
# parser.add_argument(
#     '--parameters', type=str, default="parameters.py",
#     help='parameters file')
parser.add_argument(
    '--dry', action="store_true",
    help='dry run (do not run Climada)')
parser.add_argument(
    '--shared', action="store_true",
    help='share nodes on cluster')
parser.add_argument(
    '--notify', action="store_true",
    help='notify per mail when done')
parser.add_argument(
    '--minutes', type=int, default=0,
    help='maximal minutes to run on cluster (< 60)')
parser.add_argument(
    '--hours', type=int, default=24,
    help='maximal hours to run on cluster (168=week, 720=month)')
parser.add_argument(
    '--threads', type=int, default=16,
    help='maximal number of threads on cluster (<= 16)')
parser.add_argument(
    '--mem_per_cpu', type=int, default=3584,
    help='number of memory per CPU (3584 is MaxMemPerCPU on cluster)')
parser.add_argument(
    '--largemem', action="store_true",
    help='use ram_gpu partition')
parser.add_argument(
    '--verbose', action="store_true",
    help='be verbose')

args = parser.parse_args()

indices = []
sys.dont_write_bytecode = True

# Definition of the four forcing data sets

CL_MODEL = [#'gfdl-esm2m',
            #'hadgem2-es',
            #'ipsl-cm5a-lr',
            #'miroc5'
            'princeton',
            'gswp3',
            'watch',
            'wfdei'
            ]

# Definition of the GHMS

RF_MODEL = [
            'clm40',
            'matsiro',
            'jules-w1',
            'jules-b1',
            'orchidee',
            'vic',
            'dbh',
            'h08',
            'mpi-hm',
            'pcr-globwb',
            'watergap2',
           'lpjml']

def schedule_run(run_nb,flag,RF_model,CL_model, Socmode, SM_mode):
    if not flag:
        run_label = "run%s" % run_nb
        if os.path.exists(run_label):
        #    run_id += 1
            return
        os.mkdir(run_label)
 #       desc = run_description()
 #       f = open("%s/parameters.txt" % run_label, 'w')
 #       f.write(desc)
 #       f.close()
 #       run_index.write(run_description_csv(run_label))
 #       run_index.write("\n")
        # with open("%s/settings.yml" % run_label, 'w') as f:
        #     f.write(pyaml.dump(settings_yml))
        #     for nc in glob.glob('*.nc'):
        #         copyfile(nc,"%s/%s" % (run_label,nc))
        #run_id += 1
    else:
        run_label = "."
    if args.dry:
        return
    else:
        if (int(args.hours) <= 24):
            _class = "short"
        elif (int(args.hours) <= 24 * 7):
            _class = "medium"
        else:
            _class = "long"

        run_params = {
            "job_name": "%s/%s" % (os.path.basename(os.getcwd()), run_label),
            "minutes": args.minutes,
            "hours": args.hours,
            "class": _class,
            "initialdir": run_label,
            "node_usage": "share" if args.shared else "exclusive",
            "notification": "END,FAIL,TIME_LIMIT" if args.notify else "FAIL,TIME_LIMIT",
            "comment": "%s/%s" % (os.getcwd(), run_label),
            "environment": "ALL",
            "executable": 'schedule_sim.py',
            "options": "--RF_model %s --CL_model %s --Socmode %s --SM_mode %s"%(RF_model, CL_model, Socmode, SM_mode),
            "num_threads": args.threads,
            "mem_per_cpu": args.mem_per_cpu if not args.largemem else 15360,   # if mem_per_cpu is larger than MaxMemPerCPU then num_threads is reduced
            "other": "#SBATCH --partition=ram_gpu" if args.largemem else ""
        }

        cmd = """echo "#!/bin/sh
#SBATCH --job-name=\\\"%(job_name)s\\\"
#SBATCH --comment=\\\"%(comment)s\\\"
#SBATCH --time=%(hours)02d:%(minutes)02d:00
#SBATCH --qos=%(class)s
#SBATCH --output=output.txt
#SBATCH --error=errors.txt
#SBATCH --export=%(environment)s
#SBATCH --mail-type=%(notification)s
#SBATCH --%(node_usage)s
#SBATCH --account=ebm
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=%(num_threads)1d
#SBATCH --mem-per-cpu=%(mem_per_cpu)1d
#SBATCH --workdir=%(initialdir)s
%(other)s
export OMP_PROC_BIND=true
export OMP_NUM_THREADS=%(num_threads)1d
source activate climada_env
ulimit -c unlimited
%(executable)s %(options)s
" | sbatch -Q""" % run_params

        if args.verbose:
            print(cmd)

        os.system(cmd)
        #run_cnt += 1

num = 1
num *= len(RF_MODEL)
num *= len(CL_MODEL)

single = True if num == 1 else False
if num > 1:
    print("Number of runs to be scheduled: %s" % num)
    sys.stdout.write('Run? y/N : ')
    if sys.version_info >= (3, 0):
        if input() != "y":
            exit("Aborted")
    else:
        if raw_input() != "y":
            exit("Aborted")

enum = 1
for rf_model in RF_MODEL:
    for cl_model in CL_MODEL:
        schedule_run(run_nb=enum,flag=single,RF_model=rf_model,CL_model=cl_model, Socmode = 'nosoc', SM_mode ='geo')
        enum += 1
if num > 1:
    print("Scheduled %s runs" % num)

# def set_in_yml(paths, value):
#     global yml_nodes
#     for p in paths:
#         node = yml_nodes
#         nodes = p.split(".")
#         for n in nodes[:-1]:
#             try:
#                 n = int(n)
#             except ValueError:
#                 if not n in node:
#                     exit("Path '%s' not found!" % p)
#             node = node[n]
#         n = nodes[-1]
#         if not n in node:
#             exit("Path '%s' not found!" % p)
#         node[n] = value

# def next_step():
#     for i, ind in enumerate(indices):
#         indices[i] += 1
#         if indices[i] < len(parameters[i]["values"]):
#             set_in_yml(
#                 parameters[i]["paths"], parameters[i]["values"][indices[i]])
#             return True
#         else:
#             indices[i] = 0
#             set_in_yml(
#                 parameters[i]["paths"], parameters[i]["values"][indices[i]])

# if os.path.exists(args.parameters):
#     parameters = imp.load_source("parameters", args.parameters).parameters
#     single = False
# else:
#     single = True
# run_cnt = 0
# def run_description():
#     res = ""
#     for i, ind in enumerate(indices):
#         res += "%s = %s\n" % (parameters[i]
#                               ["name"], parameters[i]["values"][ind])
#     return res

# def run_description_csv(run_label):
#     res = "\"%s\"" % run_label
#     for i, ind in enumerate(indices):
#         res += ",\"%s\"" % parameters[i]["values"][ind]
#     return res


#!/usr/bin/env python

# Determine the size relationships between the various intermediate languages (ILs)
# by analyzing all the busybox binaries in BinaryNinja.

import os
import sys
import binaryninja

# How they print differently
#
# function.Function                         like "int64_t _init()"
# lowlevelil.LowLevelILFunction             like "<llil func: x86_64@0x4000e8>"
# mediumlevelil.MediumLevelILFunction       like "<mlil func: x86_64@0x4000e8>"
# highlevelil.HighLevelILFunction           the whole function including its instructions

# (Pdb) func
# <func: x86_64@0x4000e8>
# (Pdb) print(func)
# int64_t _init()
# (Pdb) print(func.lifted_il)
# <llil func: x86_64@0x4000e8>
# (Pdb) print(func.low_level_il)
# <llil func: x86_64@0x4000e8>
# (Pdb) print(func.low_level_il.ssa_form)
# <llil func: x86_64@0x4000e8>
# (Pdb) print(func.medium_level_il)
# <mlil func: x86_64@0x4000e8>
# (Pdb) print(func.medium_level_il.ssa_form)
# <mlil func: x86_64@0x4000e8>
# (Pdb) print(func.high_level_il)
# sub_400150()
# return sub_400960()
# (Pdb) print(func.high_level_il.ssa_form)
# sub_400150() @ mem#0 -> mem#1
# return sub_400960() @ mem#1 -> mem#2

# How to get the various levels
#
#  type                                            how
#  ----                                            --------------
#  binaryninja.function.Function                   bv.get_function_at(0x100000f50)
#  binaryninja.lowlevelil.LowLevelILFunction       func.lifted_il
#                                                  func.low_level_il
#                                                  func.low_level_il.ssa_form
#  binaryninja.mediumlevelil.MediumLevelILFunction func.medium_level_il
#                                                  func.medium_level_il.ssa_form
#  binaryninja.highlevelil.HighLevelILFunction     func.high_level_il
#                                                  func.high_level_il.ssa_form

def counti(func):
    return sum([b.instruction_count for b in func])

def countb(func):
    return len(func.basic_blocks)

class relation(object):
    def __init__(self, description):
        self.description = description
        self.lt = True # <
        self.le = True # <=
        self.eq = True # ==
        self.ge = True # >=
        self.gt = True # >

    def consume(self, func_a, func_b, a, b):
        if self.lt and a >= b:
            print(f'({self.description}) < disproved, counterexample: {repr(func_a)} has {a} >= {b}')
            self.lt = False
        if self.le and a > b:
            print(f'({self.description}) <= disproved, counterexample: {repr(func_a)} has {a} > {b}')
            self.le = False
        if self.eq and a != b:
            print(f'({self.description}) == disproved, counterexample: {repr(func_a)} has {a} != {b}')
            self.eq = False
        if self.ge and a < b:
            print(f'({self.description}) >= disproved, counterexample: {repr(func_a)} has {a} < {b}')
            self.ge = False
        if self.gt and a <= b:
            print(f'({self.description}) > disproved, counterexample: {repr(func_a)} has {a} <= {b}')
            self.gt = False

    def count_instrs(self, func_a, func_b):
        a,b = counti(func_a), counti(func_b)
        self.consume(func_a, func_b, a, b)

    def count_blocks(self, func_a, func_b):
        a,b = countb(func_a), countb(func_b)
        self.consume(func_a, func_b, a, b)

    def report(self):
        print(f'{self.description} REPORT:')
        if self.lt: print(f' <  holds')
        if self.le: print(f' <= holds')
        if self.eq: print(f' == holds')
        if self.ge: print(f' >= holds')
        if self.gt: print(f' >  holds')

files = []
if sys.argv[1:]:
    files = [sys.argv[1]]
else:
    import glob
    #files = glob.glob('~/fdumps/filesamples/busybox-*')
    files = glob.glob('/Users/andrewl/fdumps/filesamples/busybox-*')
    # keep files without extensions
    files = [f for f in files if os.path.splitext(f)[1] == '']

r0 = relation('asm vs. lifted instructions')
r0_b = relation('asm vs. lifted blocks')
r1 = relation('lifted vs. low instructions')
r1_b = relation('lifted vs. low blocks')
r2 = relation('low vs. low ssa instructions')
r2_b = relation('low vs. low ssa blocks')
r3 = relation('low vs. medium instructions')
r3_b = relation('low vs. medium blocks')
r4 = relation('medium vs. medium ssa instructions')
r4_b = relation('medium vs. medium ssa blocks')
r5 = relation('medium vs. high instructions')
r5_b = relation('medium vs. high blocks')
r6 = relation('high vs. high ssa instructions')
r6_b = relation('high vs. high ssa blocks')

for file in files:
    if '-m68k' in file or '-sparc' in file or '-sh4' in file:
        print(f'skipping: {file}')
        continue

    print(f'opening: {file}')
    bv = binaryninja.open_view(file)
    assert bv

    for func in bv.functions:
        # asm -> lifted
        r0.count_instrs(func, func.lifted_il)
        r0_b.count_blocks(func, func.lifted_il)

        # lifted -> low
        # low -> low ssa
        r1.count_instrs(func.lifted_il, func.low_level_il)
        r1_b.count_blocks(func.lifted_il, func.low_level_il)
        r2.count_instrs(func.low_level_il, func.low_level_il.ssa_form)
        r2_b.count_blocks(func.low_level_il, func.low_level_il.ssa_form)

        # low -> medium
        # medium -> medium ssa
        r3.count_instrs(func.low_level_il, func.medium_level_il)
        r3_b.count_blocks(func.low_level_il, func.medium_level_il)
        r4.count_instrs(func.medium_level_il, func.medium_level_il.ssa_form)
        r4_b.count_blocks(func.medium_level_il, func.medium_level_il.ssa_form)

        # medium -> high
        # high -> high ssa
        r5.count_instrs(func.medium_level_il, func.high_level_il)
        r5_b.count_blocks(func.medium_level_il, func.high_level_il)
        r6.count_instrs(func.high_level_il, func.high_level_il.ssa_form)
        r6_b.count_blocks(func.high_level_il, func.high_level_il.ssa_form)

print('--------')

print('for all these files:')
print('\n'.join(files))

print('--------')

for r in [r0, r1, r2, r3, r4, r5, r6]:
    r.report()

print('--------')

for r in [r0_b, r1_b, r2_b, r3_b, r4_b, r5_b, r6_b]:
    r.report()


#!/usr/bin/python3

import time
start = time.time()
# time.sleep(2)

import apex
# import cv2

# import math
# import numpy as np
# import os
# import pdb
# import random

# from taxonomy.utils_flat import *

# end = time.time()
# print(end - start)

"""
TODO: GET THE MODELS TRAINING, THEN GO BACK LATER AND WRITE THE
UNIT TESTS FOR TAXONOMY CONVERTER

Should have fixed ratios --> then experiment with it.

Train w/ MGDA
Train w/o MGDA.
Get results on the training set as well.

Submit the jobs first -- for all training/test sets.

fix the max_iters -- 1.2 Million examples

make sure we have the right flags to evaluate on the train dataset.
"""

"""
NVIDIA Apex has 4 optimization levels:

    O0 (FP32 training): basically a no-op. Everything is FP32 just as before.
    O1 (Conservative Mixed Precision): only some whitelist ops are done in FP16.
    O2 (Fast Mixed Precision): this is the standard mixed precision training.
        It maintains FP32 master weights and optimizer.step acts directly on the FP32 master weights.
    O3 (FP16 training): full FP16. Passing keep_batchnorm_fp32=True can speed
        things up as cudnn batchnorm is faster anyway.
"""

class ToFlatLabel(object):
    def __init__(self, tc_init, dataset):
        self.dataset = dataset
        self.tc = tc_init

    def __call__(self, image, label):
        return image, self.tc.transform_label(label, self.dataset)

# cv2.ocl.setUseOpenCL(False)
# cv2.setNumThreads(0)

def get_parser():
    import argparse
    from util import config

    parser = argparse.ArgumentParser(description='PyTorch Semantic Segmentation')
    parser.add_argument('--config', type=str, default='config/ade20k/ade20k_pspnet50.yaml', help='config file')
    parser.add_argument('opts', help='see config/ade20k/ade20k_pspnet50.yaml for all options', default=None, nargs=argparse.REMAINDER)
    args = parser.parse_args()
    assert args.config is not None
    cfg = config.load_cfg_from_cfg_file(args.config)
    if args.opts is not None:
        cfg = config.merge_cfg_from_list(cfg, args.opts)
    return cfg

def get_logger():
    import logging
    logger_name = "main-logger"
    logger = logging.getLogger(logger_name)
    logger.setLevel(logging.INFO)
    handler = logging.StreamHandler()
    fmt = "[%(asctime)s %(levelname)s %(filename)s line %(lineno)d %(process)d] %(message)s"
    handler.setFormatter(logging.Formatter(fmt))
    logger.addHandler(handler)
    return logger

def worker_init_fn(worker_id):
    import random
    random.seed(args.manual_seed + worker_id)

def main_process():
    return not args.multiprocessing_distributed or (args.multiprocessing_distributed and args.rank % args.ngpus_per_node == 0)

def main():
    """
    """
    # with open('test_2.txt', 'a') as f:
    #     f.write('test')
    #     f.close()
    import torch, os, math
    import torch.backends.cudnn as cudnn
    import torch.nn as nn
    import torch.nn.functional as F
    import torch.nn.parallel
    import torch.optim
    import torch.utils.data

    import torch.multiprocessing as mp
    import torch.distributed as dist
# from tensorboardX import SummaryWriter
    from util.dataset_config import infos

    from util import config
    from util.verification_utils import verify_architecture
    from util.avg_meter import AverageMeter, SegmentationAverageMeter
    from taxonomy.utils_flat import TaxonomyConverter
    from taxonomy.utils_baseline import StupidTaxonomyConverter
    import pickle

    print('Using PyTorch version: ', torch.__version__)
    args = get_parser()
    os.environ["CUDA_VISIBLE_DEVICES"] = ','.join(str(x) for x in args.train_gpu)

    ###### FLAT-MIX CODE #######################
    print(os.environ["CUDA_VISIBLE_DEVICES"])

    # Randomize args.dist_url too avoid conflicts on same machine
    args.dist_url = args.dist_url[:-2] + str(os.getpid() % 100).zfill(2)

    from util.dataset_config import infos

    if args.use_multiple_datasets and args.universal: # multiple datasets training, must be on universal taxononmy
        if args.tax_version == 0:
            args.tc = StupidTaxonomyConverter(version=args.tax_version)
        else:
            if args.finetune:
                args.tc = TaxonomyConverter(version=args.tax_version, finetune=True, finetune_dataset=args.finetune_dataset)
            else:
                args.tc = TaxonomyConverter(version=args.tax_version) #, train_datasets=args.dataset, test_datasets=args.test_dataset) #, train_datasets=args.dataset, test_datasets=args.test_dataset)

        args.data_root = {dataset:infos[dataset].dataroot for dataset in args.dataset}
        args.train_list = {dataset:infos[dataset].trainlist for dataset in args.dataset}
        args.classes = args.tc.classes
        # args.save_path = args.save_path.replace("{}", '-'.join([infos[dataset].shortname for dataset in args.dataset]))

    elif (not args.use_multiple_datasets) and args.universal: # single dataset on universal taxonomy training
        args.tc = TaxonomyConverter(version=args.tax_version, train_datasets=[args.dataset], test_datasets=args.test_dataset)
        args.data_root = infos[args.dataset].dataroot
        args.train_list = infos[args.dataset].trainlist
        args.classes = args.tc.classes
        # args.save_path = args.save_path.replace("{}", info[args.dataset].shortname)

    elif (not args.use_multiple_datasets) and (not args.universal): # single dataset on self taxnonmy training
        args.data_root = infos[args.dataset].dataroot
        args.train_list = infos[args.dataset].trainlist
        args.classes = infos[args.dataset].num_classes
        # args.save_path = args.save_path.replace("{}", infos[args.dataset].shortname)
    else:
        print('wrong mode, please check')
        exit()

    # verify arch after args.classes is populated
    verify_architecture(args)

    if args.manual_seed is not None:
        cudnn.benchmark = False
        cudnn.deterministic = True
        torch.manual_seed(args.manual_seed)
        np.random.seed(args.manual_seed)
        torch.manual_seed(args.manual_seed)
        torch.cuda.manual_seed_all(args.manual_seed)
    if args.dist_url == "env://" and args.world_size == -1:
        args.world_size = int(os.environ["WORLD_SIZE"])
    args.distributed = args.world_size > 1 or args.multiprocessing_distributed
    args.ngpus_per_node = len(args.train_gpu)
    if len(args.train_gpu) == 1:
        args.sync_bn = False
        args.distributed = False
        args.multiprocessing_distributed = False
    if args.multiprocessing_distributed:
        args.world_size = args.ngpus_per_node * args.world_size
        mp.spawn(main_worker, nprocs=args.ngpus_per_node, args=(args.ngpus_per_node, args))
    else:
        main_worker(args.train_gpu, args.ngpus_per_node, args)

def get_train_transform_list(args, split, dataset_name):
    """
        Args:
        -   args:
        -   split

        Return:
        -   List of transforms
    """
    from util.normalization_utils import get_imagenet_mean_std
    from util import transform

    mean, std = get_imagenet_mean_std()
    if split == 'train':
        transform_list = [
            transform.RandScale([args.scale_min, args.scale_max]),
            transform.RandRotate([args.rotate_min, args.rotate_max], padding=mean, ignore_label=args.ignore_label),
            transform.RandomGaussianBlur(),
            transform.RandomHorizontalFlip(),
            transform.Crop([args.train_h, args.train_w], crop_type='rand', padding=mean, ignore_label=args.ignore_label),
            transform.ToTensor(),
            transform.Normalize(mean=mean, std=std)
        ]
    elif split == 'val':
        transform_list = [
            transform.Crop([args.train_h, args.train_w], crop_type='center', padding=mean, ignore_label=args.ignore_label),
            transform.ToTensor(),
            transform.Normalize(mean=mean, std=std)
        ]
    else:
        print('Unknown split. Quitting ...')
        quit()

    transform_list += [ToFlatLabel(args.tc, dataset_name)]

    return transform.Compose(transform_list)

def load_pretrained_weights(args, model, optimizer):
    """
        Args:
        -   args
        -   model: Passed by reference

        Returns:
        -   None
    """
    import torch, os, math

    resume_iter = 0

    if args.weight:
        if os.path.isfile(args.weight):
            if main_process():
                logger.info("=> loading weight '{}'".format(args.weight))
            checkpoint = torch.load(args.weight)
            model.load_state_dict(checkpoint['state_dict'])
            if main_process():
                logger.info("=> loaded weight '{}'".format(args.weight))
        else:
            if main_process():
                logger.info("=> no weight found at '{}'".format(args.weight))

    if args.resume:
        if os.path.isfile(args.resume):
            if main_process():
                logger.info("=> loading checkpoint '{}'".format(args.resume))
            # checkpoint = torch.load(args.resume)
            checkpoint = torch.load(args.resume, map_location=lambda storage, loc: storage.cuda())
            # args.start_epoch = checkpoint['epoch']
            args.start_epoch = 0 # we don't really rely on this, but on resume_iter
            if args.finetune:
                args.start_epoch = 0
            model.load_state_dict(checkpoint['state_dict'])
            optimizer.load_state_dict(checkpoint['optimizer'])
            resume_iter = checkpoint['current_iter']
            if main_process():
                logger.info("=> loaded checkpoint '{}' (epoch {})".format(args.resume, checkpoint['epoch']))
        else:
            if main_process():
                logger.info("=> no checkpoint found at '{}'".format(args.resume) + ' Please check')
                exit()

    return model, optimizer, resume_iter

            # optimizer = get_optimizer(args.model)

def get_model(args, criterion, BatchNorm):
    """
        Args:
        -

        Returns:
        -
    """
    if args.arch == 'psp':
        from ccsa.ccsa_pspnet import CCSA_PSPNet
        model = CCSA_PSPNet(layers=args.layers, classes=args.classes, zoom_factor=args.zoom_factor, criterion=criterion, BatchNorm=BatchNorm, network_name=args.network_name)

    elif args.arch == 'psa':
        model = PSANet(layers=args.layers, classes=args.classes, zoom_factor=args.zoom_factor, psa_type=args.psa_type,
                       compact=args.compact, shrink_factor=args.shrink_factor, mask_h=args.mask_h, mask_w=args.mask_w,
                       normalization_factor=args.normalization_factor, psa_softmax=args.psa_softmax,
                       criterion=criterion,
                       BatchNorm=BatchNorm)
    return model

def get_optimizer(args, model):
    """
    Create a parameter list, where first 5 entries (ResNet backbone) have low learning rate
    to not clobber pre-trained weights, and later entries (PPM derivatives) have high learning rate.

        Args:
        -   args
        -   model

        Returns:
        -   optimizer
    """
    import torch, os, math

    if args.arch == 'psp':
        modules_ori = [model.layer0, model.layer1, model.layer2, model.layer3, model.layer4]
        modules_new = [model.ppm, model.cls, model.aux]
    elif args.arch == 'psa':
        modules_ori = [model.layer0, model.layer1, model.layer2, model.layer3, model.layer4]
        modules_new = [model.psa, model.cls, model.aux]
    params_list = []
    for module in modules_ori:
        params_list.append(dict(params=module.parameters(), lr=args.base_lr))

    for module in modules_new:
        if args.finetune:
            params_list.append(dict(params=module.parameters(), lr=args.base_lr))
        else:
            params_list.append(dict(params=module.parameters(), lr=args.base_lr * 10))
    args.index_split = 5
    optimizer = torch.optim.SGD(params_list, lr=args.base_lr, momentum=args.momentum, weight_decay=args.weight_decay)
    return optimizer

def get_rank_to_dataset_map(args):
    """
        Obtain a mapping from GPU rank (index) to the name of the dataset residing on this GPU.

        Args:
        -   args

        Returns:
        -   rank_to_dataset_map
    """
    rank_to_dataset_map = {}
    for dataset, gpu_idxs in args.dataset_gpu_mapping.items():
        for gpu_idx in gpu_idxs:
            rank_to_dataset_map[gpu_idx] = dataset
    print('Rank to dataset map: ', rank_to_dataset_map)
    return rank_to_dataset_map

def main_worker(gpu, ngpus_per_node, argss):
    """
    Consider if a dataset has size 18,000 and is placed on a single GPU, of 4 gpus.
    Batch size 32. In this case, len(train_data) = 18,000 but len(train_loader) = 2250
    Because effective batch size is 8.

    Consider if a dataset has size 118287. If placed on 2/4 gpus with batch size 32.
    In this case, len(train_data) = 118287 and len(train_loader) = 7393.
    """

    # with open('test_3.txt', 'a') as f:
    #     f.write('test')
    #     f.close()
    global args
    args = argss

    from ccsa.ccsa_data import CCSA_Data
    from util import dataset
    from taxonomy.utils_flat import TaxonomyConverter
    from multiobjective_opt.dist_mgda_utils import scale_loss_and_gradients
    import apex
    import torch, os, math
    import torch.backends.cudnn as cudnn
    import torch.nn as nn
    import torch.nn.functional as F
    import torch.nn.parallel
    import torch.optim
    import torch.utils.data

    import torch.multiprocessing as mp
    import torch.distributed as dist
    from tensorboardX import SummaryWriter
    from util.dataset_config import infos

    from util import config
    from util.verification_utils import verify_architecture
    from util.avg_meter import AverageMeter, SegmentationAverageMeter
    from util.util import poly_learning_rate

    # with open('test_mainworker.txt', 'a') as f:
    #     f.write('test\t')
    #     f.close()
# os.sleep
    # time.sleep(30)
    if args.sync_bn:
        if args.multiprocessing_distributed:
            # BatchNorm = torch.nn.SyncBatchNorm
            BatchNorm = apex.parallel.SyncBatchNorm
        else:
            from lib.sync_bn.modules import BatchNorm2d
            BatchNorm = BatchNorm2d
    else:
        BatchNorm = nn.BatchNorm2d
    print('Using batchnorm variant: ', BatchNorm)
    if args.distributed:
        if args.dist_url == "env://" and args.rank == -1:
            args.rank = int(os.environ["RANK"])
        if args.multiprocessing_distributed:
            args.rank = args.rank * ngpus_per_node + gpu
        dist.init_process_group(backend=args.dist_backend, init_method=args.dist_url, world_size=args.world_size, rank=args.rank)

    criterion = nn.CrossEntropyLoss(ignore_index=args.ignore_label)
    model = get_model(args, criterion, BatchNorm)
    optimizer = get_optimizer(args, model)

    if True:
        global logger, writer
        logger = get_logger()
        writer = SummaryWriter(args.save_path)
        args.logger = logger

        if main_process():
            logger.info(args)
            logger.info("=> creating model ...")
            logger.info("Classes: {}".format(args.classes))
            logger.info(model)
    if args.distributed:
        torch.cuda.set_device(gpu)
        args.batch_size = int(args.batch_size / ngpus_per_node)
        args.batch_size_val = int(args.batch_size_val / ngpus_per_node)
        args.batch_size_val = max(1, args.batch_size_val)
        args.workers = int(args.workers / ngpus_per_node)
        if args.use_apex:
            model, optimizer = apex.amp.initialize(model.cuda(), optimizer, opt_level=args.opt_level, keep_batchnorm_fp32=args.keep_batchnorm_fp32, loss_scale=args.loss_scale)
            model = apex.parallel.DistributedDataParallel(model)
        else:
            model = torch.nn.parallel.DistributedDataParallel(model.cuda(), device_ids=[gpu])

    else:
        model = torch.nn.DataParallel(model.cuda())

    model, optimizer, args.resume_iter = load_pretrained_weights(args, model, optimizer)

    domain_idx_map = {
        'coco-panoptic-v1-qvga': 0,
        'mapillary_vistas_comm-qvga': 1,
        'ade20k-v1-qvga': 2
    }

    train_transform_dict = {}
    for dname, domain_idx in domain_idx_map.items():
        train_transform_dict[domain_idx] = get_train_transform_list(args, split='train', dataset_name=dname)

    # FLATMIX ADDITION
    train_data = CCSA_Data(split='train', data_roots=args.data_root, data_lists=args.train_list, transform_dict=train_transform_dict)

    from util.txt_utils import read_txt_file
    num_examples = len(train_data)

    num_examples_total = args.num_examples
    args.epochs = math.ceil(num_examples_total / num_examples)
    args.max_iters = math.floor(num_examples_total / (args.batch_size * args.ngpus_per_node))

    # avoid too frequent saving to waste time, on small datasets
    if args.epochs > 200:
        args.save_freq = args.epochs // 100

    logger.info(f'Train data has len {len(train_data)} on {args.rank}')
    if args.distributed:

        train_sampler = torch.utils.data.distributed.DistributedSampler(train_data, num_replicas=args.ngpus_per_node, rank=args.rank)
        logger.info(f"rank: {args.rank}, actual_replica: {train_sampler.num_replicas}, length of sampler, {len(train_sampler)}")

    else:
        train_sampler = None
    train_loader = torch.utils.data.DataLoader(train_data, batch_size=args.batch_size, shuffle=(train_sampler is None), num_workers=args.workers, pin_memory=True, sampler=train_sampler, drop_last=True)
    logger.info(f'Train loader has len {len(train_loader)} on {args.rank}')

    if args.evaluate:
        val_transform = get_train_transform_list(args, split='val')
        # val_transform = transform.Compose(val_transform_list)
        val_data = dataset.SemData(split='val', data_root=args.data_root, data_list=args.val_list, transform=val_transform)
        if args.distributed:
            val_sampler = torch.utils.data.distributed.DistributedSampler(val_data)
        else:
            val_sampler = None
        val_loader = torch.utils.data.DataLoader(val_data, batch_size=args.batch_size_val, shuffle=False, num_workers=args.workers, pin_memory=True, sampler=val_sampler)

    for epoch in range(args.start_epoch, args.epochs):
        epoch_log = epoch + 1
        logger.info(f'New epoch {epoch_log} starts on rank {args.rank}')

        if args.distributed:
            train_sampler.set_epoch(epoch)
        print(f'On training epoch {epoch} in GPU {args.rank}')
        loss_train, mIoU_train, mAcc_train, allAcc_train = train(train_loader, model, optimizer, epoch)
        # if main_process():
        #     writer.add_scalar('loss_train', loss_train, epoch_log)
        #     writer.add_scalar('mIoU_train', mIoU_train, epoch_log)
        #     writer.add_scalar('mAcc_train', mAcc_train, epoch_log)
        #     writer.add_scalar('allAcc_train', allAcc_train, epoch_log)

        if ((epoch_log % args.save_freq == 0)) and main_process():
            filename = args.save_path + '/train_epoch_' + str(epoch_log) + '.pth'
            logger.info('Saving checkpoint to: ' + filename)
            torch.save({'epoch': epoch_log, 'state_dict': model.state_dict(), 'optimizer': optimizer.state_dict(),
                'current_iter': (epoch + 1) * len(train_loader), 'max_iter': args.max_iters}, filename)
            if epoch_log / args.save_freq > 2:
                # if (epoch_log - 3) % 10 != 0:
                if not args.finetune:
                    deletename = args.save_path + '/train_epoch_' + str(epoch_log - args.save_freq * 2) + '.pth'
                    os.remove(deletename)

        if (epoch == args.epochs - 1) and main_process():
            filename = args.save_path + '/train_epoch_final.pth'
            logger.info('Saving checkpoint to: ' + filename)
            torch.save({'epoch': epoch_log, 'state_dict': model.state_dict(), 'optimizer': optimizer.state_dict(),
                'current_iter': (epoch + 1) * len(train_loader), 'max_iter': args.max_iters}, filename)
            exit()

        # if args.evaluate:
        #     loss_val, mIoU_val, mAcc_val, allAcc_val = validate(val_loader, model, criterion)
        #     if main_process():
        #         writer.add_scalar('loss_val', loss_val, epoch_log)
        #         writer.add_scalar('mIoU_val', mIoU_val, epoch_log)
        #         writer.add_scalar('mAcc_val', mAcc_val, epoch_log)
        #         writer.add_scalar('allAcc_val', allAcc_val, epoch_log)

def train(train_loader, model, optimizer, epoch):
    """
    No MGDA -- whole iteration takes 0.31 sec.
    0.24 sec to run typical backward pass (with no MGDA)

    With MGDA -- whole iteration takes 1.10 sec.
    1.05 sec to run backward pass w/ MGDA subroutine -- scale_loss_and_gradients() in every iteration.

    TODO: Profile which part of Frank-Wolfe is slow

    """

    from util.avg_meter import AverageMeter, SegmentationAverageMeter
    from util.util import poly_learning_rate

    import torch.distributed as dist
    from multiobjective_opt.dist_mgda_utils import scale_loss_and_gradients

    import torch, os, math, time

    batch_time = AverageMeter()
    data_time = AverageMeter()
    main_loss_meter = AverageMeter()
    aux_loss_meter = AverageMeter()
    loss_meter = AverageMeter()
    sam = SegmentationAverageMeter()

    model.train()
    # set bn to be eval() and see the norm
    # def set_bn_eval(m):
    #     classname = m.__class__.__name__
    #     if classname.find('BatchNorm') != -1:
    #         m.eval()
    # model.apply(set_bn_eval)
    end = time.time()
    max_iter = args.max_iters

    for i, (input, target, batch_domain_idxs) in enumerate(train_loader):
        # pass
        # if main_process():
        data_time.update(time.time() - end)
        if args.zoom_factor != 8:
            h = int((target.size()[1] - 1) / 8 * args.zoom_factor + 1)
            w = int((target.size()[2] - 1) / 8 * args.zoom_factor + 1)
            # 'nearest' mode doesn't support align_corners mode and 'bilinear' mode is fine for downsampling
            target = F.interpolate(target.unsqueeze(1).float(), size=(h, w), mode='bilinear', align_corners=True).squeeze(1).long()
        input = input.cuda(non_blocking=True)
        target = target.cuda(non_blocking=True)
        batch_domain_idxs = batch_domain_idxs.cuda(non_blocking=True)

        if args.use_mgda:
            output, loss, main_loss, aux_loss, scales = forward_backward_mgda(input, target, model, optimizer, args)
        else:
            #print('Batch domain idxs: ', batch_domain_idxs.shape, batch_domain_idxs.device, batch_domain_idxs)
            output, loss, main_loss, aux_loss = forward_backward_full_sync(input, target, model, optimizer, args, batch_domain_idxs)

        optimizer.step()

        n = input.size(0)
        if args.multiprocessing_distributed:
            main_loss, aux_loss, loss = main_loss.detach() * n, aux_loss * n, loss * n  # not considering ignore pixels
            count = target.new_tensor([n], dtype=torch.long)
            dist.all_reduce(main_loss), dist.all_reduce(aux_loss), dist.all_reduce(loss), dist.all_reduce(count)
            n = count.item()
            main_loss, aux_loss, loss = main_loss / n, aux_loss / n, loss / n

        sam.update_metrics_gpu(output, target, args.classes, args.ignore_label, args.multiprocessing_distributed)

        main_loss_meter.update(main_loss.item(), n)
        aux_loss_meter.update(aux_loss.item(), n)
        loss_meter.update(loss.item(), n)
        # if main_process():
        if i > 0:
            batch_time.update(time.time() - end)
        end = time.time()

        current_iter = epoch * len(train_loader) + i + 1 + args.resume_iter
        current_lr = poly_learning_rate(args.base_lr, current_iter, max_iter, power=args.power)
        # current_lr = 0
        for index in range(0, args.index_split):
            optimizer.param_groups[index]['lr'] = current_lr
        for index in range(args.index_split, len(optimizer.param_groups)):
            if args.finetune:
                optimizer.param_groups[index]['lr'] = current_lr
            else:
                optimizer.param_groups[index]['lr'] = current_lr * 10

        remain_iter = max_iter - current_iter
        remain_time = remain_iter * batch_time.avg
        t_m, t_s = divmod(remain_time, 60)
        t_h, t_m = divmod(t_m, 60)
        remain_time = '{:02d}:{:02d}:{:02d}'.format(int(t_h), int(t_m), int(t_s))

        if (i + 1) % args.print_freq == 0 and main_process():
        # if True:
            logger.info('Epoch: [{}/{}][{}/{}] '
                        'Data {data_time.val:.3f} ({data_time.avg:.3f}) '
                        'Batch {batch_time.val:.3f} ({batch_time.avg:.3f}) '
                        'Remain {remain_time} '
                        'MainLoss {main_loss_meter.val:.4f} '
                        'AuxLoss {aux_loss_meter.val:.4f} '
                        'Loss {loss_meter.val:.4f} '
                        'Accuracy {accuracy:.4f}.'.format(epoch+1, args.epochs, i + 1, len(train_loader),
                                                          batch_time=batch_time,
                                                          data_time=data_time,
                                                          remain_time=remain_time,
                                                          main_loss_meter=main_loss_meter,
                                                          aux_loss_meter=aux_loss_meter,
                                                          loss_meter=loss_meter,
                                                          accuracy=sam.accuracy) + f'current_iter: {current_iter}' + f' rank: {args.rank} ')
            if args.use_mgda and main_process():
                # Scales identical in each process, so print out only in main process.
                scales_str = [f'{d}: {scale:.2f}' for d,scale in scales.items()]
                scales_str = ' , '.join(scales_str)
                logger.info(f'Scales: {scales_str}')

        if main_process() and current_iter == max_iter - 5: # early exit to prevent iter number not matching between gpus
            break
        # if main_process():
        #     writer.add_scalar('loss_train_batch', main_loss_meter.val, current_iter)
        #     writer.add_scalar('mIoU_train_batch', np.mean(intersection / (union + 1e-10)), current_iter)
        #     writer.add_scalar('mAcc_train_batch', np.mean(intersection / (target + 1e-10)), current_iter)
        #     writer.add_scalar('allAcc_train_batch', accuracy, current_iter)

    iou_class, accuracy_class, mIoU, mAcc, allAcc = sam.get_metrics()
    # if main_process():
    logger.info('Train result at epoch [{}/{}]: mIoU/mAcc/allAcc {:.4f}/{:.4f}/{:.4f}.'.format(epoch+1, args.epochs, mIoU, mAcc, allAcc))
    return main_loss_meter.avg, mIoU, mAcc, allAcc

def forward_backward_full_sync(input, target, model, optimizer, args, batch_domain_idxs):
    """
        Args:
        -   input: Tensor of size (?) representing
        -   target: Tensor of size (?) representing
        -   model
        -   optimizer
        -   args

        Returns:
        -   output: Tensor of size (?) representing
        -   loss: Tensor of size (?) representing
        -   main_loss: Tensor of size (?) representing
        -   aux_loss: Tensor of size (?) representing
    """
    output, main_loss, aux_loss = model(input, target, batch_domain_idxs)
    if not args.multiprocessing_distributed:
        main_loss, aux_loss = torch.mean(main_loss), torch.mean(aux_loss)
    loss = main_loss + args.aux_weight * aux_loss

    optimizer.zero_grad()
    if args.use_apex and args.multiprocessing_distributed:
        with apex.amp.scale_loss(loss, optimizer) as scaled_loss:
            scaled_loss.backward()
    else:
        loss.backward()
    return output, loss, main_loss, aux_loss

def forward_backward_mgda(input, target, model, optimizer, args):
    from multiobjective_opt.dist_mgda_utils import scale_loss_and_gradients
    """
        We rely upon the ddp.no_sync() of gradients:
        https://github.com/pytorch/pytorch/blob/master/torch/nn/parallel/distributed.py

        Args:
        -   input: Tensor of size (?) representing
        -   target: Tensor of size (?) representing
        -   model
        -   optimizer
        -   args

        Returns:
        -   output: Tensor of size (?) representing
        -   loss: Tensor of size (?) representing
        -   main_loss: Tensor of size (?) representing
        -   aux_loss: Tensor of size (?) representing
    """
    with model.no_sync():
        output, main_loss, aux_loss = model(input, target)
        loss = main_loss + args.aux_weight * aux_loss
        loss, scales = scale_loss_and_gradients(loss, optimizer, model, args)

    return output, loss, main_loss, aux_loss, scales

def validate(val_loader, model, criterion):
    if main_process():
        logger.info('>>>>>>>>>>>>>>>> Start Evaluation >>>>>>>>>>>>>>>>')
    batch_time = AverageMeter()
    data_time = AverageMeter()
    loss_meter = AverageMeter()
    sam = SegmentationAverageMeter()

    model.eval()
    if main_process():
        end = time.time()
    for i, (input, target) in enumerate(val_loader):
        if main_process():
            data_time.update(time.time() - end)
        input = input.cuda(non_blocking=True)
        target = target.cuda(non_blocking=True)
        output = model(input)
        if args.zoom_factor != 8:
            output = F.interpolate(output, size=target.size()[1:], mode='bilinear', align_corners=True)
        loss = criterion(output, target)

        n = input.size(0)
        if args.multiprocessing_distributed:
            loss = loss * n  # not considering ignore pixels
            count = target.new_tensor([n], dtype=torch.long)
            dist.all_reduce(loss), dist.all_reduce(count)
            n = count.item()
            loss = loss / n
        else:
            loss = torch.mean(loss)

        output = output.max(1)[1]
        sam.update_metrics_gpu(output, target, args.classes, args.ignore_label, args.multiprocessing_distributed)
        loss_meter.update(loss.item(), input.size(0))
        if main_process():
            batch_time.update(time.time() - end)
            end = time.time()
        if ((i + 1) % args.print_freq == 0) and main_process():
            logger.info('Test: [{}/{}] '
                        'Data {data_time.val:.3f} ({data_time.avg:.3f}) '
                        'Batch {batch_time.val:.3f} ({batch_time.avg:.3f}) '
                        'Loss {loss_meter.val:.4f} ({loss_meter.avg:.4f}) '
                        'Accuracy {accuracy:.4f}.'.format(i + 1, len(val_loader),
                                                          data_time=data_time,
                                                          batch_time=batch_time,
                                                          loss_meter=loss_meter,
                                                          accuracy=sam.accuracy))

    iou_class, accuracy_class, mIoU, mAcc, allAcc = sam.get_metrics()
    if main_process():
        logger.info('Val result: mIoU/mAcc/allAcc {:.4f}/{:.4f}/{:.4f}.'.format(mIoU, mAcc, allAcc))
        for i in range(args.classes):
            logger.info('Class_{} Result: iou/accuracy {:.4f}/{:.4f}.'.format(i, iou_class[i], accuracy_class[i]))
        logger.info('<<<<<<<<<<<<<<<<< End Evaluation <<<<<<<<<<<<<<<<<')
    return loss_meter.avg, mIoU, mAcc, allAcc

end = time.time()
print(end-start)
if __name__ == '__main__':
    print('main')

    main()


"""This is the messenger class module"""
import requests
import os

class Messenger:
    """prepares messages to be sent via email or saved to database"""

    def __init__(self, base_url=None, url=None, recipient_email=None):
        """initialize the class with api endpoint or the recipient email"""
        self.base_url = base_url
        self.sender_email = recipient_email
        self.url = url

    def query_server(self, data=None, files=None) -> dict:
        """sends the data to api"""
        url = self.base_url + self.url
        request_headers = {'Content-Type': 'application/json'}
        try:
            if files is not None:
                files_dict = {field_name: (file_obj, base_name) for field_name, (file_obj, base_name) in files.items()}
                files_for_request = {field_name: (base_name, file_obj, 'application/octet-stream') for
                                     field_name, (file_obj, base_name) in files_dict.items()}
                response = requests.post(url, files=files_for_request)
            else:
                response = requests.post(url, headers=request_headers, json=data)

            if response.status_code == 400:
                # Log or display detailed information about the error response
                print(f"400 Error Response: {response.text}")

            response.raise_for_status()  # Raise exception for non-200 status codes

        except requests.HTTPError as http_err:
            # Handle HTTP errors (other than 400)
            return {'status': 2, 'message': str(http_err), 'data': None, 'error': [str(http_err)]}
        except Exception as e:
            # Handle other exceptions
            return {'status': 2, 'message': str(e), 'data': None, 'error': [str(e)]}

        return response.json()

    def check_for_existing_record(self, vehicle_id: str) -> dict:
        """prepares data and saves to data base"""
        response = self.query_server({'vehicle_id': vehicle_id})
        print(response)
        return response


import sys
import configparser

from function import global_value as g

def load(configfile):
    config = configparser.ConfigParser()

    try:
        config.read(configfile, encoding="utf-8")
    except:
        sys.exit()

    g.logging.info(f"configload: {configfile} -> {config.sections()}")
    return(config)

def save(config, configfile):
    with open(configfile, "w") as f:
        config.write(f)

def parameter_load():
    # メンバー登録ファイル
    if g.args.member:
        g.memberfile = g.args.member
    else:
        g.memberfile = g.config["member"].get("filename", "member.ini")

    try:
        g.player_list = configparser.ConfigParser()
        g.player_list.read(g.memberfile, encoding="utf-8")
        g.logging.info(f"configload: {g.memberfile} -> {g.player_list.sections()}")
    except:
        sys.exit(f"{g.memberfile}: file not found")

    g.guest_name = g.config["member"].get("guest_name", "ゲスト")
    g.dbfile = g.config["database"].get("filename", "score.db")

def command_option_initialization(command):
    """
    設定ファイルからコマンドのオプションのデフォルト値を読み込む

    Parameters
    ----------
    command : str
        読み込むコマンド名

    Returns
    -------
    option : dict
        初期化されたオプション
    """

    option = {
        "aggregation_range": [],
        "recursion": True,
    }

    option["aggregation_range"].append(g.config[command].get("aggregation_range", "当日"))
    option["playername_replace"] = g.config[command].getboolean("playername_replace", True)
    option["unregistered_replace"] = g.config[command].getboolean("unregistered_replace", True)
    option["guest_skip"] = g.config[command].getboolean("guest_skip", True)
    option["guest_skip2"] = g.config[command].getboolean("guest_skip2", True)
    option["score_comparisons"] = g.config[command].getboolean("score_comparisons", False)
    option["archive"] = g.config[command].getboolean("archive", False)
    option["game_results"] = g.config[command].getboolean("game_results", False)
    option["versus_matrix"] = g.config[command].getboolean("versus_matrix", False)
    option["ranked"] = g.config[command].getint("ranked", 3)
    option["stipulated_rate"] = g.config[command].getfloat("stipulated_rate", 0.05)

    return(option)


from django.shortcuts import render, redirect
from .models import Course
from .forms import CourseForm
from django.http import JsonResponse
from django.contrib import messages

# Create your views here.

def course_view(request):
    courses=Course.objects.all()
    return render(request,'course.html',{'courses':courses})

def addCourse(request):
    if request.method == 'POST':
        form = CourseForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return redirect('courses')
    else:
        form = CourseForm()

    return render(request, 'addCourse.html', {'form': form})

def active_courses(request):
    active_courses = Course.objects.filter(active=True).values('title', 'subtitle', 'image')
    return JsonResponse({'active_courses': list(active_courses)})

def inactive_courses(request):
    inactive_courses = Course.objects.filter(active=False).values('title','subtitle','image')
    return JsonResponse({'inactive_courses': list(inactive_courses)})

def EditCourse(request, id):
    course = Course.objects.get(id=id)

    if request.method == 'POST':
        form = CourseForm(request.POST, request.FILES, instance=course)

        if form.is_valid():
            form.save()
            messages.success(request, 'Course edited successfully.')
            return redirect('courses')
        else:
            messages.error(request, 'Invalid input')

    form = CourseForm(instance=course)
    context = {
        'form': form,
        'course': course,
    }

    return render(request, 'EditCourse.html', context)

def deleteCourse(request, id):
  course = Course.objects.get(id=id)
  course.delete()
  messages.success(request, 'Course deleted successfully.')
  return redirect('courses')


# ##### BEGIN GPL LICENSE BLOCK #####
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software Foundation,
#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####

# <pep8 compliant>

import bpy
import blf

from . import utils
from mathutils import Vector

SpaceView3D = bpy.types.SpaceView3D
callback_handle = []

def tag_redraw_areas():
    context = bpy.context

    # Py cant access notifers
    for window in context.window_manager.windows:
        for area in window.screen.areas:
            if area.type in ['VIEW_3D', 'PROPERTIES']:
                area.tag_redraw()

def callback_enable():
    if callback_handle:
        return

    handle_pixel = SpaceView3D.draw_handler_add(draw_callback_px, (), 'WINDOW', 'POST_PIXEL')
    handle_view = SpaceView3D.draw_handler_add(draw_callback_view, (), 'WINDOW', 'POST_VIEW')
    callback_handle[:] = handle_pixel, handle_view

    tag_redraw_areas()

def callback_disable():
    if not callback_handle:
        return

    handle_pixel, handle_view = callback_handle
    SpaceView3D.draw_handler_remove(handle_pixel, 'WINDOW')
    SpaceView3D.draw_handler_remove(handle_view, 'WINDOW')
    callback_handle[:] = []

    tag_redraw_areas()

def draw_callback_px():
    context = bpy.context

    from bgl import glColor3f
    font_id = 0  # XXX, need to find out how best to get this.
    blf.size(font_id, 12, 72)

    data_matrix, data_quat, data_euler, data_vector, data_vector_array = utils.console_math_data()

    name_hide = context.window_manager.MathVisProp.name_hide

    if name_hide:
        return

    if not data_matrix and not data_quat and not data_euler and not data_vector and not data_vector_array:

        '''
        # draw some text
        glColor3f(1.0, 0.0, 0.0)
        blf.position(font_id, 180, 10, 0)
        blf.draw(font_id, "Python Console has no mathutils definitions")
        '''
        return

    glColor3f(1.0, 1.0, 1.0)

    region = context.region
    region3d = context.space_data.region_3d

    region_mid_width = region.width / 2.0
    region_mid_height = region.height / 2.0

    # vars for projection
    perspective_matrix = region3d.perspective_matrix.copy()

    def draw_text(text, vec, dx=3.0, dy=-4.0):
        vec_4d = perspective_matrix * vec.to_4d()
        if vec_4d.w > 0.0:
            x = region_mid_width + region_mid_width * (vec_4d.x / vec_4d.w)
            y = region_mid_height + region_mid_height * (vec_4d.y / vec_4d.w)

            blf.position(font_id, x + dx, y + dy, 0.0)
            blf.draw(font_id, text)

    # points
    if data_vector:
        for key, vec in data_vector.items():
            draw_text(key, vec)

    # lines
    if data_vector_array:
        for key, vec in data_vector_array.items():
            if vec:
                draw_text(key, vec[0])

    # matrix
    if data_matrix:
        for key, mat in data_matrix.items():
            loc = Vector((mat[0][3], mat[1][3], mat[2][3]))
            draw_text(key, loc, dx=10, dy=-20)

    line = 20
    if data_quat:
        loc = context.scene.cursor_location.copy()
        for key, mat in data_quat.items():
            draw_text(key, loc, dy=-line)
            line += 20

    if data_euler:
        loc = context.scene.cursor_location.copy()
        for key, mat in data_euler.items():
            draw_text(key, loc, dy=-line)
            line += 20

def draw_callback_view():
    context = bpy.context

    from bgl import (
        glEnable,
        glDisable,
        glColor3f,
        glVertex3f,
        glPointSize,
        glLineWidth,
        glBegin,
        glEnd,
        glLineStipple,
        GL_POINTS,
        GL_LINE_STRIP,
        GL_LINES,
        GL_LINE_STIPPLE
    )

    data_matrix, data_quat, data_euler, data_vector, data_vector_array = utils.console_math_data()

    # draw_matrix modifiers
    bbox_hide = context.window_manager.MathVisProp.bbox_hide
    bbox_scale = context.window_manager.MathVisProp.bbox_scale

    # draw_matrix vars
    zero = Vector((0.0, 0.0, 0.0))
    x_p = Vector((bbox_scale, 0.0, 0.0))
    x_n = Vector((-bbox_scale, 0.0, 0.0))
    y_p = Vector((0.0, bbox_scale, 0.0))
    y_n = Vector((0.0, -bbox_scale, 0.0))
    z_p = Vector((0.0, 0.0, bbox_scale))
    z_n = Vector((0.0, 0.0, -bbox_scale))
    bb = [Vector() for i in range(8)]

    def draw_matrix(mat):
        zero_tx = mat * zero

        glLineWidth(2.0)

        # x
        glColor3f(1.0, 0.2, 0.2)
        glBegin(GL_LINES)
        glVertex3f(*(zero_tx))
        glVertex3f(*(mat * x_p))
        glEnd()

        glColor3f(0.6, 0.0, 0.0)
        glBegin(GL_LINES)
        glVertex3f(*(zero_tx))
        glVertex3f(*(mat * x_n))
        glEnd()

        # y
        glColor3f(0.2, 1.0, 0.2)
        glBegin(GL_LINES)
        glVertex3f(*(zero_tx))
        glVertex3f(*(mat * y_p))
        glEnd()

        glColor3f(0.0, 0.6, 0.0)
        glBegin(GL_LINES)
        glVertex3f(*(zero_tx))
        glVertex3f(*(mat * y_n))
        glEnd()

        # z
        glColor3f(0.4, 0.4, 1.0)
        glBegin(GL_LINES)
        glVertex3f(*(zero_tx))
        glVertex3f(*(mat * z_p))
        glEnd()

        glColor3f(0.0, 0.0, 0.6)
        glBegin(GL_LINES)
        glVertex3f(*(zero_tx))
        glVertex3f(*(mat * z_n))
        glEnd()

        # bounding box
        if bbox_hide:
            return

        i = 0
        glColor3f(1.0, 1.0, 1.0)
        for x in (-bbox_scale, bbox_scale):
            for y in (-bbox_scale, bbox_scale):
                for z in (-bbox_scale, bbox_scale):
                    bb[i][:] = x, y, z
                    bb[i] = mat * bb[i]
                    i += 1

        # strip
        glLineWidth(1.0)
        glLineStipple(1, 0xAAAA)
        glEnable(GL_LINE_STIPPLE)

        glBegin(GL_LINE_STRIP)
        for i in 0, 1, 3, 2, 0, 4, 5, 7, 6, 4:
            glVertex3f(*bb[i])
        glEnd()

        # not done by the strip
        glBegin(GL_LINES)
        glVertex3f(*bb[1])
        glVertex3f(*bb[5])

        glVertex3f(*bb[2])
        glVertex3f(*bb[6])

        glVertex3f(*bb[3])
        glVertex3f(*bb[7])
        glEnd()
        glDisable(GL_LINE_STIPPLE)

    # points
    if data_vector:
        glPointSize(3.0)
        glBegin(GL_POINTS)
        glColor3f(0.5, 0.5, 1)
        for key, vec in data_vector.items():
            glVertex3f(*vec.to_3d())
        glEnd()
        glPointSize(1.0)

    # lines
    if data_vector_array:
        glColor3f(0.5, 0.5, 1)
        glLineWidth(2.0)

        for line in data_vector_array.values():
            glBegin(GL_LINE_STRIP)
            for vec in line:
                glVertex3f(*vec)
            glEnd()
            glPointSize(1.0)

        glLineWidth(1.0)

    # matrix
    if data_matrix:
        for mat in data_matrix.values():
            draw_matrix(mat)

    if data_quat:
        loc = context.scene.cursor_location.copy()
        for quat in data_quat.values():
            mat = quat.to_matrix().to_4x4()
            mat.translation = loc
            draw_matrix(mat)

    if data_euler:
        loc = context.scene.cursor_location.copy()
        for eul in data_euler.values():
            mat = eul.to_matrix().to_4x4()
            mat.translation = loc
            draw_matrix(mat)


import os
import sys

# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information

project = 'Omnipy'
copyright = '2023, Sveinung Gundersen, Joshua Baskaran, Federico Bianchini, Jeanne Cheneby, ' \
            'Ahmed Ghanem, Pável Vázquez'
author = 'Sveinung Gundersen, Joshua Baskaran, Federico Bianchini, Jeanne Cheneby, Ahmed Ghanem, ' \
         'Pável Vázquez'
release = '0.10.5'

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

extensions = [
    'autoapi.extension',
    'sphinx.ext.viewcode',
    'sphinx.ext.napoleon',
    'sphinx_copybutton',
]

autoapi_dirs = ['../../src/omnipy']
autoapi_keep_files = False
autoapi_type = 'python'
autoapi_template_dir = '../templates/autoapi'
autoapi_options = [
    'members',
    'inherited-members',
    'undoc-members',
    'special-members',
    'show-inheritance',
    'show-module-summary',
    'imported-members',
]

autodoc_typehints = 'signature'

exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']

html_theme = 'furo'
html_static_path = ['../static']

toc_object_entries = False

def attr_inherited_from_other_package(attr_name_rel: str, class_name: str, module_abs: str) -> bool:
    import importlib
    import inspect

    try:
        module = importlib.import_module(module_abs)
        cls = getattr(module, class_name)

        attr_info = None
        for attr in inspect.classify_class_attrs(cls):
            if attr.name == attr_name_rel:
                attr_info = attr

        return attr_info is None or attr_info.defining_class.__module__.split('.')[0] != 'omnipy'
    except Exception as e:
        print(f'Exception occurred for attr {attr_name_rel}: {type(e)} {e}')
        return True

def skip_members(app, what, name, obj, skip, options):
    name_split = name.split('.')
    name_rel = name_split[-1]

    if what in ('method', 'attribute'):
        assert len(name_split) > 3, name
        class_name = name_split[-2]
        module_abs = '.'.join(name_split[:-2])

        if name_rel.startswith('__'):
            # __call__ method of Template classes are internal, should not be used externally
            if name_rel != '__call__' or class_name.endswith('Template'):
                skip = True
        elif attr_inherited_from_other_package(name_rel, class_name, module_abs):
            skip = True

    elif what == 'class' and name_rel in ('Config', 'list', 'dict'):
        skip = True

    return skip

def setup(sphinx):
    sphinx.connect('autoapi-skip-member', skip_members)

sys.path.insert(0, os.path.abspath('../src'))

# Copied from https://github.com/abey79/vsketch/blob/master/docs/conf.py under the following
# license:
#
# ------------------------------
# MIT License
#
# Copyright (c) 2020 Antoine Beyeler & contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

def contains(seq, item):
    """Jinja2 custom test to check existence in a container.
    Example of use:
    {% set class_methods = methods|selectattr("properties", "contains", "classmethod") %}
    Related doc: https://jinja.palletsprojects.com/en/3.1.x/api/#custom-tests
    """
    return item in seq

def prepare_jinja_env(jinja_env) -> None:
    """Add `contains` custom test to Jinja environment."""
    jinja_env.tests['contains'] = contains

autoapi_prepare_jinja_env = prepare_jinja_env

# Custom role for labels used in auto_summary() tables.
rst_prolog = """
.. role:: summarylabel
"""

# Related custom CSS
html_css_files = ['css/label.css']


from django.urls import path, include
from . import views
# from rest_framework import routers
#
# router = routers.DefaultRouter()
# router.register('addresses', views.AddressViewSet)

urlpatterns = [
    path('', views.home, name='home'),
    path('products/', views.products, name='products'),
    path('cart/', views.cart, name='cart'),
    path('profil/', views.profil, name='profil'),
    path('address/', views.address, name='address-update'),
    path('history/', views.history, name='history'),
    path('checkout/', views.checkout, name='checkout'),
    path('contact/', views.contact, name='contact'),
    path('signup/', views.usersignup, name='signup'),
    path('login/', views.userlogin, name='login'),
    path('logout/', views.userlogout, name='logout'),
    path('checkout/', views.checkout, name='checkout'),
    path('about/', views.about, name='about'),
    # path('', include(router.urls)),
    #path('api-auth', include('rest_framework.urls', namespace='rest_framework'))
]


import threading

f = open('stock.txt')
data = f.readlines()
num=0
lock = threading.Lock()
class Dispatcher:

    @staticmethod
    def Dispatch(self):
        lock.acquire()
        if len(data)>0:
            global num

            num=num+1
            d=data.pop()
            print('提取：'+str(num))
            lock.release()
            return d.strip('\n')

        else:
            lock.release()
            return '0'


'''
부분순열의 마지막 값이 n
    -> n-1까지의 원소 중 n이하 중 가장 큰 값을 마지막으로하는 부분순열 길이 +1
'''
n = int(input())
numbers = list(map(int, input().split()))

dp = [1] * n

for i in range(n):
    for j in range(i):
        if numbers[i] > numbers[j]:
            dp[i] = max(dp[i], dp[j]+1)

print(max(dp))

백준/Silver/11053. 가장 긴 증가하는 부분 수열/가장 긴 증가하는 부분 수열.py

가장 긴 증가하는 부분 수열.py


from http import client
import re
import requests
import urllib.request
base64_login = 'YnV0dGVyOmZseQ=='
headers = {"Authorization": "Basic %s" % base64_login}
conn = client.HTTPConnection("www.pythonchallenge.com")

"""for n in range(30202, 40000):
    headers["Range"] = "bytes=%s-%s" % (n, n + 1)
    conn.request("GET", "/pc/hex/unreal.jpg", "", headers)
    response = conn.getresponse()
    data = response.read()
    print(response.headers)
    if data:
        print(data)"""

import urllib.request, base64

request = urllib.request.Request('http://www.pythonchallenge.com/pc/hex/unreal.jpg')
cred = base64.b64encode(b"butter:fly")
request.add_header("Authorization", "Basic %s" % cred.decode())
print(request.headers)
# {'Authorization': 'Basic YnV0dGVyOmZseQ=='}

response = urllib.request.urlopen(request)

pattern = re.compile('bytes (\d+)-(\d+)/(\d+)')
content_range = response.headers['content-range']
(start, end, length) = pattern.search(content_range).groups()
request.headers['Range'] = 'bytes=%i-' % (int(end) + 1)
response = urllib.request.urlopen(request)
print(response.headers)

print(response.read().decode())

request.headers['Range'] = 'bytes=1152983631-'
response = urllib.request.urlopen(request)
print(response.headers)

zipfile = response.read()

f = open("C:\\Users\\m3\\Desktop\\stage20.zip",'wb')
f.write(zipfile)


"""
https://leetcode.com/problems/single-threaded-cpu/

You are given n tasks labeled from 0 to n - 1 represented by a 2D integer array
tasks, where tasks[i] = [enqueueTimei, processingTimei] means that the ith task
will be available to process at enqueueTimei and will take processingTimei to
finish processing.

You have a single-threaded CPU that can process at most one task at a time and
will act in the following way:

  If the CPU is idle and there are no available tasks to process, the CPU
  remains idle.

  If the CPU is idle and there are available tasks, the CPU will choose the one
  with the shortest processing time. If multiple tasks have the same shortest
  processing time, it will choose the task with the smallest index.

  Once a task is started, the CPU will process the entire task without stopping.

  The CPU can finish a task then start a new one instantly.

Return the order in which the CPU will process the tasks.
"""

from typing import List
from bisect import bisect

def get_order(tasks: List[List[int]]) -> List[int]:
  """
  O() O(n)
  """
  tasks = sorted((t[0], (t[1], i)) for i, t in enumerate(tasks))
  len_tasks = len(tasks)
  t = tasks[0][0]
  i = j = 0
  while True:
    while tasks[j][0] <= t:
      k = bisect(tasks, tasks[j][1], lo=i, hi=j, key=lambda item: item[1])
      if k != j: tasks.insert(k, tasks.pop(j))
      j += 1
      if j == len_tasks:
        return [task[1][1] for task in tasks]
    if tasks[i][0] > t:
      t = tasks[i][0]
    else:
      t += tasks[i][1][0]
      i += 1


from data import *
import matplotlib.pyplot as plt

print("podaj liczbe miesiecy symulacji\n")
miesiace = int(input())

regola =  int(input("podaj regole :2,3,4,5,6,7,10,12\n"))
#systems.setf(regola);
systems = allSystems(1, 1, regola, 2)
offset = systems.readData("datainput2.txt")
miesiace += offset
for i in range(offset + 1, miesiace + 1):
    print("#############" + str(i) + "###############\n")
    systems.computeToFill(i)
    systems.update(i)
    #systems.print_()

YvalSys1 = systems.getSysYval(0)
TimesSys1 = systems.getSysTimes(0)
functSys1 = systems.getSysFunctions(0)

YvalSys2 = systems.getSysYval(1)
TimesSys2 = systems.getSysTimes(1)
functSys2 = systems.getSysFunctions(1)

YvalSys3 = systems.getSysYval(2)
TimesSys3 = systems.getSysTimes(2)
functSys3 = systems.getSysFunctions(2)

print(functSys3)
print(functSys1)
print(functSys2)
plt.figure(1)
plt.plot(TimesSys1,YvalSys1)
plt.plot(TimesSys2,YvalSys2)
plt.plot(TimesSys3,YvalSys3)
plt.show()

plt.figure(1)
plt.plot(TimesSys1,functSys1)
plt.plot(TimesSys2,functSys2)
plt.plot(TimesSys3,functSys3)
plt.show()
#systems.save(fileout);
#fileout.close();
#file.close();