from app.models import KanbanArticle,KanbanComment,KanbanDepartmentAdmin,KanbanGroup, KanbanRead,KanbanZan, KefuDepartment,KefuUser, KefuUserDepartmentRelation
from common.mysql import session
from app.paginator import Paginator
from sqlalchemy import and_
import json

def paginators(data, page_size, page_index):
    page_info = Paginator(data, page_size, 0)
    content = page_info.page(page_index).object_list
    pagenum = page_info.get_num_pages()
    return [content, pagenum]

def get_delactive(data):
    for item in data:
        del_active = item['is_del']
        return del_active

def get_department(data):
    department = []
    for item in data:
        department.append(item['departmentid'])
    return department

def get_groupname(data):
    for item in data:
        groupname = item['name']
        return groupname

def get_adminpermission_info(iuserid:int):
    data = session.query(KanbanDepartmentAdmin.departmentid).filter(KanbanDepartmentAdmin.userid==iuserid).all()
    return data

def get_groupdepartment_info(itemid:int):
    data = session.query(KanbanGroup.departmentid).filter(KanbanGroup.id==itemid).first()
    return data

def get_groupname_info(iname:str,idepartmentid:int):
    data = session.query(KanbanGroup.name).filter(KanbanGroup.departmentid==idepartmentid,KanbanGroup.name==iname).first()
    return data

def get_id_info(itemid:int):
    data = session.query(KanbanArticle.is_del).filter(KanbanArticle.id==itemid,KanbanArticle.is_del==0).first()
    return data

def get_userid_info(itemid:int,iuserid:int):
    department_id = []
    read_art = session.query(KanbanRead.id).filter(KanbanRead.articleid==itemid,KanbanRead.userid==iuserid).first()
    departmentid = [session.query(KanbanArticle.departmentid).filter(KanbanArticle.id==itemid).first()]
    for i in departmentid:
        department_id.append(i['departmentid'])
        if read_art == None:
            article = KanbanRead(articleid=itemid,userid=iuserid,departmentid=department_id[0])
            session.add(article)
            session.commit()
    result = []
    avatarvocer = {}
    data1 = [session.query(KanbanArticle.userid).filter(KanbanArticle.id==itemid).first()]
    if data1 != [None]:
        for item in data1:
            user_id = item['userid']
    data = [session.query(KanbanArticle.id,KanbanArticle.userid,KanbanArticle.content,KanbanArticle.attachment,KanbanArticle.reply_num,KanbanArticle.departmentid,KanbanArticle.name,KanbanArticle.is_del,KanbanArticle.addtime,KanbanArticle.lasttime,KefuUser.avatar).join(KefuUser, and_(KefuUser.id==user_id,KanbanArticle.id==itemid,KanbanArticle.is_del==0)).first()]
    author = session.query(KefuUser.avatar,KefuUser.name).filter(KefuUser.id==user_id).all()
    for j in author:
        avatarvocer[j.avatar] = j.name
    for i in data:
        i = dict(i)
        if not i['attachment']:
            i.update({'addtime':i['addtime'].strftime("%Y-%m-%d %H:%M:%S")})
            i.update({'lasttime':i['lasttime'].strftime("%Y-%m-%d %H:%M:%S")})
            i['author'] = avatarvocer.get(i['avatar'])
        else:
            a = json.loads(i['attachment'])
            i.update({'attachment':a})
            i.update({'addtime':i['addtime'].strftime("%Y-%m-%d %H:%M:%S")})
            i.update({'lasttime':i['lasttime'].strftime("%Y-%m-%d %H:%M:%S")})
            i['author'] = avatarvocer.get(i['avatar'])
    return i

def get_article_id_info(itemname:str,iuserid:int,icontent:str,iattachment:str,igroupid:int,isort:int):
    data = session.query(KanbanArticle.id,KanbanArticle.is_del).filter(KanbanArticle.name==itemname,KanbanArticle.userid==iuserid,KanbanArticle.content==icontent,KanbanArticle.attachment==iattachment,KanbanArticle.groupid==igroupid,KanbanArticle.sort==isort).first()
    return data

def add_article(iname:str,iuserid:int,igroupid:int=0):
    article = KanbanArticle(name=iname,content='请输入正文内容',attachment='[]',userid=iuserid,groupid=igroupid,sort=0,is_del=0,departmentid=1,reply_num=0,pushtime=0,is_hide=0)  # 创建一个article对象
    session.add(article)  # 添加到session
    session.commit()  # 提交到数据库
    return 0

def update_article(itemid:int,iname:str,icontent:str,iattachment:str,igroupid:int,isort:int):
    values ={'name':iname,'content':icontent,'attachment':iattachment,
    'groupid':igroupid,'sort':isort}
    data= {}
    for key,value in values.items():
        if(value != None and value != []):
            data[key] = value
    session.query(KanbanArticle).filter(KanbanArticle.id==itemid).update(data)
    session.commit()
    return 0

def del_article(itemid:int):
    session.query(KanbanArticle).filter(KanbanArticle.id==itemid).update({'is_del': 1})
    session.commit()
    return 0

def get_articleid_info(iarticleid:int,iuserid:int):
    data = session.query(KanbanComment.id,KanbanComment.pid,KanbanComment.articleid,KanbanComment.userid,KanbanComment.zan_num,KanbanComment.content,KanbanComment.is_del,KanbanComment.addtime).filter(KanbanComment.articleid==iarticleid,KanbanComment.userid==iuserid).all()
    return data

def update_sort_groupid(itemid:int,isort:int,igroupid:int):
    session.query(KanbanArticle).filter(KanbanArticle.id==itemid).update({'sort':isort,'groupid':igroupid})
    session.commit()
    return 0

def update_sort(itemid:int,isort:int):
    session.query(KanbanArticle).filter(KanbanArticle.id==itemid).update({'sort':isort})
    session.commit()
    return 0

def get_comment_info(iarticleid:int,iuserid:int):
        data = []
        getuserid = []
        groups = {}
        groups1 = {}
        groups2 = {}
        zan_comment = {}
        zan_comment1 = {}
        namecover = {}
        avatarcover = {}
        article_pids = {}
        pidnamecover = {}
        pidavatarcover = {}
        piduseridcover = {}
        get_userid = session.query(KanbanComment.userid).filter(KanbanComment.articleid==iarticleid).all()
        for user_id in get_userid:
            getuserid.append(user_id['userid'])
        result = session.query(KanbanComment.id,KanbanComment.content,KanbanComment.pid,KanbanComment.zan_num,KanbanComment.userid,KanbanComment.addtime,KanbanComment.lasttime,KanbanComment.is_del).filter(KanbanComment.pid==0,KanbanComment.real_pid==0,KanbanComment.userid.in_(getuserid),KanbanComment.articleid==iarticleid,KanbanComment.is_del==0).order_by(KanbanComment.id.desc()).all()
        for group_id in result:
            group_id = dict(group_id)
            group_id.update({'addtime':group_id['addtime'].strftime("%Y-%m-%d %H:%M:%S")})
            group_id.update({'lasttime':group_id['lasttime'].strftime("%Y-%m-%d %H:%M:%S")})
            group_id['child'] = []
            groups[group_id['id']] = group_id
        group_ids = groups.keys()
        is_zan1 = session.query(KanbanZan.commentid,KanbanZan.is_zan).filter(KanbanZan.userid==iuserid,KanbanZan.commentid.in_(group_ids)).all()
        admins = session.query(KanbanComment.id,KanbanComment.userid).filter(KanbanComment.real_pid.in_(group_ids),KanbanComment.is_del==0).all()
        name_avatar = session.query(KefuUser.id,KefuUser.name,KefuUser.avatar).filter(KefuUser.id.in_(getuserid)).all()
        for zan_row1 in is_zan1:
            zan_comment1[zan_row1.commentid] = zan_row1.is_zan
        for i in name_avatar:
            namecover[i.id] = i.name
            avatarcover[i.id] = i. avatar
        for group_id in result:
            group_id = dict(group_id)
            group_id.update({'addtime':group_id['addtime'].strftime("%Y-%m-%d %H:%M:%S")})
            group_id.update({'lasttime':group_id['lasttime'].strftime("%Y-%m-%d %H:%M:%S")})
            if zan_comment1.get(group_id['id']) == 1:
                group_id['is_zan']=1
            else:
                group_id['is_zan']=0
            if namecover.get(group_id['userid']) != None:
                group_id['name'] = namecover.get(group_id['userid'])
                group_id['avatar'] = avatarcover.get(group_id['userid'])
            group_id['child'] = []
            groups[group_id['id']] = group_id
        group_ids = groups.keys()
        for group_id1 in admins:
            group_id1 = dict(group_id1)
            groups1[group_id1['id']] = group_id1
            groups2[group_id1['userid']] = group_id1
        group_ids1 = groups1.keys()
        group_ids2 = groups2.keys()
        is_zan = session.query(KanbanZan.commentid,KanbanZan.is_zan).filter(KanbanZan.userid==iuserid,KanbanZan.commentid.in_(group_ids1)).all()
        for zan_row in is_zan:
            zan_comment[zan_row.commentid] = zan_row.is_zan
        child_pid = session.query(KanbanComment.id,KanbanComment.pid,KanbanComment.real_pid,KanbanComment.userid,KanbanComment.zan_num,KanbanComment.content,KanbanComment.addtime,KanbanComment.lasttime).filter(KanbanComment.id.in_(group_ids1),KanbanComment.is_del==0).all()
        for article_pid in child_pid:
            article_pid = dict(article_pid)
            article_pids[article_pid['userid']] = article_pid
        articleuserids = article_pids.keys()
        pid_name_avatar = session.query(KefuUser.id,KefuUser.name,KefuUser.avatar).filter(KefuUser.id.in_(articleuserids)).all()
        for j in pid_name_avatar:
            pidnamecover[j.id] = j.name
            pidavatarcover[j.id] = j.avatar
        for k in child_pid:
            piduseridcover[k.id] = k.userid
        for article_id in child_pid:
            article_id = dict(article_id)
            article_id.update({'addtime':article_id['addtime'].strftime("%Y-%m-%d %H:%M:%S")})
            article_id.update({'lasttime':article_id['lasttime'].strftime("%Y-%m-%d %H:%M:%S")})
            if zan_comment.get(article_id['id']) == 1:
                article_id['is_zan']=1
            else:
                article_id['is_zan']=0
            if pidnamecover.get(article_id['userid']) != None:
                article_id['name'] = pidnamecover.get(article_id['userid'])
                article_id['avatar'] = pidavatarcover.get(article_id['userid'])
            if pidnamecover.get(article_id['userid']) != None and article_id['pid'] != article_id['real_pid']:
                article_id['reply_userid'] = piduseridcover.get(article_id['pid'])
                article_id['reply_username'] = pidnamecover.get(article_id['reply_userid'])
            groups[article_id['real_pid']]['child'].append(article_id)
        for key,groupss in groups.items():
            data.append(groupss)
        return data

def get_commentid_info(itemid:int):
    data = session.query(KanbanComment.id,KanbanComment.pid,KanbanComment.articleid,KanbanComment.userid,KanbanComment.zan_num,KanbanComment.content,KanbanComment.is_del,KanbanComment.addtime).filter(KanbanComment.id==itemid,KanbanComment.is_del==0).first()
    return data

def del_commentid(itemid:int,iuserid:int):
    session.query(KanbanComment).filter(KanbanComment.id==itemid,KanbanComment.userid==iuserid).update({'is_del': 1})
    session.commit()
    return 0

def add_comment(icontent:str,ipid:int,iarticleid:int,iuserid:int):
    article = KanbanComment(content=icontent,pid=ipid,articleid=iarticleid,userid=iuserid,is_del=0,zan_num=0,real_pid=0)
    session.add(article)
    session.commit()
    return 0

def update_comment(itemid:int,icontent:str,ipid:int,iarticleid:int,iuserid:int):
    session.query(KanbanComment).filter(KanbanComment.id==itemid).update({'content':icontent,'pid':ipid,'articleid':iarticleid,'userid':iuserid},)
    session.commit()
    return 0

def get_content_info(itemcontent:str,ipid:int,iarticleid:int,iuserid:int):
    data = session.query(KanbanComment.id).filter(KanbanComment.content==itemcontent,KanbanComment.pid==ipid,KanbanComment.articleid==iarticleid,KanbanComment.userid==iuserid).first()
    return data

def get_user_rolelist(iuserid:int):
    data = session.query(KanbanDepartmentAdmin.departmentid).filter(KanbanDepartmentAdmin.userid==iuserid).all()
    if data != [None]:
        departmentid = []
        for item in data:
            departmentid.append(item['departmentid'])
        return departmentid

def save_zan(icommentid:int,iuserid:int,ais_zan:int):
    data = session.query(KanbanZan.id).filter(KanbanZan.userid==iuserid,KanbanZan.commentid==icommentid).first()
    if data == None and ais_zan == 1:
        article = KanbanZan(commentid=icommentid,userid=iuserid,is_zan=ais_zan)
        session.add(article)
        session.query(KanbanZan).filter(KanbanZan.commentid==icommentid,KanbanZan.userid==iuserid).update({'is_zan':ais_zan})
        zannum = [session.query(KanbanComment.zan_num).filter(KanbanComment.id==icommentid).first()]
        zan_num = []
        for i in zannum:
            zan_num.append(i['zan_num'])
        zan = zan_num[0] + 1
        session.query(KanbanComment).filter(KanbanComment.id==icommentid).update({'zan_num':zan})
        session.commit()
    elif data != None and ais_zan == 0:
        session.query(KanbanZan).filter(KanbanZan.commentid==icommentid,KanbanZan.userid==iuserid).update({'is_zan':ais_zan})
        zannum = [session.query(KanbanComment.zan_num).filter(KanbanComment.id==icommentid).first()]
        zan_num = []
        for i in zannum:
            zan_num.append(i['zan_num'])
        zan = zan_num[0] - 1
        session.query(KanbanComment).filter(KanbanComment.id==icommentid).update({'zan_num':zan})
        session.commit()
    elif data != None and ais_zan == 1:
        session.query(KanbanZan).filter(KanbanZan.commentid==icommentid,KanbanZan.userid==iuserid).update({'is_zan':ais_zan})
        zannum = [session.query(KanbanComment.zan_num).filter(KanbanComment.id==icommentid).first()]
        zan_num = []
        for i in zannum:
            zan_num.append(i['zan_num'])
        zan = zan_num[0] + 1
        session.query(KanbanComment).filter(KanbanComment.id==icommentid).update({'zan_num':zan})
        session.commit()
    return 0

def get_zan_info(icommentid:str,iuserid:int):
    data = session.query(KanbanZan.id,KanbanZan.commentid,KanbanZan.is_zan,KanbanZan.userid,KanbanZan.addtime).filter(KanbanZan.commentid==icommentid,KanbanZan.userid==iuserid).first()
    return data

def save_departmentadmin(idepartmentid:int,iuserid:int):
    article = KanbanDepartmentAdmin(departmentid=idepartmentid,userid=iuserid)
    session.add(article)
    session.commit()
    return 0

def get_group_info(iname:str,idepartmentid:int,isort:int):
    data = session.query(KanbanGroup.id,KanbanGroup.name,KanbanGroup.departmentid,KanbanGroup.sort,KanbanGroup.is_del,KanbanGroup.addtime).filter(KanbanGroup.name==iname,KanbanGroup.departmentid==idepartmentid,KanbanGroup.sort==isort).first()
    return data

def get_groupid_info(itemid:int):
    data = session.query(KanbanGroup.id,KanbanGroup.name,KanbanGroup.departmentid,KanbanGroup.sort,KanbanGroup.is_del,KanbanGroup.addtime).filter(KanbanGroup.id==itemid,KanbanGroup.is_del==0).first()
    return data

def add_group(iname:str,idepartmentid:int,isort:int):
    article = KanbanGroup(name=iname,departmentid=idepartmentid,sort=isort,is_del=0)
    session.add(article)
    session.commit()
    return 0

def update_group(itemid:int,iname:str,idepartmentid:int,isort:int):
    session.query(KanbanGroup).filter(KanbanGroup.id==itemid).update({'name':iname,'departmentid':idepartmentid,'sort':isort},)
    session.commit()
    return 0

def del_group(itemid:int):
    session.query(KanbanGroup).filter(KanbanGroup.id==itemid).update({'is_del':1},)
    session.commit()
    return 0

def get_groupuserid_info(groupid:int, userid:int):
    data = session.query(KanbanArticle.id,KanbanArticle.sort,KanbanArticle.groupid,KanbanArticle.content,KanbanArticle.attachment,KanbanArticle.addtime,KanbanArticle.reply_num,KanbanArticle.departmentid,KanbanArticle.name,KanbanArticle.is_del).filter(and_(KanbanArticle.groupid==groupid,KanbanArticle.userid==userid)).all()
    return data

def get_depatmentuserid_list(departmentid:int,iuserid:int):
        data = []
        groups = {}
        read_articleid = {}
        group = session.query(KanbanGroup.id,KanbanGroup.sort,KanbanGroup.departmentid,KanbanGroup.name).filter(KanbanGroup.departmentid==departmentid,KanbanGroup.is_del==0).order_by(KanbanGroup.sort.desc()).all()
        for group_id in group:
            group_id = dict(group_id)
            group_id['article']= []
            groups[group_id['id']] = group_id
        group_ids = groups.keys()
        isread = session.query(KanbanRead.articleid).filter(KanbanRead.departmentid==departmentid,KanbanRead.userid==iuserid).all()
        for read_row in isread:
            read_articleid[read_row.articleid] = 1
        article = session.query(KanbanArticle.lasttime,KanbanArticle.userid,KanbanArticle.id,KanbanArticle.sort,KanbanArticle.groupid,KanbanArticle.addtime,KanbanArticle.reply_num,KanbanArticle.name,KanbanArticle.is_del).filter(and_(KanbanArticle.groupid.in_(group_ids),KanbanArticle.departmentid==departmentid,KanbanArticle.is_del==0)).order_by(KanbanArticle.sort.desc()).all()
        for article_id in article:
            article_id = dict(article_id)
            article_id.update({'addtime':article_id['addtime'].strftime("%Y-%m-%d %H:%M:%S")})
            article_id.update({'lasttime':article_id['lasttime'].strftime("%Y-%m-%d %H:%M:%S")})
            if read_articleid.get(article_id['id']) != None and article_id['userid'] != iuserid:
                article_id['is_read'] = 1
            elif article_id['userid'] == iuserid:
                article_id['is_read'] = 1
            else:
                article_id['is_read'] = 0
            groups[article_id['groupid']]['article'].append(article_id)
        for key,groupss in groups.items():
            data.append(groupss)
        return data

def update_sortgroup(itemid:int,isort:int):
    session.query(KanbanGroup).filter(KanbanGroup.id==itemid).update({'sort':isort},)
    session.commit()
    return 0

def get_department_admin_list():
        data = []
        result = session.query(KefuDepartment.id,KefuDepartment.name,KefuDepartment.qywx_id).all()
        for item in result:
            row = {'id':item.id,'name':item.name,'qywx_id':item.qywx_id}
            admins = session.query(KanbanDepartmentAdmin.userid).filter(KanbanDepartmentAdmin.departmentid==item.qywx_id).all()
            userid = []
            for lst in admins:
                userid.append(lst['userid'])
            id_name = session.query(KefuUser.id,KefuUser.name).filter(KefuUser.id.in_(userid)).all()
            row['dep_admin'] = id_name
            data.append(row)
        return data

def get_notread_info(iuserid:int):
    data = []
    departmentid = session.query(KefuUserDepartmentRelation.departmentid).filter(KefuUserDepartmentRelation.userid==iuserid).all()
    department_admin = session.query(KanbanDepartmentAdmin.departmentid).filter(KanbanDepartmentAdmin.userid==iuserid).all()
    departmentadmin = []
    for i in department_admin:
        departmentadmin.append(i['departmentid'])
    department = []
    for item in departmentid:
        department.append(item['departmentid'])
    department.append(1)
    departmentlist = department.append(departmentadmin)
    if 1 in departmentadmin:
        result = session.query(KefuDepartment.qywx_id,KefuDepartment.name).filter(KefuDepartment.qywx_id.in_([1,1002,4,5,6,8,13,14,15,16,20,30])).all()
        department = [1,4,5,6,8,13,14,15,16,20,30,1002]
    else:
        result = session.query(KefuDepartment.qywx_id,KefuDepartment.name).filter(KefuDepartment.qywx_id.in_(departmentlist)).all()
    for rows in result:
        row = {'id':rows.qywx_id,'name':rows.name}
        lst = []
        for department_id in department:
            lst.append(department_id)
        n = result.index(rows)
        artgroup = session.query(KanbanArticle.groupid).filter(KanbanArticle.departmentid==department[n],KanbanArticle.userid!=iuserid,KanbanArticle.is_del==0).all()
        artgroupid = []
        for artgroup_id in artgroup:
            artgroupid.append(artgroup_id['groupid'])
        group = session.query(KanbanGroup.id).filter(KanbanGroup.id.in_(artgroupid),KanbanGroup.is_del==0).all()
        groupid = []
        for group_id in group:
            groupid.append(group_id['id'])
        tgroupid = [x for x in artgroupid if x in groupid]
        readarticle = session.query(KanbanRead.articleid).filter(KanbanRead.departmentid==department[n],KanbanRead.userid==iuserid).all()
        readarticleid = []
        for readarticle_id in readarticle:
            readarticleid.append(readarticle_id['articleid'])
        article = session.query(KanbanArticle.groupid).filter(KanbanArticle.id.in_(readarticleid),KanbanArticle.userid!=iuserid,KanbanArticle.is_del==0).all()
        articleid = []
        for article_id in article:
            articleid.append(article_id['groupid'])
        did = [x for x in articleid if x  in groupid]
        not_read = len(tgroupid) - len(did)
        row['not_read'] = not_read
        data.append(row)
    return data


from cmath import nan
from hashlib import new
from math import floor
import os, nrrd, json, numpy as np
import cupy as cp
import cupyx.scipy.ndimage
import scipy.ndimage
import time

def exportNormalisedNrrdAndAnnotation(nrrdFilePath=None, annotationFilePath=None, exportNrrdPath=None, exportAnnotationPath=None, debug=False):
	if nrrdFilePath is None or annotationFilePath is None or (exportAnnotationPath is None and exportNrrdPath is None and not debug):
		return

	if exportNrrdPath is not None:
		if not os.path.exists(exportNrrdPath):
			os.makedirs(exportNrrdPath)
	if exportAnnotationPath is not None:
		if not os.path.exists(exportAnnotationPath):
			os.makedirs(exportAnnotationPath)

	nrrdFileName = os.path.basename(nrrdFilePath)
	annotationFileName = os.path.basename(annotationFilePath)

	nrrdFileData, nrrdFileHeader = nrrd.read(nrrdFilePath, index_order='C')
	#print(nrrdFileData.dtype)scipy.ndimage.zoom

	space_directions = nrrdFileHeader['space directions']
	origin = nrrdFileHeader['space origin']

	m_RAS_To_IJK = np.array([
			[1 / space_directions[1, 0], 0, 0, -origin[0]/space_directions[1, 0]],
			[0, 1 / space_directions[2, 1], 0, -origin[1]/space_directions[2, 1]],
			[0, 0, 1 / space_directions[3, 2], -origin[2]/space_directions[3, 2]],
			[0, 0, 0, 1],
		])

	m_old_to_new = np.array([
			[space_directions[1, 0], 0, 0, 0],
			[0, space_directions[2, 1], 0, 0],
			[0, 0, space_directions[3, 2], 0],
			[0, 0, 0, 1],
		])

	if exportNrrdPath is not None or debug:
		print("Exporting Adjusted NRRD For", os.path.basename(nrrdFilePath), '...')
		if os.path.isfile(os.path.join(exportNrrdPath, nrrdFileName)) and os.path.exists(os.path.join(exportNrrdPath, nrrdFileName)) and not debug:
			print('File Exists')
		else:
			time_start = time.process_time()
			data_shape = np.array(nrrdFileData.shape)
			new_data_array = np.empty(np.rint(data_shape*np.array([space_directions[3, 2], space_directions[2, 1], space_directions[1, 0], 1])).astype(int), dtype=np.float64)

			for t in range(new_data_array.shape[3]):
				new_data_array[:,:,:,t] = cupyx.scipy.ndimage.zoom(cp.array(nrrdFileData[:,:,:,t], dtype=cp.float64), [space_directions[3, 2], space_directions[2, 1], space_directions[1, 0]], output=cp.float64).get()

			new_data_array[new_data_array>254.5] = 255
			new_data_array[new_data_array<0.5] = 0

			new_data_array = new_data_array.astype(np.uint8)

			elapsed_time = time.process_time() - time_start
			print('Zoom DONE. Zoom Time used:', elapsed_time)
			time_start = time.process_time()

			newNrrdHeader = {}
			for key, val in nrrdFileHeader.items():
				if key == 'type' or key == 'endian' or key == 'dimension' or key == 'sizes':
					continue
				newNrrdHeader[key] = val
				#print(key, val)

			newNrrdHeader['space directions'] = [[nan, nan, nan], [1, 0, 0], [0, 1, 0], [0, 0, 1]]
			newNrrdHeader['space origin'] = [0, 0, 0]

			if exportNrrdPath is not None:
				nrrd.write(os.path.join(exportNrrdPath, nrrdFileName), new_data_array, header=newNrrdHeader, index_order='C')
			elapsed_time2 = time.process_time() - time_start
			print('Export DONE. Export Time used:', elapsed_time2)
			print('Total Time used:', elapsed_time + elapsed_time2)
			print('--------------------------------------------------')

	if exportAnnotationPath is not None:
		with open(annotationFilePath, 'r') as f:
			jsonData = json.load(f)

		jsonData['adjusted'] = {
			'oldSpacing': [space_directions[1, 0], space_directions[2, 1], space_directions[3, 2]],
			'points': [],
			'planes': [],
		}

		for point_data in jsonData['fidData']:
			jsonData['adjusted']['points'].append({
				'Structure Name': point_data['Structure Name'],
				'Position-IJK': (np.array(point_data['Position-IJK']) * np.array([space_directions[1, 0], space_directions[2, 1], space_directions[3, 2]])).tolist(),
				'View Name': point_data['View Name'],
				'Time': point_data['Time'],
				'Time Index': point_data['Time Index'],
			})

		for plane_data in jsonData['planeData']:
			colour = plane_data['colour']
			if 'SliceToIJK' in plane_data:
				m_slice_to_IJK = np.array(plane_data['SliceToIJK']).reshape(4, 4)
			else:
				m_slice_to_RAS = np.array(plane_data[colour]['SliceToRAS']).reshape(4, 4)
				m_slice_to_IJK = np.matmul(m_RAS_To_IJK, m_slice_to_RAS)
			m_slice_to_new_IJK = np.matmul(m_old_to_new, m_slice_to_IJK)

			jsonData['adjusted']['planes'].append({
				'FieldOfView': plane_data[colour]['FieldOfView'],
				'Dimensions': plane_data[colour]['Dimensions'],
				'Origin': plane_data[colour]['Origin'],
				'SliceToIJK': m_slice_to_new_IJK.flatten().tolist(),
				'view': plane_data['view'],
				'timeIndex': plane_data['timeIndex'],
			})

		with open(os.path.join(exportAnnotationPath, annotationFileName), 'w+') as f:
			json.dump(jsonData, f)

if __name__ == '__main__':

	ANNOTATION_PATH = 'E:/Datasets/Annotations/All Annotations/Normal Annotations/11-10-2021-annotations/PWHOR190733599Q_11Oct2021_CWJKF3OP_3DQ.json'
	NRRD_PATH = 'E:/Datasets/Echocardio/CU/11-10-2021-3d-nrrd/PWHOR190733599Q_11Oct2021_CWJKF3OP_3DQ.seq.nrrd'
	EXPORT_PATH = 'E:/FYP/Nrrd Spacing/Normal-Export-gpu2'

	exportCorrectNrrdAndAnnotation(nrrdFilePath=NRRD_PATH, annotationFilePath=ANNOTATION_PATH, exportNrrdPath=EXPORT_PATH, exportAnnotationPath=None, debug=True)

	exit(0)

	NRRD_NORMAL = 'E:/FYP/Nrrd Spacing/Normal-Export-cpu/PWHOR190733599Q_11Oct2021_CWJKF3OP_3DQ.seq.nrrd'
	NRRD_GPU = 'E:/FYP/Nrrd Spacing/Normal-Export-gpu2/PWHOR190733599Q_11Oct2021_CWJKF3OP_3DQ.seq.nrrd'

	nrrdFileDataCpu, nrrdFileHeaderCpu = nrrd.read(NRRD_NORMAL, index_order='C')
	nrrdFileDataGpu, nrrdFileHeaderGpu = nrrd.read(NRRD_GPU, index_order='C')

	same_array = nrrdFileDataCpu == nrrdFileDataGpu
	diff_array2 = nrrdFileDataCpu != nrrdFileDataGpu
	diff_array = np.absolute(nrrdFileDataCpu[np.logical_not(same_array)] - nrrdFileDataGpu[np.logical_not(same_array)])
	print(np.prod(nrrdFileDataCpu.shape) - np.sum(same_array))
	print(np.sum(diff_array2))
	print(diff_array.shape[0]/np.prod(nrrdFileDataCpu.shape)*100, '%')
	print(diff_array.shape[0], np.prod(nrrdFileDataCpu.shape))
	print(np.mean(diff_array))
	print(np.max(diff_array))
	print(np.min(diff_array))

	print('==================================')

	print(np.sum(nrrdFileDataCpu[nrrdFileDataCpu==255]))

	exit(0)


import os
import cv2
import numpy as np
from scipy.spatial.transform import Rotation

ARUCO_DICT = {
    "DICT_4X4_50": cv2.aruco.DICT_4X4_50,
    "DICT_4X4_100": cv2.aruco.DICT_4X4_100,
    "DICT_4X4_250": cv2.aruco.DICT_4X4_250,
    "DICT_4X4_1000": cv2.aruco.DICT_4X4_1000,
    "DICT_5X5_50": cv2.aruco.DICT_5X5_50,
    "DICT_5X5_100": cv2.aruco.DICT_5X5_100,
    "DICT_5X5_250": cv2.aruco.DICT_5X5_250,
    "DICT_5X5_1000": cv2.aruco.DICT_5X5_1000,
    "DICT_6X6_50": cv2.aruco.DICT_6X6_50,
    "DICT_6X6_100": cv2.aruco.DICT_6X6_100,
    "DICT_6X6_250": cv2.aruco.DICT_6X6_250,
    "DICT_6X6_1000": cv2.aruco.DICT_6X6_1000,
    "DICT_7X7_50": cv2.aruco.DICT_7X7_50,
    "DICT_7X7_100": cv2.aruco.DICT_7X7_100,
    "DICT_7X7_250": cv2.aruco.DICT_7X7_250,
    "DICT_7X7_1000": cv2.aruco.DICT_7X7_1000,
    "DICT_ARUCO_ORIGINAL": cv2.aruco.DICT_ARUCO_ORIGINAL,
    "DICT_APRILTAG_16h5": cv2.aruco.DICT_APRILTAG_16h5,
    "DICT_APRILTAG_25h9": cv2.aruco.DICT_APRILTAG_25h9,
    "DICT_APRILTAG_36h10": cv2.aruco.DICT_APRILTAG_36h10,
    "DICT_APRILTAG_36h11": cv2.aruco.DICT_APRILTAG_36h11
}

def AnalyseVideo(main_config, tests_config):

    for test_config in tests_config:
        world_name = main_config.world_file[:-4]
        test_name = test_config.test_name

        capture_pose = test_config.vid_pose_file
        capture_marker_corner = test_config.marker_corner_file

        print(f"[INFO] Analysing Video of test: {test_name}")

        test_dir = os.path.join(main_config.test_files_path, "Tests", test_config.test_name)
        if not os.path.exists(test_dir):  # Check if test dir exists
            print("[ERR] " + test_name + " test does not exist. Skipping")
            continue

        pose_dir = os.path.join(test_dir, "marker_pose")
        if capture_pose:
            if not os.path.exists(pose_dir):
                os.mkdir(pose_dir)
        else:
            print(f"[INFO] For {test_name}, not capturing pose info")

        marker_corner_dir = os.path.join(test_dir, "marker_corners")
        if capture_marker_corner:
            if not os.path.exists(os.path.join(marker_corner_dir)):
                os.mkdir(marker_corner_dir)
        else:
            print(f"[INFO] For, {test_name} not capturing marker area")

        # Create dictionary to store all marker info for the specific test.
        marker_info_by_dict = {}

        for marker in test_config.markers:
            dictionary = marker.dictionary
            id = marker.id
            size = marker.size
            pose = marker.pose

            if dictionary not in marker_info_by_dict:
                marker_info_by_dict[dictionary] = []

            marker_info_by_dict[dictionary].append((id, size, pose))

        # -- Video file for each camera used in the test (some cameras record with more than one lens)
        for camera in test_config.cameras:
            camera_name = camera.camera_file[:-4]

            if test_config.video_file:
                topic_names = camera.config.get_all_topic_names()
                for topic_name in topic_names:
                    video_name = f"vid_{camera_name}_{topic_name}"
                    video_file = f"{video_name}.mp4"
                    video_file_dir = os.path.join(test_dir, video_file)

                    if not os.path.exists(video_file_dir):
                        print("[ERR] video" + video_file_dir + " does not exist. Skipping test")
                        continue
                    else:

                        if capture_pose:
                            marker_files = create_marker_files(test_config.markers,
                                                               pose_dir, video_name, "poses")
                            _ExtractPoseFromVideo(video_file_dir, video_name, marker_info_by_dict, marker_files)

                        if capture_marker_corner:
                            marker_files = create_marker_files(test_config.markers,
                                                               marker_corner_dir, video_name, "corners")
                            _ExtractMarkerCornersFromVideo(video_file_dir, video_name, marker_info_by_dict, marker_files)

def _ExtractPoseFromVideo(video_file, video_name, marker_info_by_dict, marker_files):

    print("[INFO] Extracting pose")

    cap = cv2.VideoCapture(video_file)

    aruco_dicts = list(marker_info_by_dict.keys())

    # Define the camera matrix (replace with your own values)
    camera_matrix = np.array([[1188.3078, 0, 638.71195], [0, 1188.66076, 355.72245], [0, 0, 1]], dtype=np.float32)

    # Define the distortion coefficients (replace with your own values)
    dist_coeffs = np.zeros((4, 1), dtype=np.float32)

    width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
    height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
    fps = cap.get(cv2.CAP_PROP_FPS)

    output_video_path = video_file[:-4] + "_edit.mp4"  # Specify the desired output video path
    framerate = float(24)
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    frame = (1280, 720)
    # Width then height
    output_video = cv2.VideoWriter(output_video_path, fourcc, framerate, (frame[0], frame[1]))

    while cap.isOpened():

        ret, frame = cap.read()
        if not ret:
            break

        # Detect markers in the frame
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        # parameters = cv2.aruco.DetectorParameters()  # PC
        parameters = cv2.aruco.DetectorParameters_create()  # Laptop
        current_time = cap.get(cv2.CAP_PROP_POS_FRAMES) / cap.get(cv2.CAP_PROP_FPS)

        for idx, aruco_dict_str in enumerate(aruco_dicts):

            aruco_dict = cv2.aruco.getPredefinedDictionary(ARUCO_DICT[aruco_dict_str])

            corners, ids, rejected = cv2.aruco.detectMarkers(gray, aruco_dict, parameters=parameters)

            if len(corners) > 0:
                for i, id in enumerate(ids):

                    # Estimate the pose of each marker
                    marker_size, pose = get_size_and_pose(aruco_dict_str, float(id), marker_info_by_dict)

                    rvecs, tvecs, _ = cv2.aruco.estimatePoseSingleMarkers(corners, marker_size, camera_matrix, dist_coeffs)

                    # Draw a bounding box around the marker
                    cv2.aruco.drawDetectedMarkers(frame, corners)
                    frame = cv2.drawFrameAxes(frame, camera_matrix, dist_coeffs, rvecs[i], tvecs[i], marker_size)

                    marker_pos = np.array([pose.X, pose.Y, pose.Z])
                    marker_rot = np.array([pose.r, pose.p, pose.y])  # In Radians
                    R_marker = Rotation.from_euler('XYZ', marker_rot, degrees=False).as_matrix()

                    marker_pose = np.concatenate((R_marker, marker_pos.reshape(-1, 1)), axis=1)
                    marker_pose = np.vstack((marker_pose, [0, 0, 0, 1]))

                    # Calculate pose between markers and cameras
                    R, _ = cv2.Rodrigues(rvecs[i])
                    pose_mark_rel_cam = np.concatenate((R, tvecs[i].reshape(-1, 1)), axis=1)
                    pose_mark_rel_cam = np.vstack((pose_mark_rel_cam, [0, 0, 0, 1]))
                    pose_cam_rel_mark = np.linalg.inv(pose_mark_rel_cam)
                    #
                    # # Extract the translation and rotation components
                    # print(camera_pose*marker_pos)
                    pose_cam_world = marker_pose@pose_cam_rel_mark
                    pos_cam_world = pose_cam_world[:3,3]

                    rot_cam_world = np.deg2rad(cv2.RQDecomp3x3(pose_cam_world[:3, :3])[0])

                    R_remap = np.array([[0, 1, 0], [-1, 0, 0], [0, 0, 1]])
                    t_remap = np.concatenate((R_remap, np.array([[0],[0],[0]])), axis=1)
                    t_remap = np.vstack((t_remap, [0, 0, 0, 1]))

                    remap_pose = marker_pose  @ (t_remap @ pose_cam_rel_mark)

                    remap_rot = np.around(Rotation.from_matrix(remap_pose[:3,:3]).as_euler('XYZ', degrees=True))
                    remap_rot[2] = remap_rot[2] + 90
                    if remap_rot[2] > 180:
                        remap_rot[2] = remap_rot[2] - 360

                    # Remapping end ------------------------------
                    marker_name = aruco_dict_str + "_s" + str(int(marker_size*1000)) + "_id" + str(id)
                    lbl_marker_name = f"Marker ID: {marker_name}"
                    lbl_marker_pose = f"Marker Pos: {np.around(marker_pos, decimals=2)} Cam rot: {np.around(marker_rot, decimals=2)}"  # Print in Deg
                    lbl_marker_rel_cam = f"Marker relative Cam: {np.around(pose_mark_rel_cam[:3,3], decimals=2)} Cam rot: {np.around(Rotation.from_matrix(pose_mark_rel_cam[:3,:3]).as_euler('XYZ', degrees=True), decimals=2)}"
                    lbl_cam_rel_marker = f"Cam relative Marker: {np.around(pose_cam_rel_mark[:3,3], decimals=2)} Cam rot: {np.around(Rotation.from_matrix(pose_cam_rel_mark[:3,:3]).as_euler('XYZ', degrees=True), decimals=2)}"
                    lbl_cam_glob_pose = f"Global Cam Pos: {np.around(pos_cam_world, decimals=2)} Cam rot: {np.rad2deg(np.around(rot_cam_world, decimals=2))}"
                    lbl_remap = f"Remapped Cam Pos: {np.around(remap_pose[:3,3], decimals=2)} Cam rot: {remap_rot}"

                    # print("New Frame (all angles in deg")
                    # print(lbl_marker_pose)
                    # print(lbl_marker_rel_cam)
                    # print(lbl_cam_rel_marker)
                    # print(lbl_cam_glob_pose)
                    # print(lbl_remap)

                    # Display the tag ID and pose information
                    cv2.putText(frame, lbl_marker_name, (int(corners[i][0][0][0]), int(corners[i][0][0][1] - 35)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 125, 125), 1, cv2.LINE_AA)
                    cv2.putText(frame, lbl_marker_pose, (int(corners[i][0][0][0]), int(corners[i][0][0][1] - 20)),
                                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 125, 125), 1, cv2.LINE_AA)
                    cv2.putText(frame, lbl_remap, (int(corners[i][0][0][0]), int(corners[i][0][0][1] - 5)),
                                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 125, 125), 1, cv2.LINE_AA)
                    # cv2.putText(frame, lbl_cam_glob_pose, (0, 70), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 125, 125), 1, cv2.LINE_AA)
                    # cv2.putText(frame, lbl_remap, (0, 25*(idx+1)*(i+1)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 125, 125), 1, cv2.LINE_AA)

                    marker_info = (aruco_dict_str, int(id), video_name)
                    file_handler = marker_files[marker_info]

                    write_pose_to_file(file_handler, remap_pose[:3,3], remap_rot, current_time)

            # Show the frame
            cv2.imshow('Pose Estimation', frame)
            output_video.write(frame)

        #

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    cap.release()
    cv2.destroyAllWindows()
    output_video.release()

def get_size_and_pose(dictionary, id, marker_info_by_dict):
    if dictionary in marker_info_by_dict:
        marker_info_list = marker_info_by_dict[dictionary]
        for marker_id, size, pose in marker_info_list:
            if marker_id == id:
                return size, pose
    return None, None

def create_marker_files(markers, file_dir, video_name, data_identifier):
    marker_files = {}
    for marker in markers:
        dictionary = marker.dictionary
        marker_id = marker.id
        file_name = f"marker_{dictionary}_{marker_id}_{video_name}_{data_identifier}.txt"
        file_path = os.path.join(file_dir, file_name)

        if os.path.exists(file_path):
            # If the file exists, clear its content by opening it in write mode with 'w'
            file_handler = open(file_path, "w")
        else:
            # If the file does not exist, create it by opening it in write mode with 'x'
            file_handler = open(file_path, "x")

        marker_files[(dictionary, marker_id, video_name)] = file_handler
    return marker_files

def write_pose_to_file(file_handler, position, orientation, current_time):
    pose_info = f"{position[0]},{position[1]},{position[2]},{orientation[0]},{orientation[1]},{orientation[2]},{current_time}\n"
    file_handler.write(pose_info)

def _ExtractMarkerCornersFromVideo(video_file, video_name, marker_info_by_dict, marker_files):

    print("[INFO] Extracting marker corners")

    cap = cv2.VideoCapture(video_file)
    aruco_dicts = list(marker_info_by_dict.keys())

    # Define the camera matrix (replace with your own values)
    camera_matrix = np.array([[1188.3078, 0, 638.71195], [0, 1188.66076, 355.72245], [0, 0, 1]], dtype=np.float32)

    # Define the distortion coefficients (replace with your own values)
    dist_coeffs = np.zeros((4, 1), dtype=np.float32)

    width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
    height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
    fps = cap.get(cv2.CAP_PROP_FPS)

    framerate = float(24)
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    frame = (1280, 720)

    while cap.isOpened():

        ret, frame = cap.read()
        if not ret:
            break

        # Detect markers in the frame
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        # parameters = cv2.aruco.DetectorParameters()  # PC
        parameters = cv2.aruco.DetectorParameters_create()  # Laptop
        current_time = cap.get(cv2.CAP_PROP_POS_FRAMES) / cap.get(cv2.CAP_PROP_FPS)

        for idx, aruco_dict_str in enumerate(aruco_dicts):

            aruco_dict = cv2.aruco.getPredefinedDictionary(ARUCO_DICT[aruco_dict_str])
            corners, ids, rejected = cv2.aruco.detectMarkers(gray, aruco_dict, parameters=parameters)

            if len(corners) > 0:
                for i, id in enumerate(ids):

                    marker_size, pose = get_size_and_pose(aruco_dict_str, float(id), marker_info_by_dict)
                    marker_name = aruco_dict_str + "_s" + str(int(marker_size * 1000)) + "_id" + str(id)
                    marker_info = (aruco_dict_str, int(id), video_name)
                    file_handler = marker_files[marker_info]

                    write_corners_to_file(file_handler, corners[0][0], current_time)

            # Show the frame
            # cv2.imshow('Marker Area', frame)

        # if cv2.waitKey(1) & 0xFF == ord('q'):
        #     break

    # cap.release()
    # cv2.destroyAllWindows()

def write_corners_to_file(file_handler, corners, current_time):
    pose_info = f"{corners[0]},{corners[1]},{corners[2]},{corners[3]},{current_time}\n"
    file_handler.write(pose_info)


import openai
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize, sent_tokenize
from collections import defaultdict

openai.api_key = "API_KEY"

# Función para identificar los temas principales utilizando la API de OpenAI
def get_topics(dialogue):
    response = openai.Completion.create(
        engine="davinci",
        prompt="Identify the main topics in the following dialogue: " + dialogue,
        max_tokens=60,
        n=1,
        stop=None,
        temperature=0.5,
    )
    topic = response.choices[0].text.strip()
    return topic

dialogues = ["Diálogo 1", "Diálogo 2", "Diálogo 3"]

# Crea un diccionario para almacenar las oraciones relevantes de cada diálogo
dialogue_summaries = defaultdict(list)

# Preprocesamos los datos
stop_words = set(stopwords.words('spanish'))

for dialogue in dialogues:
    # Identifica los temas principales utilizando la API de OpenAI
    topics = get_topics(dialogue)
    # Tokeniza las oraciones
    sentences = sent_tokenize(dialogue.lower())
    for sentence in sentences:
        # Tokeniza las palabras de la oración y elimina las palabras vacías y los signos de puntuación
        words = [word for word in word_tokenize(sentence) if word.isalnum() and word not in stop_words]
        for topic in topics:
            if topic.lower() in sentence.lower():
                # Si la oración contiene uno de los temas principales, la agregam al resumen del diálogo correspondiente
                dialogue_summaries[dialogue].append(sentence)

# Genera el resumen de cada diálogo
for dialogue, sentences in dialogue_summaries.items():
    print("Resumen del diálogo:")
    print(" ".join(sentences))


from sklearn.preprocessing import MinMaxScaler
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns

np.random.seed(0)
sns.set(font_scale=0.5)

df_main = pd.read_csv('data/jorge.csv', sep='\t', index_col=0)
df_main['Class'] = df_main['Class'].map({'YES': 1, 'NO': 0})
# df_class = df_main.pop('Class')
# df_main.pop('Time')

scaler = MinMaxScaler()
df_main[df_main.columns] = scaler.fit_transform(df_main[df_main.columns])

n_clusters = (2, 2)

my_palette = dict(zip(df_main.Class.unique(), ['orange', 'brown']))
row_colors = df_main.Class.map(my_palette)
df_main.pop('Class')

# my_palette2 = dict(zip(df_main.Time.unique(), sns.color_palette("RdBu_r", 7)))
# row_colors2 = df_main.Time.map(my_palette2)
# df_main.pop('Time')

data = df_main

methods = ['average']
# methods = ['ward', 'median', 'centroid', 'single', 'average', 'complete', 'weighted']

for method in methods:
    sns.clustermap(data, method=method, xticklabels=True, yticklabels=True, row_colors=[row_colors],
                   cmap="Blues")
    fig = plt.gcf()
    fig.set_size_inches(10, 10)
    plt.title(method)
    plt.savefig('heatmap-' + method + '.png', dpi=300)
    plt.savefig('heatmap-' + method + '.eps', format='eps')
# plt.show()


import os
import openai
import wandb

openai.api_key = ""#key deleted before uploading to github repo

run = wandb.init(project='GPT-3 in Python')
prediction_table = wandb.Table(columns=["prompt", "completion"])

gpt_prompt = "Make a list of astronomical observatories:"
#gpt_prompt = "Please list the steps to remove an item from a box in iManage Records Manager???"
#gpt_prompt = "Respond in a pirate dialect to the following question, Is iManage Records Manager vulnerable to log4j???"
#gpt_prompt = "The trend toward lower rents may seem surprising given that some communities in New York are bemoaning the loss of favorite local businesses to high rents. But, despite the recent softening, for many of these retailers there's still been too big a jump from the rental rates of the late 1970s, when their leases were signed. Certainly, the recent drop in prices doesn't mean Manhattan comes cheap. Human-supplied input : question: Manhattan comes cheap. true, false, or neither?"

response = openai.Completion.create(
  engine="davinci:ft-personal-2022-09-06-18-40-06",
  prompt=gpt_prompt,
  temperature=0.83,
  max_tokens=30,
  top_p=1.0,
  frequency_penalty=0.0,
  presence_penalty=0.0,
  stop="###"
)

print(response['choices'][0]['text'])

prediction_table.add_data(gpt_prompt,response['choices'][0]['text'])

wandb.log({'predictions': prediction_table})
wandb.finish()


import torch
import os
import numpy as np
import scipy.sparse as sp
import json
import scipy.io as scio

from ordered_set import OrderedSet

def l2_loss(a, b):
    return ((a - b) ** 2).sum() / (len(a) * 2)

class DATA_LOADER:
    def __init__(self, args):
        # load KG graph
        self.build_graph(args)

        if args.DATASET == 'AwA2':
            self.read_awa(args)
        else:
            self.read_imagenet(args)

    def read_awa(self, args):
        split = json.load(open(os.path.join(args.DATA_DIR, args.DATASET, 'class.json')))
        seens, unseens = split['seen'], split['unseen']
        seen_wnids, unseen_wnids = list(seens.keys()), list(unseens.keys())
        # print(seen_wnids)
        seen_names = [seens[wnid] for wnid in seen_wnids]
        unseen_names = [unseens[wnid] for wnid in unseen_wnids]

        print("Loading Training Data ...")
        # training data: averaged seen features
        matcontent = scio.loadmat(os.path.join(args.DATA_DIR, args.DATASET, 'att_splits.mat'))
        class_names = matcontent['allclasses_names'].squeeze().tolist()

        feat_matcontent = scio.loadmat(os.path.join(args.DATA_DIR, args.DATASET, 'res101.mat'))
        features = feat_matcontent['features'].T
        labels = feat_matcontent['labels'].astype(int).squeeze() - 1

        train_idx = list()
        feat_set = list()

        for i, name in enumerate(seen_names):
            train_idx.append(self.nodes_dict[seen_wnids[i]])
            sample_label = class_names.index(name)
            feat_index = np.where(labels == sample_label)
            cls_feats = features[feat_index]
            cls_feats = np.mean(cls_feats, axis=0)  # (2048)
            feat_set.append(cls_feats)

        self.fc_vectors = np.vstack(tuple(feat_set))

        print("Loading Test Set ...")
        test_idx = [self.nodes_dict[unseen_wnids[i]] for i, name in enumerate(unseen_names)]

        self.train_idx = train_idx
        self.test_idx = test_idx
        self.all_nodes = class_names
        self.seen_classes = seen_wnids
        self.unseen_classes = unseen_wnids
        self.seen_names = seen_names
        self.unseen_names = unseen_names

    def read_imagenet(self, args):

        seen_file = os.path.join(args.DATA_DIR, args.DATASET, 'seen.txt')
        unseen_file = os.path.join(args.DATA_DIR, args.DATASET, 'unseen.txt')
        seen_wnids = [line[:-1] for line in open(seen_file)]
        unseen_wnids = [line[:-1] for line in open(unseen_file)]

        print("Loading Training Data ...")
        # training data: averaged seen features
        Seen_Feat = os.path.join(args.DATA_DIR, 'ImageNet', 'Res101_Features/ILSVRC2012_train')
        matcontent = scio.loadmat(os.path.join(args.DATA_DIR, 'ImageNet', 'split.mat'))
        allwnids = matcontent['allwnids'].squeeze().tolist()

        train_idx = list()
        feat_set = list()
        for wnid in seen_wnids:
            train_idx.append(self.nodes_dict[wnid])
            feat_index = allwnids.index(wnid) + 1
            feat_path = os.path.join(Seen_Feat, str(feat_index) + '.mat')
            seen_feat = np.array(scio.loadmat(feat_path)['features'])
            feats = np.mean(seen_feat, axis=0)  # (2048)
            feat_set.append(feats)
        self.fc_vectors = np.vstack(tuple(feat_set))

        print("Loading Test Set ...")
        test_idx = [self.nodes_dict[wnid] for wnid in unseen_wnids]

        self.train_idx = train_idx
        self.test_idx = test_idx
        self.all_nodes = allwnids
        self.seen_classes = seen_wnids
        self.unseen_classes = unseen_wnids

    def build_graph(self, args):
        KG_file_path = os.path.join(args.DATA_DIR, args.DATASET, 'KG_file', 'KG_triples_hie_att.txt')

        ent_set, rel_set = OrderedSet(), OrderedSet()
        triples = list()

        for line in open(KG_file_path):
            sub, rel, obj = line.strip().split('\t')
            # remove namespace prefix
            sub, obj = sub.split(':')[1], obj.split(':')[1]
            ent_set.add(sub)
            ent_set.add(obj)
            rel_set.add(rel)
            triples.append((sub, rel, obj))

        nodes = list(ent_set)
        n = len(nodes)
        nodes_dict = {node: i for i, node in enumerate(nodes)}

        edges = [(nodes_dict[h], nodes_dict[t]) for (h, r, t) in triples]

        print("Number of nodes: {}, Number of edges: {}".format(len(nodes), len(edges)))

        # + inverse edges and reflexive edges
        edges = edges + [(v, u) for (u, v) in edges]
        edges = edges + [(u, u) for u in range(n)]
        edges = np.array(edges)
        adj = sp.coo_matrix((np.ones(len(edges)), (edges[:, 0], edges[:, 1])),
                            shape=(n, n), dtype='float32')
        adj = normt_spm(adj, method='in')
        adj = spm_to_tensor(adj)

        all_feats = []
        for _ in nodes:
            feat = np.random.uniform(low=-1, high=1, size=args.input_dim)
            feat = feat / (np.linalg.norm(feat) + 1e-6)
            all_feats.append(feat)
        all_feats = np.array(all_feats)

        self.nodes_dict = nodes_dict
        self.adj = adj
        self.inputs = all_feats

def normt_spm(mx, method='in'):
    if method == 'in':
        mx = mx.transpose()
        rowsum = np.array(mx.sum(1))
        r_inv = np.power(rowsum, -1).flatten()
        r_inv[np.isinf(r_inv)] = 0.
        r_mat_inv = sp.diags(r_inv)
        mx = r_mat_inv.dot(mx)
        return mx

    if method == 'sym':
        rowsum = np.array(mx.sum(1))
        r_inv = np.power(rowsum, -0.5).flatten()
        r_inv[np.isinf(r_inv)] = 0.
        r_mat_inv = sp.diags(r_inv)
        mx = mx.dot(r_mat_inv).transpose().dot(r_mat_inv)
        return mx

def spm_to_tensor(sparse_mx):
    sparse_mx = sparse_mx.tocoo().astype(np.float32)
    indices = torch.from_numpy(np.vstack(
            (sparse_mx.row, sparse_mx.col))).long()
    values = torch.from_numpy(sparse_mx.data)
    shape = torch.Size(sparse_mx.shape)
    return torch.sparse.FloatTensor(indices, values, shape)


# import django models/libraries
from django.contrib.auth.models import User

# import DRF models/libraries
from rest_framework import serializers, status
from rest_framework.response import Response

# import external libraries
from taggit.serializers import TagListSerializerField, TaggitSerializer

# import project/app stuff
from common.utils import FileUploadField, FileValidator
from common.utils.check_url_status import is_valid_url

from .models import Location, Upload, Comment, Link, FileBookmark
from users.models import CustomUser
from users.serializers import UserSerializer

from geolocation.models import Location
from django.contrib.gis.geos import Point as GEOSPoint

class LinkSerializer(serializers.ModelSerializer):
    class Meta:
        model = Link
        fields = "__all__"
        ordering = ["created"]

class LocationSerializer(serializers.ModelSerializer):
    class Meta:
        model = Location
        fields = "__all__"
        ordering = ["created"]

class TagSearchSerializer(TaggitSerializer, serializers.ModelSerializer):
    search_tag = serializers.CharField()

    class Meta:
        model = Upload
        fields = ["search_tag"]

class UploadPostSerializer(TaggitSerializer, serializers.ModelSerializer):
    # user is logged in user
    # readonly=True, because upload user is unique
    # PrimaryKeyRelatedField takes user instance
    user = serializers.PrimaryKeyRelatedField(read_only=True)
    location = serializers.CharField(max_length=200)
    zip_code = serializers.IntegerField()
    address = serializers.CharField(max_length=50, required=False)
    media_type = serializers.CharField(read_only=True)
    file = FileUploadField(validators=[FileValidator()])
    link = serializers.CharField(max_length=250)
    tags = TagListSerializerField()

    class Meta:
        model = Upload
        fields = "__all__"
        # exclude = ["user"]
        ordering = ["created"]

    def save(self, **kwargs):
        # Getting the exact location and saving it to a Location object and saving the Upload object
        # Get the city string, zip_code and address(optional) from the validated data
        validated_data = self.validated_data
        city = validated_data.get("location").title()
        zip_code = validated_data.get("zip_code")
        if validated_data.get("address"):
            address = validated_data.get("address")
        else:
            address = ""

        # Look up the coordinates
        latitude, longitude = Location.get_coordinates_from_city(
            f"{address} {zip_code} {city}"
        )

        # Create a GEOSPoint object for the city coordinates
        coordinates = GEOSPoint(latitude, longitude)
        # Create a Location object for the location
        location, _ = Location.objects.get_or_create(
            city=city,
            zip_code=zip_code,
            address=address,
            coordinates=coordinates,
        )
        # Replace the validated_data with the new created Location field
        validated_data["location"] = location

        # Delete zip_code and address from the validated data to create Upload object
        del validated_data["zip_code"]
        if validated_data.get("address"):
            del validated_data["address"]

        # Checking the url validation
        # Get the link data
        link_data = validated_data.get("link")
        # Check if the link is valid and save it as a Link object
        valid_link = is_valid_url(link_data)
        # breakpoint()
        if valid_link.status_code == status.HTTP_200_OK:
            link, _ = Link.objects.get_or_create(url=link_data)
            validated_data["link"] = link
        else:
            raise serializers.ValidationError(
                {
                    "status": status.HTTP_400_BAD_REQUEST,
                    "message": "The URL you entered is not valid.",
                }
            )

        # Create Upload object
        upload_instance = super().create(validated_data)

        return upload_instance

class CommentSerializerForUploadSerializer(serializers.ModelSerializer):
    author = UserSerializer()

    class Meta:
        model = Comment
        exclude = ["upload"]

class UploadSerializer(TaggitSerializer, serializers.ModelSerializer):
    user = serializers.PrimaryKeyRelatedField(read_only=True)
    location = "LocationSerializer()"
    link = LinkSerializer()
    tags = TagListSerializerField()
    comments = CommentSerializerForUploadSerializer(many=True, read_only=True)

    class Meta:
        model = Upload
        fields = "__all__"
        ordering = ["created"]

class LinkSerializer(serializers.ModelSerializer):
    class Meta:
        model = Link
        fields = "__all__"
        ordering = ["created"]

class LocationSerializer(serializers.ModelSerializer):
    class Meta:
        model = Location
        fields = "__all__"
        ordering = ["created"]

class FileBookmarkSerializer(serializers.ModelSerializer):
    user = serializers.PrimaryKeyRelatedField(read_only=True)

    class Meta:
        model = FileBookmark
        fields = "__all__"
        ordering = ["created"]

class CommentPostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comment
        exclude = ["author"]

class CommentSerializer(serializers.ModelSerializer):
    author = UserSerializer()
    upload = UploadSerializer()

    class Meta:
        model = Comment
        fields = "__all__"


from functools import partial

from PIL import Image
from PyQt6.QtGui import QIcon
from PyQt6.QtWidgets import QHBoxLayout, QWidget

from airunner.utils import get_session, image_to_pixmap
from airunner.widgets.input_image.templates.input_image_ui import Ui_input_image
from airunner.widgets.slider.slider_widget import SliderWidget
from airunner.widgets.base_widget import BaseWidget

class InputImageSettingsWidget(BaseWidget):
    widget_class_ = Ui_input_image
    input_image = None
    keep_refreshed = False
    _active_grid_area_image = None

    @property
    def generator_section(self):
        return self.property("generator_section")

    @property
    def generator_name(self):
        return self.property("generator_name")

    def active_grid_area_image(self):
        if not self.settings_manager.generator.input_image_recycle_grid_image or not self._active_grid_area_image:
            layer_image = self.app.canvas.current_layer.image
            if layer_image.image:
                self._active_grid_area_image = layer_image.image.copy()
        return self._active_grid_area_image

    @property
    def current_input_image(self):
        try:
            if not self.settings_manager.generator:
                return None
            if self.settings_manager.generator.input_image_use_imported_image:
                return self.input_image
            elif self.settings_manager.generator.input_image_use_grid_image:
                return self.active_grid_area_image()
        except AttributeError:
            return None

    def initialize(
        self,
        generator_name,
        generator_section
    ):
        self.setProperty("generator_name", generator_name)
        self.setProperty("generator_section", generator_section)
        self.settings_manager.generator_name = generator_name
        self.settings_manager.generator_section = generator_section
        self.update_buttons()
        self.ui.groupBox.setTitle(self.property("checkbox_label"))
        self.ui.scale_slider_widget.initialize()
        self.initialize_groupbox()

    def initialize_groupbox(self):
        if self.settings_manager.generator:
            self.ui.groupBox.setChecked(self.settings_manager.generator.enable_input_image)

    def action_toggled_use_input_image(self, val):
        self.settings_manager.set_value("generator.enable_input_image", val)

    def action_toggled_button_use_imported_image(self, val):
        self.toggle_use_imported_image(val)
        self.toggle_use_active_grid_area(not val)
        self.update_buttons()

    def action_toggled_button_use_grid_image(self, val):
        self.toggle_use_imported_image(not val)
        self.toggle_use_active_grid_area(val)
        self.update_buttons()

    def toggle_use_imported_image(self, value):
        self.settings_manager.set_value("generator.input_image_use_imported_image", value)
        self.set_thumbnail(self.input_image)

    def action_toggled_button_lock_grid_image(self, val):
        self.toggle_keep_refreshed(val)

    def action_toggled_button_refresh_input_image(self, val):
        self.toggle_keep_refreshed(val)

    def toggle_keep_refreshed(self, value):
        if self.settings_manager.generator.input_image_use_grid_image:
            self.settings_manager.set_value("generator.input_image_recycle_grid_image", value)
        self.set_thumbnail()

    def action_clicked_button_refresh_grid_image(self):
        self.set_thumbnail(self.active_grid_area_image())

    def action_clicked_button_import_image(self):
        self.import_input_image()

    def action_clicked_button_thumbnail(self):
        self.send_active_image_to_canvas()

    def action_clicked_button_clear_input_image(self):
        self.clear_input_image()

    def add_input_image_strength_scale_widget(self):
        slider = None
        if self.app.current_section in ["txt2img", "img2img", "depth2img"]:
            slider = SliderWidget(
                app=self.app,
                label_text="Input Image Scale",
                slider_callback=partial(self.handle_image_strength_changed),
                current_value=self.app.settings_manager.generator.strength,
                slider_maximum=10000,
                spinbox_maximum=100.0,
                display_as_float=True,
                spinbox_single_step=0.01,
                spinbox_page_step=0.01
            )
        else:
            if self.app.current_section not in ["pix2pix"]:
                value = 10000
            else:
                value = int(self.settings_manager.generator.image_guidance_scale)

            if self.app.current_section != "upscale":
                slider = SliderWidget(
                    app=self.app,
                    label_text="Input Image Scale",
                    slider_callback=partial(self.handle_image_scale_changed),
                    current_value=value,
                    slider_maximum=500,
                    spinbox_maximum=5.0,
                    display_as_float=True,
                    spinbox_single_step=0.01,
                    spinbox_page_step=0.01
                )
            if self.app.current_section not in ["pix2pix", "upscale"]:
                slider.setEnabled(False)
        if slider:
            self.add_slider_to_scale_frame(slider)

    def add_slider_to_scale_frame(self, slider):
        grid_layout = QHBoxLayout(self.ui.scale_frame)
        grid_layout.setSpacing(0)
        grid_layout.setContentsMargins(0, 0, 0, 0)
        widget = QWidget()
        grid_layout.addWidget(widget)
        grid_layout.addWidget(slider)

    def handle_image_strength_changed(self, val):
        self.settings_manager.set_value("generator.strength", val)

    def handle_image_scale_changed(self, val):
        self.settings_manager.set_value("generator.image_scale", val)

    def import_input_image(self):
        file_path, _ = self.app.display_import_image_dialog(
            directory=self.settings_manager.path_settings.image_path,
        )
        if file_path == "":
            return
        image = Image.open(file_path)
        image = image.convert("RGBA")
        self.input_image = image
        self.set_thumbnail(image)

    def clear_input_image(self):
        if self.settings_manager.generator.input_image_use_grid_image:
            self._active_grid_area_image = None
        elif self.settings_manager.generator.input_image_use_imported_image:
            self.input_image = None
        self.set_thumbnail()

    def toggle_use_active_grid_area(self, value):
        self.settings_manager.set_value("generator.input_image_use_grid_image", value)
        self.set_thumbnail(self.current_input_image)

    def update_buttons(self):
        if not self.settings_manager.generator:
            return

        if self.settings_manager.generator.input_image_use_grid_image:
            self.ui.import_image_button.setEnabled(False)
            self.ui.recycle_grid_image_button.setEnabled(True)
            # hide the self.ui.refresh_input_image_button button widget
            self.ui.clear_image_button.hide()
            self.ui.refresh_input_image_button.show()
            self.ui.use_imported_image_button.setChecked(False)
            self.ui.use_grid_image_button.setChecked(self.settings_manager.generator.input_image_use_grid_image)
            self.ui.recycle_grid_image_button.setChecked(self.settings_manager.generator.input_image_recycle_grid_image)
        else:
            self.ui.import_image_button.setEnabled(True)
            self.ui.recycle_grid_image_button.setEnabled(False)
            self.ui.refresh_input_image_button.hide()
            self.ui.clear_image_button.show()
            self.ui.use_imported_image_button.setChecked(True)
            self.ui.use_grid_image_button.setChecked(False)
            self.ui.recycle_grid_image_button.setChecked(False)

    def export_input_image_mask(self):
        print("export input image mask")

    def clear_input_image_mask(self):
        print("clear input image mask")

    def handle_new_image(self, data):
        if not self.settings_manager.generator.input_image_recycle_grid_image or not self._active_grid_area_image:
            self._active_grid_area_image = data["processed_image"].copy()
        self.set_thumbnail()

    def set_thumbnail(self, image=None):
        try:
            image = self.current_input_image if not image else image
        except AttributeError:
            return
        if image:
            # self.ui.image_thumbnail is a QPushButton
            self.ui.image_thumbnail.setIcon(QIcon(image_to_pixmap(image, size=72)))
        else:
            self.ui.image_thumbnail.setIcon(QIcon())

        # self.app.update_controlnet_thumbnail()

    def send_active_image_to_canvas(self):
        # send the current input image to the canvas
        if not self.current_input_image:
            return
        self.app.canvas.update_image_canvas(
            self.app.current_section,
            {
                "action": self.app.current_section,
                "options": {
                    "outpaint_box_rect": self.app.canvas.active_grid_area_rect,
                    "generator_section": self.generator_section,
                }
            },
            self.current_input_image
        )
        self.app.canvas.update()


from flask import Flask, render_template, request
from get_data import get_data
from make_graph import make_graph
import file_handle as fh

app = Flask(__name__)

@app.route('/', methods=['POST', 'GET'])
def index():
    s_fname, l_fname = fh.get_filepaths()
    if request.method == 'POST':
        data = get_data(request)
        make_graph(filename=s_fname, **data)
        data.update({
            'figure': l_fname})
        return render_template('input_page.html', **data)
    else:
        return render_template('input_page.html')


from yandex_translate import YandexTranslate

def translate_language(sourcetext,translationfrom,translationTo):
    translate = YandexTranslate('trnsl.1.1.20171108T161528Z.11fd5cf559085f7e.68f45fa90a6197a56fc8353410bec46f7386e419')
    print('Languages:', translate.langs)
    print('Translate directions:', translate.directions)
    print('Detect language:', translate.detect(sourcetext))
    translated_text= translate.translate(sourcetext, translationfrom+'-'+translationTo)
    arr=translated_text['text'];
    return arr
    print (arr)

from nltk.sentiment.vader import SentimentIntensityAnalyzer
#sentences=[]
from nltk import tokenize
#lines_list = tokenize.sent_tokenize(translated_text)
#sentences.extend(lines_list)
def SentimentAnalyzer(analysinglevel,data):
    sid = SentimentIntensityAnalyzer()
    if analysinglevel=='File':
        for sentence in data:
             print('\n',sentence,'\n')
             ss = sid.polarity_scores(sentence)
             for k in ss:
                 print('{0}: {1},\n '.format(k, ss[k]), end='')
    elif analysinglevel=='Line':
        for sentence in data:
            for sen in sentence.split(","):
                 print('\n',sen,'\n')
                 ss = sid.polarity_scores(sen)
                 for k in ss:
                     print('{0}: {1},\n '.format(k, ss[k]), end='')
    elif analysinglevel=='Token':
        lines_list = tokenize.sent_tokenize(",".join(str(x) for x in data))
        for sentence in lines_list:
             print('\n',sentence,'\n')
             ss = sid.polarity_scores(sentence)
             for k in ss:
                 print('{0}: {1}, \n'.format(k, ss[k]), end='')


from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_details(object):

    def setupUi(self, details):
        details.setObjectName('details')
        details.resize(606, 307)
        self.centralWidget = QtWidgets.QWidget(details)
        self.centralWidget.setObjectName('centralWidget')
        self.table = QtWidgets.QTableWidget(self.centralWidget)
        self.table.setGeometry(QtCore.QRect(10, 10, 581, 291))
        self.table.setObjectName('table')
        self.table.setColumnCount(10)
        self.table.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.table.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.table.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.table.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        item.setTextAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignVCenter)
        self.table.setHorizontalHeaderItem(3, item)
        item = QtWidgets.QTableWidgetItem()
        self.table.setHorizontalHeaderItem(4, item)
        item = QtWidgets.QTableWidgetItem()
        self.table.setHorizontalHeaderItem(5, item)
        item = QtWidgets.QTableWidgetItem()
        self.table.setHorizontalHeaderItem(6, item)
        item = QtWidgets.QTableWidgetItem()
        self.table.setHorizontalHeaderItem(7, item)
        item = QtWidgets.QTableWidgetItem()
        self.table.setHorizontalHeaderItem(8, item)
        item = QtWidgets.QTableWidgetItem()
        self.table.setHorizontalHeaderItem(9, item)
        details.setCentralWidget(self.centralWidget)
        self.retranslateUi(details)
        QtCore.QMetaObject.connectSlotsByName(details)

    def retranslateUi(self, details):
        _translate = QtCore.QCoreApplication.translate
        details.setWindowTitle(_translate('details', 'details'))
        item = self.table.horizontalHeaderItem(0)
        item.setText(_translate('details', 'Тип объекта'))
        item = self.table.horizontalHeaderItem(1)
        item.setText(_translate('details', 'ID группы*'))
        item = self.table.horizontalHeaderItem(2)
        item.setText(_translate('details', 'Токен группы*'))
        item = self.table.horizontalHeaderItem(3)
        item.setText(_translate('details', 'Токен пользователя'))
        item = self.table.horizontalHeaderItem(4)
        item.setText(_translate('details', 'Выбрать из'))
        item = self.table.horizontalHeaderItem(5)
        item.setText(_translate('details', 'ID владельца*'))
        item = self.table.horizontalHeaderItem(6)
        item.setText(_translate('details', 'ID объекта'))
        item = self.table.horizontalHeaderItem(7)
        item.setText(_translate('details', 'Действие'))
        item = self.table.horizontalHeaderItem(8)
        item.setText(_translate('details', 'Срок*'))
        item = self.table.horizontalHeaderItem(9)
        item.setText(_translate('details', 'Причина*'))

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    details = QtWidgets.QMainWindow()
    ui = Ui_details()
    ui.setupUi(details)
    details.show()
    sys.exit(app.exec_())


from django.urls import path
from .views import (
    RazorPayOrderForm,
    CallbackView,
    WalletAPI,
    OrderHistory,
    RandomODDS,
    GetTransactionStatus,
    home
)
urlpatterns = [
    path('payment/',home,name='home'),
    path('callback/',CallbackView.as_view(), name="razorpay-callback"),
    path('razorPay/',RazorPayOrderForm.as_view(),name='razorpay'),
    path('get_wallet/',WalletAPI.as_view(), name="get-wallet"),
    path('get_history/',OrderHistory.as_view(),name='get-history'),
    path('get_random_odds/',RandomODDS.as_view(),name='get-random-odds'),
    path('get_status/',GetTransactionStatus.as_view(),name='get-status')
]


import pygame as pg

from engine import get_gfx, Scene
from ..definition import SpaceInvadersGfx

class BaseScene(Scene):

    def __init__(self, game, screen=None, active: bool = False):
        Scene.__init__(self, game, screen, active)
        self.group = pg.sprite.Group()
        self.background = get_gfx(SpaceInvadersGfx.BACKGROUND.value)
        self._first_rendering = True

    def on_activate(self):
        self._first_rendering = True

    def render(self):
        if self._first_rendering:
            self._first_rendering = False
            self.screen.blit(self.background, (0, 0))
        self.group.clear(self.screen, self.background)
        self.group.draw(self.screen)
        return True


# João Pedro Gomes de Lemos
# 0050016060
from flask import Flask
from flask_cors import CORS, cross_origin
from artLib import listArtLib
from artBr import listArtBr
from campBr import listCampBr
from campLib import listCampLib

app = Flask(__name__)
CORS(app)

#rota API
@app.route("/artilheirosbr")
def artilheiros_br():
    resultado = listArtBr()
    return resultado

@app.route("/artilheiroslib")
def artilheiros_lib():
    resultado = listArtLib()
    return resultado

@app.route("/campeoesbr")
def campeoes_br():
    resultado = listCampBr()
    return resultado

@app.route("/campeoeslib")
def campeoes_lib():
    resultado = listCampLib()
    return resultado

if __name__ == "__main__":
    app.run(debug=True)


#!/usr/bin/env python
# coding: utf-8
# Homework 1 - KNN
## CSCI 5622 - Spring 2019

import numpy as np
import matplotlib.pyplot as plt
import sklearn
import sklearn.datasets
from sklearn.utils import shuffle
from collections import Counter
import sklearn.neighbors

class KNNClassifier:

    def __init__(self, X, y, k=5):
        """
        Initializes custom KNN classifier
        PARAMETERS
        X -  training data features
        y -  training data answers
        k - the number of nearest neighbors to consider for classification
        """
        self._model = sklearn.neighbors.BallTree(X)
        self._y = y
        self._k = k
        self._x = X
        self._counts = self.getCounts()

    def getCounts(self):
        """
        Creates a dictionary storing the counts of each answer class found in y
        returns counts - a dictionary of counts of answer classes
        """

        unique, count = np.unique(self._y, return_counts=True)
        counts = dict(zip(unique, count))
        return counts

    def majority(self, indices):
        """
        Given indices, reports the majority label of those points.
        For a tie, report the most common label in the data sets
        returns label - the majority label of our neighbors
        """
        count_neighbor = []
        for item in indices:
            count_neighbor.append(self._y[item])
        counter = Counter(count_neighbor)
        most_common = [counter.most_common()[0][0]]
        higher = counter.most_common()[0][1]
        i = 0
        for item in counter.most_common():
            if counter.most_common()[i][1] == higher:
                most_common.append(counter.most_common()[i][0])
                i += 1
            else:
                break
        total_counts = self.getCounts()
        label = most_common[0]
        highest = total_counts[most_common[0]]
        j = 0
        for item in most_common:
            if total_counts[most_common[j]] > highest:
                label = most_common[j]
        return label

    def classify(self, given_point):
        """
        Given a new data point, classifies it according to the training data X and our number of neighbors k into the appropriate class in the training answers y
        returns ans - the predicted classification
        """
        dimensions = len(given_point)
        dist, ind = self._model.query(np.reshape(given_point, (-1, dimensions)), k=self._k)
        ans = self.majority(ind[0])
        return ans

    def confusionMatrix(self, testX, testY):
        """
        Generates a confusion matrix for the given test set
        returns C - an N*N np.array of counts, where N is the number of classes in the classifier
        """
        C = np.zeros((len(self._counts), len(self._counts)), dtype=int)
        i = 0
        class_number = {}
        for key, value in self._counts.items():
            class_number[key] = i
            i += 1
        i = 0
        prediction_array = []
        wrong_predictions = []
        for x in testX:
            prediction = self.classify(x)
            prediction_array.append(prediction)
            C[class_number[testY[i]]][class_number[prediction]] += 1
            if class_number[testY[i]] != class_number[prediction]:
                wrong_predictions.append(class_number[testY[i]])
            i += 1
        return C, wrong_predictions

    def accuracy(self, C):
        """
        Generates an accuracy score for the classifier based on the confusion matrix
        returns score - an accuracy score
        """
        score = np.sum(C.diagonal()) / C.sum()
        return score

class Numbers:
    def __init__(self):
        # load data from sklearn
        self.digits = sklearn.datasets.load_digits()
        self.split = 80 * len(self.digits.data) / 100
        self.data = self.digits.data
        self.target = self.digits.target
        self.random_data, self.random_target = shuffle(self.data, self.target)
        self.train_x = self.random_data[:int(self.split), :]  # A 2D np.array of training examples, REPLACE
        self.train_y = self.random_target[:int(self.split)]  # A 1D np.array of training answers, REPLACE
        self.test_x = self.random_data[int(self.split):, :]  # A 2D np.array of testing examples, REPLACE
        self.test_y = self.random_target[int(self.split):]  # A 1D np.array of testing answers, REPLACE

    def report(self):
        """
        Reports information about the dataset using the print() function
        """
        print(f"Size of train set : {len(self.train_x)}")
        print(f"Size of each datapoint in X: {len(self.train_x[0])}")
        print(f"Size of test set : {len(self.test_x)}")

    def classify(self, k_value):
        """
        Creates a classifier using the training data and generate a confusion matrix for the test data
        """
        model = KNNClassifier(self.train_x, self.train_y, k_value)
        conf_mat, incorrect_predictions = model.confusionMatrix(self.test_x, self.test_y)
        unique, count = np.unique(self.test_y, return_counts=True)
        counts = dict(zip(unique, count))
        return conf_mat, model.accuracy(conf_mat), incorrect_predictions

    def viewDigit(self, digitImage):
        """
        Displays an image of a digit
        """
        plt.gray()
        plt.matshow(self.digits.images[digitImage])
        plt.show()

num = Numbers()
num.report()
matrix, accuracy, incorrect = num.classify(5)
print("\nConfusion matrix for K=5")
print(matrix)
print("\nAccuracy with split 80/20 and K=5")
print(accuracy)

for item in incorrect:
    num.viewDigit(item)

class Numbers2:
    def __init__(self, trainPercentage):
        # load data from sklearn
        self.digits = sklearn.datasets.load_digits()
        self.split = trainPercentage * len(self.digits.data) / 100
        self.data = self.digits.data
        self.target = self.digits.target
        self.random_data, self.random_target = shuffle(self.data, self.target)
        self.train_x = self.random_data[:int(self.split), :]  # A 2D np.array of training examples,
        self.train_y = self.random_target[:int(self.split)]  # A 1D np.array of training answers,
        self.test_x = self.random_data[int(self.split):, :]  # A 2D np.array of testing examples,
        self.test_y = self.random_target[int(self.split):]  # A 1D np.array of testing answers,

    def report(self):
        """
        Reports information about the dataset
        """
        print(f"Size of train set : {len(self.train_x)}")
        print(f"Size of each datapoint in X: {len(self.train_x[0])}")
        print(f"Size of test set : {len(self.test_x)}")

    def classify(self, k_value):
        """
        Creates a classifier using the training data and generate a confusion matrix for the test data
        """
        model = KNNClassifier(self.train_x, self.train_y, k_value)
        conf_mat, incorrect_predictions = model.confusionMatrix(self.test_x, self.test_y)
        unique, count = np.unique(self.test_y, return_counts=True)
        counts = dict(zip(unique, count))
        return conf_mat, model.accuracy(conf_mat), incorrect_predictions

    def viewDigit(self, digitImage):
        """
        Displays an image of a digit
        """
        plt.gray()
        plt.matshow(self.digits.images[digitImage])
        plt.show()

k = list(range(1, 20))
accuracy_list = []
for each_k in k:
    cnf_mtrx, acc, wrng_prd = num.classify(each_k)
    accuracy_list.append(acc)
plt.plot(k, accuracy_list)
plt.xlabel("Value of K")
plt.ylabel("Accuracy of prediction")
plt.title("K vs.,Accuracy graph")
plt.show()

k = 5
accuracy_list = []
percent = np.arange(50, 85, 5)
for prcnt in percent:
    num = Numbers2(prcnt)
    print(f"Percent split: {prcnt}")
    num.report()
    cnf_mtrx, acc, wr_pred = num.classify(k)
    accuracy_list.append(acc)
plt.plot(percent, accuracy_list)
plt.xlabel("Percentage split")
plt.ylabel("Accuracy of prediction")
plt.title("Percentage split vs.,Accuracy graph")
plt.show()


#created by the main python file.
import streamlit
streamlit.title('MY Parents new healthy diner')
streamlit.header('🥝Breakfast menu')
streamlit.text('🥝omega3 & Blueberry Oatmeal')
streamlit.text('🥝kale, spinach &Rocket smothie')
streamlit.text('🥝Hard boiled Free-range egg')
streamlit.header('🍌🥭 Build Your Own Fruit Smoothie 🥝🍇')

import pandas
my_fruit_lists= pandas.read_csv ("https://uni-lab-files.s3.us-west-2.amazonaws.com/dabw/fruit_macros.txt")
my_fruit_lists = my_fruit_lists.set_index('Fruit')

# Let's put a pick list here so they can pick the fruit they want to include
streamlit.multiselect("Pick some fruits:", list(my_fruit_lists.index),['Avocado','Strawberries'])

# Display the table on the page.
streamlit.dataframe(my_fruit_lists)


from flask import Flask, request, render_template, jsonify
from flask_cors import CORS
import pymongo
import datetime
import os

# Host configuration vars, set up on Heroku or entered here on the command line.
# Many have defaults here for convenience, although the Heroku config. should be exhaustive.

ON_HEROKU = "ON_HEROKU" in os.environ

def key(id, default):
    return (os.environ[id] if id in os.environ else default)

DB_USER = key("DB_USER", "wm_user")
DB_PASS = os.environ["DB_PASS"]         # No default.
DB_HOST = key("DB_HOST", "wm-auto-tsgej.mongodb.net")
DB_NAME = key("DB_NAME", "wm_auto")
DB_COLL = key("DB_COLL", "auto_collection")
DB_OPTS = "?retryWrites=true&w=majority"

uri = "mongodb+srv://%s:%s@%s/%s%s" % (DB_USER, DB_PASS, DB_HOST, DB_NAME, DB_OPTS)

client = pymongo.MongoClient(uri)
db = client[DB_NAME]

app = Flask(__name__, static_url_path='/static')
CORS(app)

def discs_to_ordered_labels(data):
    result = []
    l = len(data)
    for i in range(l):
        for j in range(l):
            d = data[j]
            if d['pos'] == i: result.append("%d" % (j + 1))

    return result

def sanitise_entry(x):
    print(x)

    sanitised = {
        "id"     : x["index"],
        "date"   : x["date"].strftime("%d %b %Y %H:%M:%S"),
        "legend" : " ".join(x["data"]["legend"]),
        "discs"  : discs_to_ordered_labels(x["data"]["discs"])
    }

    x["sanitised"] = sanitised
    return x

@app.route('/list')
def list():
    collection = db[DB_COLL]
    data = [sanitise_entry(dict(x)) for x in collection.find().sort("date", pymongo.DESCENDING)]
    return render_template('list.html', data=data)

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

@app.route('/exchange', methods=['POST'])
def exchange():
    d = request.get_json()
    index = d['index']
    collection = db[DB_COLL]

    candidate = collection.find_one({'index' : index})

    if candidate == None:
        #print("NEW")
        #print(dict(d))
        d2 = dict(d)
        d2["date"] = datetime.datetime.utcnow()
        collection.insert_one(d2)
        return jsonify(d)
    else:
        #print("EXISTING")
        #print(candidate)
        # Lose the _id which doesn't convert to JSON cleanly:
        return jsonify({'index' : index,
                        'type' : "ANY",
                        'data' : candidate['data']})

if (not ON_HEROKU) and __name__ == "__main__":
    app.run(debug=True)


import datetime

import dash
from dash_table import DataTable
import dash_core_components as dcc
import dash_html_components as html
import plotly
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from collections import deque
from dash.dependencies import Input, Output
import sys
import numpy as np
from flask import request
import time
from multiprocessing import Process, Queue

class Visual:

    external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

    def __init__(self, qDisp, qStart, qData):
        self.start = False
        self.qDisp = qDisp
        self.qStart = qStart
        self.qData = qData

        self.oldTime = time.time()

        self.maxData = 20
        self.maxDataE = 20

        prices, self.currentDateTime, self.equipes = self.qDisp.get()
        self.X = np.full(self.maxData,self.currentDateTime)
        self.dACPC = np.full(self.maxData, prices['ACPC'])
        self.dAME = np.full(self.maxData, prices['AME'])
        self.dOZV = np.full(self.maxData, prices['OZV'])
        self.dSHT = np.full(self.maxData, prices['SHT'])
        self.dLAL = np.full(self.maxData, prices['LAL'])
        self.dETF = np.full(self.maxData, prices['ETF'])

        self.XE = np.full(self.maxDataE,self.currentDateTime)
        self.totalValues = {}

        self.column = [{'id':0,'name':'Équipe'},
                       {'id':1,'name':'Total'},
                       {'id':2,'name':'Cash'},
                       {'id':3,'name':'ACPC'},
                       {'id':4,'name':'AME'},
                       {'id':5,'name':'OZV'},
                       {'id':6,'name':'SHT'},
                       {'id':7,'name':'LAL'},
                       {'id':8,'name':'ETF'}]

        titles = ("ACPC:",
                    "AME:",
                    "OZV:",
                    "SHT:",
                    "LAL:",
                    "ETF:")
        self.fig = plotly.subplots.make_subplots(rows=6, cols=1, shared_xaxes=True, vertical_spacing=0.05, subplot_titles=titles)
        self.figTot = go.Figure()

        self.app = dash.Dash(__name__, external_stylesheets=self.external_stylesheets)
        self.app.layout = html.Div(
            html.Div([
                html.H4('Compétition IEEE'),
                html.Button('Start', id='buttonStart'),
                html.Button('View all data', id='buttonView'),
                html.Button('Stop server', id='buttonStop'),
                html.P(id='StartPlaceholder'),
                html.P(id='ViewPlaceholder'),
                html.P(id='StopPlaceholder'),
                html.Div([
                    html.Div([
                        html.Div(id='live-update-text'),
                        dcc.Graph(id='live-update-graph')
                        ], className="one-third column"),
                    html.Div([
                        dcc.Graph(id='Total_Value'),
                        DataTable(
                            id='Table',
                            data=[]
                        )
                        ], className="two-thirds column"),
                    ], className="row"),
                dcc.Interval(
                    id='interval-component',
                    interval=1000, # in milliseconds
                    n_intervals=0
                )
            ])
        )
        self.app.callback(Output('live-update-text', 'children'),
                  Input('interval-component', 'n_intervals'))(self.update_metrics)
        self.app.callback(Output('live-update-graph', 'figure'),
                  Input('interval-component', 'n_intervals'))(self.update_graph_live)
        self.app.callback(Output('Total_Value', 'figure'),
                  Input('interval-component', 'n_intervals'))(self.update_total_value)
        self.app.callback([Output('Table', 'data'), Output('Table', 'columns')],
                  Input('interval-component', 'n_intervals'))(self.update_table)
        self.app.callback(Output('StartPlaceholder', 'children'),
                          Input('buttonStart', 'n_clicks'))(self.Start)
        self.app.callback(Output('ViewPlaceholder', 'children'),
                          Input('buttonView', 'n_clicks'))(self.View)
        self.app.callback(Output('StopPlaceholder', 'children'),
                          Input('buttonStop', 'n_clicks'))(self.Stop)

    def Start(self, n_clicks):
        if n_clicks:
            self.qStart.put(True)
            self.start = True
            return None
        else:
            return None

    def View(self, n_clicks):
        if n_clicks:
            self.qData.put(True)
            return None
        else:
            return None

    def Stop(self, n_clicks):
        if n_clicks:
            self.qStart.put(False)
            self.shutdown_server()

    def getStart(self):
        return self.start

    def getStop(self):
        return self.stop

    def shutdown_server(self):
        func = request.environ.get('werkzeug.server.shutdown')
        if func is None:
            raise RuntimeError('Not running with the Werkzeug Server')
        func()

    def update_metrics(self,n):
        style = {'padding': '5px', 'fontSize': '16px'}
        text = [ html.Span('Date et Heure: '+ self.currentDateTime.strftime("%d/%m/%Y, %H:%M:%S"), style=style)]
        return text

    # Multiple components can update everytime interval gets fired.
    def update_graph_live(self,n):

        if(self.start):
            self.oldTime = time.time()
            prices, self.currentDateTime, self.equipes = self.qDisp.get()

            self.X = np.roll(self.X,-1)
            self.X[-1] = self.currentDateTime
            self.dACPC = np.roll(self.dACPC,-1)
            self.dAME = np.roll(self.dAME,-1)
            self.dOZV = np.roll(self.dOZV,-1)
            self.dSHT = np.roll(self.dSHT,-1)
            self.dLAL = np.roll(self.dLAL,-1)
            self.dETF = np.roll(self.dETF,-1)
            self.dACPC[-1] = (prices['ACPC'])
            self.dAME[-1] = (prices['AME'])
            self.dOZV[-1] = (prices['OZV'])
            self.dSHT[-1] = (prices['SHT'])
            self.dLAL[-1] = (prices['LAL'])
            self.dETF[-1] = (prices['ETF'])

            self.fig['layout']['annotations'][0]['text'] = "ACPC: {:.2f}".format(prices['ACPC'])
            self.fig['layout']['annotations'][1]['text'] = "AME: {:.2f}".format(prices['AME'])
            self.fig['layout']['annotations'][2]['text'] = "OZV: {:.2f}".format(prices['OZV'])
            self.fig['layout']['annotations'][3]['text'] = "SHT: {:.2f}".format(prices['SHT'])
            self.fig['layout']['annotations'][4]['text'] = "LAL: {:.2f}".format(prices['LAL'])
            self.fig['layout']['annotations'][5]['text'] = "ETF: {:.2f}".format(prices['ETF'])

        self.fig.data = []
        #fig = plotly.subplots.make_subplots(rows=5, cols=1, shared_xaxes=True, vertical_spacing=0.05,
         #                                   subplot_titles=titles)

        trace = go.Scatter(name="ACPC", x=(self.X), y=(self.dACPC), mode = 'lines+markers',connectgaps=True)
        self.fig.append_trace(trace, 1, 1)

        trace = go.Scatter(name="AME", x=(self.X), y=(self.dAME), mode = 'lines+markers',connectgaps=True)
        self.fig.append_trace(trace, 2, 1)

        trace = go.Scatter(name="OZV", x=(self.X), y=(self.dOZV), mode = 'lines+markers',connectgaps=True)
        self.fig.append_trace(trace, 3, 1)

        trace = go.Scatter(name="SHT", x=(self.X), y=(self.dSHT), mode = 'lines+markers',connectgaps=True)
        self.fig.append_trace(trace, 4, 1)

        trace = go.Scatter(name="LAL", x=(self.X), y=(self.dLAL), mode = 'lines+markers',connectgaps=True)
        self.fig.append_trace(trace, 5, 1)

        trace = go.Scatter(name="ETF", x=(self.X), y=(self.dETF), mode = 'lines+markers',connectgaps=True)
        self.fig.append_trace(trace, 6, 1)

        self.fig.update_layout(showlegend=False, height=800,
                               xaxis={'type': 'date',
                                      'rangebreaks':[dict(bounds=["sat", "mon"]),
                                                     {'pattern': 'hour', 'bounds': [16, 9.5]}]},
                              margin=dict(
                                    l=0,
                                    r=0,
                                    b=0,
                                    t=30,
                                    pad=4
                                ))

        return self.fig

    def update_total_value(self,n):
        self.figTot.data = []

        if self.start:
            self.XE = np.roll(self.XE,-1)
            self.XE[-1] = self.currentDateTime
            for key in self.equipes.keys():
                if not key in self.totalValues:
                    self.totalValues[key] = np.full(self.maxDataE, self.equipes[key][1])
                else:
                    self.totalValues[key] = np.roll(self.totalValues[key],-1)
                    self.totalValues[key][-1] = (self.equipes[key][1])

                trace = go.Scatter(name=key, x=(self.XE), y=(self.totalValues[key]), mode = 'lines+markers',connectgaps=True)
                self.figTot.add_trace(trace)

        self.figTot.update_layout(xaxis={'type': 'date',
                                      'rangebreaks':[dict(bounds=["sat", "mon"]),
                                                     {'pattern': 'hour', 'bounds': [16, 9.5]}]})

        return self.figTot

    def update_table(self,n):
        values = [[self.equipes[key][0],
                   "{:.2f}".format(self.equipes[key][1]),
                   "{:.2f}".format(self.equipes[key][2]),
                   self.equipes[key][3],
                   self.equipes[key][4],
                   self.equipes[key][5],
                   self.equipes[key][6],
                   self.equipes[key][7],
                   self.equipes[key][8]] for key in self.equipes.keys()]

        return values, self.column