import argparse
import glob
import logging
import os
import re
import subprocess
import sys
from collections import OrderedDict

import xmltodict

def get_summary(results):
    ntest = int(results["@tests"])
    nfail = int(results["@failures"])
    nerror = int(results["@errors"])
    nskip = int(results["@skipped"])
    npass = ntest - nfail - nskip - nerror
    return ntest, npass, nfail, nerror, nskip

def print_summary(results, args):
    ntest, npass, nfail, nerror, nskip = (0, 0, 0, 0, 0)
    for group in results:
        _ntest, _npass, _nfail, _nerror, _nskip = get_summary(results[group])
        if args.verbose:
            print(
                f"Group: {group} Total: {_ntest} PASSED: {_npass}"
                " FAIL: {_nfail} ERROR: {_nerror} SKIP: {_nskip}"
            )
        ntest += _ntest
        npass += _npass
        nfail += _nfail
        nerror += _nerror
        nskip += _nskip
    print(f"Total: {ntest} PASSED: {npass} FAIL: {nfail} ERROR: {nerror} SKIP: {nskip}")

def get_global_testcase(results):
    for group in results:
        for testcase in results[group]["testcase"]:
            if "@file" not in testcase:
                return testcase
    return None

def get_filtered(tfilters, results, args):
    if isinstance(tfilters, str) or tfilters is None:
        tfilters = [tfilters]
    found_files = OrderedDict()
    for group in results:
        if isinstance(results[group]["testcase"], list):
            tlist = results[group]["testcase"]
        else:
            tlist = [results[group]["testcase"]]
        for testcase in tlist:
            for tfilter in tfilters:
                if tfilter is None:
                    if (
                        "failure" not in testcase
                        and "error" not in testcase
                        and "skipped" not in testcase
                    ):
                        break
                elif tfilter in testcase:
                    break
            else:
                continue
            # cname = testcase["@classname"]
            fname = testcase.get("@file", "")
            cname = testcase.get("@classname", "")
            if not fname and not cname:
                name = testcase.get("@name", "")
                if not name:
                    continue
                # If we had a failure at the module level we could be here.
                fname = name.replace(".", "/") + ".py"
                tcname = fname
            else:
                if not fname:
                    fname = cname.replace(".", "/") + ".py"
                if args.files_only or "@name" not in testcase:
                    tcname = fname
                else:
                    tcname = fname + "::" + testcase["@name"]
            found_files[tcname] = testcase
    return found_files

def dump_testcase(testcase):
    expand_keys = ("failure", "error", "skipped")

    s = ""
    for key, val in testcase.items():
        if isinstance(val, str) or isinstance(val, float) or isinstance(val, int):
            s += "{}: {}\n".format(key, val)
        elif isinstance(val, list):
            for k2, v2 in enumerate(val):
                s += "{}: {}\n".format(k2, v2)
        else:
            for k2, v2 in val.items():
                s += "{}: {}\n".format(k2, v2)
    return s

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-A",
        "--save",
        action="store_true",
        help="Save /tmp/topotests{,.xml} in --rundir if --rundir does not yet exist",
    )
    parser.add_argument(
        "-F",
        "--files-only",
        action="store_true",
        help="print test file names rather than individual full testcase names",
    )
    parser.add_argument(
        "-S",
        "--select",
        default="fe",
        help="select results combination of letters: 'e'rrored 'f'ailed 'p'assed 's'kipped.",
    )
    parser.add_argument(
        "-r",
        "--results",
        help="xml results file or directory containing xml results file",
    )
    parser.add_argument("--rundir", help=argparse.SUPPRESS)
    parser.add_argument(
        "-E",
        "--enumerate",
        action="store_true",
        help="enumerate each item (results scoped)",
    )
    parser.add_argument("-T", "--test", help="print testcase at enumeration")
    parser.add_argument(
        "--errmsg", action="store_true", help="print testcase error message"
    )
    parser.add_argument(
        "--errtext", action="store_true", help="print testcase error text"
    )
    parser.add_argument("--time", action="store_true", help="print testcase run times")

    parser.add_argument("-s", "--summary", action="store_true", help="print summary")
    parser.add_argument("-v", "--verbose", action="store_true", help="be verbose")
    args = parser.parse_args()

    if args.save and args.results and not os.path.exists(args.results):
        if not os.path.exists("/tmp/topotests"):
            logging.critical('No "/tmp/topotests" directory to save')
            sys.exit(1)
        subprocess.run(["mv", "/tmp/topotests", args.results])
        # # Old location for results
        # if os.path.exists("/tmp/topotests.xml", args.results):
        #     subprocess.run(["mv", "/tmp/topotests.xml", args.results])

    assert (
        args.test is None or not args.files_only
    ), "Can't have both --files and --test"

    results = {}
    ttfiles = []
    if args.rundir:
        basedir = os.path.realpath(args.rundir)
        os.chdir(basedir)

        newfiles = glob.glob("tt-group-*/topotests.xml")
        if newfiles:
            ttfiles.extend(newfiles)
        if os.path.exists("topotests.xml"):
            ttfiles.append("topotests.xml")
    else:
        if args.results:
            if os.path.exists(os.path.join(args.results, "topotests.xml")):
                args.results = os.path.join(args.results, "topotests.xml")
            if not os.path.exists(args.results):
                logging.critical("%s doesn't exist", args.results)
                sys.exit(1)
            ttfiles = [args.results]
        elif os.path.exists("/tmp/topotests/topotests.xml"):
            ttfiles.append("/tmp/topotests/topotests.xml")

        if not ttfiles:
            if os.path.exists("/tmp/topotests.xml"):
                ttfiles.append("/tmp/topotests.xml")

    for f in ttfiles:
        m = re.match(r"tt-group-(\d+)/topotests.xml", f)
        group = int(m.group(1)) if m else 0
        with open(f) as xml_file:
            results[group] = xmltodict.parse(xml_file.read())["testsuites"]["testsuite"]

    filters = []
    if "e" in args.select:
        filters.append("error")
    if "f" in args.select:
        filters.append("failure")
    if "s" in args.select:
        filters.append("skipped")
    if "p" in args.select:
        filters.append(None)

    found_files = get_filtered(filters, results, args)
    if found_files:
        if args.test is not None:
            if args.test == "all":
                keys = found_files.keys()
            else:
                keys = [list(found_files.keys())[int(args.test)]]
            for key in keys:
                testcase = found_files[key]
                if args.errtext:
                    if "error" in testcase:
                        errmsg = testcase["error"]["#text"]
                    elif "failure" in testcase:
                        errmsg = testcase["failure"]["#text"]
                    else:
                        errmsg = "none found"
                    s = "{}: {}".format(key, errmsg)
                elif args.time:
                    text = testcase["@time"]
                    s = "{}: {}".format(text, key)
                elif args.errmsg:
                    if "error" in testcase:
                        errmsg = testcase["error"]["@message"]
                    elif "failure" in testcase:
                        errmsg = testcase["failure"]["@message"]
                    else:
                        errmsg = "none found"
                    s = "{}: {}".format(key, errmsg)
                else:
                    s = dump_testcase(testcase)
                print(s)
        elif filters:
            if args.enumerate:
                print(
                    "\n".join(["{} {}".format(i, x) for i, x in enumerate(found_files)])
                )
            else:
                print("\n".join(found_files))

    if args.summary:
        print_summary(results, args)

if __name__ == "__main__":
    main()


from django.shortcuts import render , redirect
from .models import *
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse
import json
from django.contrib.humanize.templatetags.humanize import naturaltime
from django.template.defaultfilters import truncatechars ,safe,escape
from django.db.models import Q

# Create your views here.
def Index(request):
	context = {}
	context['data'] =  BlogPost.objects.filter().order_by('-id').values()[:6]
	for i in context['data']:
		i['short_description'] = truncatechars(strip_tags(i["content"]),250)

		i['comment'] = LeaveComments.objects.filter(post_id=i['id']).count()
		i['rating'] = LeaveComments.objects.filter(post_id=i['id']).aggregate(Sum('star')).get('star__sum')
		if i['rating'] is None:
			i['rating'] = 0
		i['rating'] = int(i['rating'])

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

def BlogDetails(request,id):
	context = {}
	if request.POST:
		data = request.POST
		print(data,'data is called ')
		try:
			star = data['star']
		except :
			star = 0

		LeaveComments.objects.create(post_id=id,comment=data['comment'],name=data['name'],star=star,email=data['email'],mobile=data['mobile'])
		return redirect(f'/blog-view/{id}')
	else:
		context['blog'] =  BlogPost.objects.get(id=id)
		context['image'] = Image.objects.filter(post_id=id)
		context['video'] = Video.objects.filter(post_id=id)

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

from django.contrib.humanize.templatetags.humanize import naturaltime

def AllBlog(request):
	return render(request,'blog_collection.html')

@csrf_exempt
def BlogPOSTAPI(request,id):

	context= {}
	data = request.POST
	print("data is called ")
	print(data)
	if data['rating'] is None:
		data['rating'] = 0

	check  = BlogPost.objects.filter(id=id)
	if check.exists():
		LeaveComments.objects.create(post_id=id,comment=data['comment'],star=data['rating'],email=data['email'],mobile=data['mobile'])
		context['status_flag'] = True
	else:
		context['status_flag'] = False
	return JsonResponse(context)

def BlogData(request,id):
	context = {}
	context['data'] = list(LeaveComments.objects.filter(post_id=id).order_by('-id').values())
	for i in context['data']:
		i['ago_date'] = naturaltime(i['created_at'])
	print(context)
	return JsonResponse(context)

@csrf_exempt
def GetInTouchView(request):
	data = json.loads(request.body)
	print(data)

	context={}
	context['email'] = data['email']
	context['mobile'] = data['phone']
	context['name']=data['name']
	context['message'] = data['message']

	GetInTouch.objects.create(**context)
	context['status_flag'] = True
	return JsonResponse(context)

@csrf_exempt
def LeaveCommentPost(request,id):
	data = json.loads(request.body)
	user = request.user
	context = {}
	blog = BlogPost.objects.filter(id=id)
	if blog.exists():
		context['status_flag'] = True
		LeaveComments.objects.create(post_id=id,comment=data['message'],star=data['star'],name = data['name'],email = data['email'],mobile=data['mobile'])
	else:
		context['status_flag'] = False

	print(data)
	return JsonResponse(context)

def LeaveCommentGet(request,id):
	user = request.user
	context = {}
	blog = LeaveComments.objects.filter(post_id=id).order_by('-id').values('id','comment','created_at','star','name','email','mobile')
	print(blog)
	for i in blog:
		i['created_at'] = naturaltime(i['created_at'])
		# replay_data = CommentReply.objects.filter(comment_id=i['id']).order_by('-id').values('id','user__full_name','user__image','reply','created_at')
		# for j in replay_data:
		# 	j['created_at'] = naturaltime(j['created_at'])
		# i['replay_data'] =list(replay_data)
	context['data'] = list(blog)
	context['count'] = blog.count()
	return JsonResponse(context)

from django.db.models import Sum
from django.utils.html import strip_tags

def AllBlogAPI(request):
	context = {}
	search = request.GET['search']
	if search is not None or searh != "":
		search = search.replace('%20'," ")
		s = Q(title__icontains=search)
	else:
		s = Q()

	blog = BlogPost.objects.filter().filter(s).values('id','title','content','update_at','create_at','banner_image')
	for i in blog:
		i['comment'] = LeaveComments.objects.filter(post_id=i['id']).count()
		i['rating'] = LeaveComments.objects.filter(post_id=i['id']).aggregate(Sum('star')).get('star__sum')
		if i['rating'] is None:
			i['rating'] = 0
		i['rating'] = int(i['rating'])
		i['short_description'] = truncatechars(strip_tags(i["content"]),250)
		i['create_at'] = naturaltime(i['create_at'])

	context['blog'] = list(blog)
	print(context)
	return JsonResponse(context)


from datetime import datetime, timedelta
import time
import threading

class Alarm(object):
    enabled = False
    alarm_active = False
    old_time = 0

    def __init__(self, alarmtime):
        self.alarmtime = datetime.strptime(alarmtime, "%H:%M")
        self.time = self.alarmtime
        self.check_alarm_thread = threading.Thread(target=self.check_alarm)
        self.check_alarm_thread.daemon = True
        self.check_alarm_thread.start()

    def check_alarm(self):
        while True:
            new_time = int(datetime.now().minute)
            if new_time != self.old_time:
                self.old_time = new_time
                if self.alarmtime.hour == datetime.now().hour and self.alarmtime.minute == datetime.now().minute:
                    self.alarm_active = True
            time.sleep(1)

    def setAlarm(self):
        self.alarmtime = self.time

    def resetAlarm(self):
        self.time = self.alarmtime

    def changeAlarm(self, m):
        self.time += timedelta(minutes=m)


from unittest import mock

from django.core.management import call_command
from django.test import TestCase

from releases.models import Release, SongFile
from releases.tests.factories import ReleaseFactory, SongFactory, SongFileFactory

class FixChecksumTestCase(TestCase):
    @mock.patch('amuse.tasks.zendesk_create_or_update_user')
    def setUp(self, mock_zendesk):
        self.release = ReleaseFactory(status=Release.STATUS_APPROVED)
        self.song = SongFactory(release=self.release)
        self.song_file = SongFileFactory(song=self.song, type=SongFile.TYPE_FLAC)

    def test_fix_checksum(self):
        SongFile.objects.filter(pk=self.song_file.pk).update(checksum=None)
        call_command("fix_checksums", "--limit=10")

        self.song_file.refresh_from_db()
        assert self.song_file.checksum

    def test_skip_deleted_releases(self):
        SongFile.objects.filter(pk=self.song_file.pk).update(checksum=None)
        self.release.status = Release.STATUS_DELETED
        self.release.save()

        call_command("fix_checksums", "--limit=10")

        self.song_file.refresh_from_db()
        assert self.song_file.checksum is None

    @mock.patch("releases.management.commands.fix_checksums.save_song_file_checksum")
    def test_dryrun(self, mock_save):
        SongFile.objects.filter(pk=self.song_file.pk).update(checksum=None)
        call_command("fix_checksums", "--limit=10", "--dryrun")

        self.song_file.refresh_from_db()
        assert self.song_file.checksum is None
        mock_save.assert_not_called()


from setuptools import setup, find_packages

with open('requirements.txt') as f:
    install_requires = f.read().splitlines()

setup(
    name='ava_asd',
    description='Scripts and models for the AVA Active Speaker Detection dataset.',
    license='Apache License Version 2.0',
    author='Tuan Chien, James Diprose',
    url='https://github.com/tuanchien/asd',
    packages=find_packages(),
    install_requires=install_requires,
    python_requires='>=3.7',
    entry_points={
        'console_scripts': [
            'ava-download = download:main',
            'ava-extract = extract:main',
            'ava-train = train:main',
            'ava-evaluate = evaluate:main'
        ]
    },
)


import os
import re
import pandas as pd
from deepface import DeepFace
from tqdm import tqdm

pattern = re.compile(r'\d+\_\d+\_q?\d+')

folders = ['Mor_morph', 'Mor_nonmorph']

data = {
	'imgname' : [],
	'isMorph' : [],
	'gt1_gt2' : [],
	'gt1_input' : [],
	'gt2_input' : [],
	'output1_input' : [],
	'output2_input' : [],
	'gt1_output1' : [],
	'gt1_output2' : [],
	'gt2_output1' : [],
	'gt2_output2' : [],
	'output1_output2' : []
}

def calculate_score(path1,path2):
    result = DeepFace.verify(path1,path2,model_name = 'ArcFace',enforce_detection=False)
    return result['distance']

f1=set()

for folder in tqdm(folders):
	is_morph_check = folder.replace('Mor_', '')
	for filename in tqdm(os.listdir(folder)):
		m = re.search(pattern, filename)
		if m is not None:
			match_str = m.group(0)
			# print(match_str)
			match_str = match_str.strip()
			# print(match_str)
			f1.add(match_str)

			if(match_str not in data['imgname']):
				## column1
				data['imgname'].append(match_str)

				## column2
				if(is_morph_check=="morph"):
					data['isMorph'].append(1)
				else:
					data['isMorph'].append(0)

				### Image files for processing
				gt1 = folder+"/"+match_str+"_gt1.png"
				gt2 = folder+"/"+match_str+"_gt2.png"
				Input = folder+"/"+match_str+"_input.png"
				output1 = folder+"/"+match_str+"_output1.png"
				output2 = folder+"/"+match_str+"_output2.png"

				data['gt1_gt2'].append('{0:.3g}'.format(calculate_score(gt1,gt2)))
				data['gt1_input'].append('{0:.3g}'.format(calculate_score(gt1,Input)))
				data['gt2_input'].append('{0:.3g}'.format(calculate_score(gt2,Input)))
				data['output1_input'].append('{0:.3g}'.format(calculate_score(output1,Input)))
				data['output2_input'].append('{0:.3g}'.format(calculate_score(output2,Input)))
				data['gt1_output1'].append('{0:.3g}'.format(calculate_score(gt1,output1)))
				data['gt1_output2'].append('{0:.3g}'.format(calculate_score(gt1,output2)))
				data['gt2_output1'].append('{0:.3g}'.format(calculate_score(gt2,output1)))
				data['gt2_output2'].append('{0:.3g}'.format(calculate_score(gt2,output2)))
				data['output1_output2'].append('{0:.3g}'.format(calculate_score(output1,output2)))

df = pd.DataFrame(data = data, columns = list(data.keys()))
print(df.head())
print(df.describe())
df.to_csv('scores.csv')


import floodsystem.geo as geo
from floodsystem.stationdata import build_station_list

def run():
    stations = build_station_list()

    rivs = sorted(geo.rivers_with_station(stations))

    print(len(rivs),"\n")

    print(rivs[:10],"\n")

    riv_stats = geo.stations_by_river(stations)

    for i in ["River Aire","River Cam","River Thames"]:
        print(i,sorted([j.name for j in riv_stats[i]]),"\n")

if __name__ == '__main__':
    run()


# def table(n):
#     # ans=1
#     l=[]
#     for i in range(1,11):
#         ans=n*i
#         l.append(ans)
#     return ans

# print(table(6))

def table(n):
    i=1
    l=[]
    while i!=11:
        ans=n*i
        l.append(ans)
        i+=1
    return l

print(table(7))


#coding=utf-8
import cv2
import numpy as np

pi=3.141592653589793

def rgb2hsi(rgbImg):
    """
    这个是我自己写的。中间使用了一些python和numpy的矩阵操作，加快了运算速度。
    下面的代码是在网上找的，速度就比较慢。这里我一开始一直算出来的结果跟人家的不一样。
    花了好长时间才发现，我的公式是照着数字图像处理第三版写的，在计算theta时书中
    少写了一个括号，所以我算出来的结果一直不对。。。后来发现了改正了就好了。
    """
    hsiImg=rgbImg.copy() #h,w,c
    rgbImg=rgbImg/255.0
    b_img,g_img,r_img=rgbImg[:,:,0],rgbImg[:,:,1],rgbImg[:,:,2]
    h_img=s_img=i_img=np.zeros(r_img.shape)

    epsi=1e-6
    den_theta=np.sqrt((r_img-g_img)*(r_img-g_img)+(r_img-b_img)*(g_img-b_img))+epsi
    num_theta=((r_img-g_img)+(r_img-b_img))/2+epsi#《数字图像处理》书中共识少些了一个括号
    cos_theta=num_theta/den_theta
    # try:
    #     theta=np.arccos(cos_theta)
    # except:
    #     print(cos_theta)
    theta=np.arccos(cos_theta)
    BG_valueCom=b_img<=g_img
    theta_part=theta*BG_valueCom
    complementary_part=(2*pi-theta)*(1-BG_valueCom)
    h_img=theta_part+complementary_part
    h_img=h_img/(2*pi)

    den_s=(r_img+b_img+g_img)+epsi
    num_s=3*np.minimum(np.minimum(r_img,b_img),g_img)+epsi
    s_img=1-num_s/den_s

    i_img=(r_img+b_img+g_img)/3

    hsiImg[:,:,0]=h_img*255.0
    hsiImg[:,:,1]=s_img*255.0
    hsiImg[:,:,2]=i_img*255.0

    return hsiImg

def hsi2rgb(hsiImg):
    """
    hsiImg需要已经归一化至01之间。
    """
    rgbImg=hsiImg.copy()
    h_img,s_img,i_img=hsiImg[:,:,0],hsiImg[:,:,1],hsiImg[:,:,2]
    h_img=h_img*2*pi
    first_section=h_img<(2*pi/3)
    second_section_=h_img<(4*pi/3)
    second_section=(1-first_section)*second_section_
    third_section=1-second_section_

    b_img_first=i_img*(1-s_img)
    r_img_first=i_img*(1+s_img*np.cos(h_img)/np.cos(pi/3-h_img))
    g_img_first=3*i_img-(r_img_first+b_img_first)

    h_img_second=h_img-2*pi/3
    r_img_second=i_img*(1-s_img)
    g_img_second=i_img*(1+s_img*np.cos(h_img_second)/np.cos(pi/3-h_img_second))
    b_img_second=3*i_img-(r_img_second+g_img_second)

    h_img_third=h_img-4*pi/3
    g_img_third=i_img*(1-s_img)
    b_img_third=i_img*(1+s_img*np.cos(h_img_third)/np.cos(pi/3-h_img_third))
    r_img_third=3*i_img-(b_img_third+g_img_third)

    b_img=b_img_first*first_section+b_img_second*second_section+b_img_third*third_section
    g_img=g_img_first*first_section+g_img_second*second_section+g_img_third*third_section
    r_img=r_img_first*first_section+r_img_second*second_section+r_img_third*third_section

    rgbImg[:,:,0]=b_img*255.0
    rgbImg[:,:,1]=g_img*255.0
    rgbImg[:,:,2]=r_img*255.0

    return rgbImg

def RGB2HSI2_fromInternet(rgb_img):
    """
    这是将RGB彩色图像转化为HSI图像的函数
    :param rgm_img: RGB彩色图像
    :return: HSI图像
    """
    #保存原始图像的行列数
    row = np.shape(rgb_img)[0]
    col = np.shape(rgb_img)[1]
    #对原始图像进行复制
    hsi_img = rgb_img.copy()
    #对图像进行通道拆分
    B,G,R = cv2.split(rgb_img)
    #把通道归一化到[0,1]
    [B,G,R] = [ i/ 255.0 for i in ([B,G,R])]
    H = np.zeros((row, col))    #定义H通道
    I = (R + G + B) / 3.0       #计算I通道
    S = np.zeros((row,col))      #定义S通道
    for i in range(row):
        den = np.sqrt((R[i]-G[i])**2+(R[i]-B[i])*(G[i]-B[i]))
        thetha = np.arccos(0.5*(R[i]-B[i]+R[i]-G[i])/den)   #计算夹角
        h = np.zeros(col)               #定义临时数组
        #den>0且G>=B的元素h赋值为thetha
        h[B[i]<=G[i]] = thetha[B[i]<=G[i]]
        #den>0且G<=B的元素h赋值为thetha
        h[G[i]<B[i]] = 2*np.pi-thetha[G[i]<B[i]]
        #den<0的元素h赋值为0
        h[den == 0] = 0
        H[i] = h/(2*np.pi)      #弧度化后赋值给H通道
    #计算S通道
    for i in range(row):
        min = []
        #找出每组RGB值的最小值
        for j in range(col):
            arr = [B[i][j],G[i][j],R[i][j]]
            min.append(np.min(arr))
        min = np.array(min)
        #计算S通道
        S[i] = 1 - min*3/(R[i]+B[i]+G[i])
        #I为0的值直接赋值0
        S[i][R[i]+B[i]+G[i] == 0] = 0
    #扩充到255以方便显示，一般H分量在[0,2pi]之间，S和I在[0,1]之间
    hsi_img[:,:,0] = H*255
    hsi_img[:,:,1] = S*255
    hsi_img[:,:,2] = I*255
    return hsi_img


# -*- coding: utf-8 -*-
"""
Created on Tue Oct 15 21:11:51 2019

@author: Nathan Hilbrands
"""

'''import PyPDF2

pgnfile = open ('pgn+40.pdf', 'rb')
pgnread = PyPDF2.PdfFileReader(pgnfile)
page1 = pgnread.getPage(7)
print(page1.extractText())
'''

def chapterparse(textloc):
    import pandas as pd
    import numpy as np
    import re
    import io
    with io.open(textloc, mode = 'r', encoding = 'utf-8') as in_file:
        timesused = 1
        dfcreated = False               #stores whether data frame has been created yet.
        #print('')
        ofoptions = False
        for line in in_file:
            lineused = False
            if 'Options and their characteristics' in line:
                ofoptions = True
                continue
            if'Description' in line:
                labelline = line.split(' ')
                keyword = labelline[1].strip()      #finds first string that is not 'Descriptinon' sets as key word
                labelindex = -1
                labellist = []
                for item in labelline:              #adds string to keyword if not keyword
                    if item.strip() == keyword:
                        labellist.append(item)
                        labelindex += 1
                    elif item != 'Description':
                        labellist[labelindex] = labellist[labelindex] + ' ' + item
                        lineused = True
            if 'Description' not in line:
                #print(line)
                tempstr = re.split(r'(^[^\d]+)', line)[1:] #splits line into
                #print(tempstr[0])
                stringsplit = tempstr[1].split(' ')
                #print(stringsplit[0])
                #print(stringsplit)
            if tempstr[0].strip() == 'ID':
                    global chapterdf
                    chapterdf = pd.DataFrame(columns = stringsplit)
                    chapterdf.loc['Description'] = labellist
                    dfcreated = True
                    lineused = True
            if '/' in tempstr[0] and 'spring' not in tempstr[0]:
                slashlabels = tempstr[0].split('/')     #creates list of row names
                slashvalstogether = tempstr[1].split(' ') #splits line into groups of connected by slashes
                slashindex = 0
                unit = slashlabels[-1].split(' ', 1)[-1]
                #print(unit)
                #print(tempstr[0])
                for slash in slashlabels:
                    slashvallist = []
                    for slashgroup in slashvalstogether:
                        slashvallist.append(slashgroup.split('/')[slashindex]) #adds slash index itme to list that will become dataframe row
                        #print(slashgroup.split('/')[slashindex])
                    if unit not in slash:
                        repeatslash = slash + ' ' + unit
                        timesused+=1
                        if ofoptions:
                            #repeatslash = repeatslash + ' of options'
                            dummy = 1
                            #print(repeatslash)
                        else:
                            chapterdf.loc[repeatslash] = slashvallist
                    else:
                        if ofoptions:
                            #slash = slash + ' of options'
                            dummy = 1
                        else:
                            chapterdf.loc[slash] = slashvallist        #adds list as row
                    slashindex += 1                                 #moves to next iem
                    lineused = True
            if ' x ' in line:
                xlabels = tempstr[0].split(' x ')
                origarray = tempstr[1].split(' ')
                noxlist = []
                #print(len(xlabels))
                for i in origarray: #adds only non x items to list
                    if i != 'x':
                        noxlist.append(i)
                noxarray = np.array(noxlist)
                noxarray = noxarray.reshape(int(len(noxlist)/len(xlabels)), len(xlabels)) #turns list into array and reshapes it
                j = 0
                for item in xlabels:      #adds correct columns to rows in dataframe
                    if ofoptions:
                    #item = item + ' of options'
                        dummy = 1
                    else:
                        chapterdf.loc[item] = noxarray[:,j]
                        j+=1
                        lineused = True

            elif dfcreated:
                if len(stringsplit) == chapterdf.shape[1] and not lineused:
                    #print(stringsplit)
                    if ofoptions:
                        #chapterdf.loc[tempstr[0] + ' of options'] = stringsplit
                        dummy = 1
                    else:
                        #print(tempstr[0])
                        if tempstr[0] != '':
                            chapterdf.loc[tempstr[0]] = stringsplit
    return(chapterdf)
def main():
    from tika import parser
    import pandas as pd
    globaldfcreated = False
    import io
    global globaldf
    collist = []
    raw = parser.from_file('MPG+.pdf')  #extracts text from PDF
    firsttxt = raw['content']
    #print(type('pgn2.txt'))
    with io.open('pgn2.txt', mode = 'w', encoding = 'utf-8') as f: #saves text in pdf to text file
        f.write(firsttxt)

    istech = False
    with io.open('pgn2.txt', mode = 'r', encoding = 'utf-8') as in_file:
        texti = 0
        for line in in_file:                            #only writing lines with tech data to condensed file named text
            if line.strip() == 'Technical data':
                istech = True
                textloc = 'temp' + str(texti) + ".txt"
                out_file = io.open(textloc, mode = 'w+', encoding = 'utf-8')
                texti +=1
                continue
            if istech:
                if line.strip() == 'Options and their characteristics' or line.strip().isnumeric() or line == '':
                    istech = False
                    #out_file.truncate(0)
                    if globaldfcreated:                         #appends global df if already created
                        out_file.close()
                        #print(chapterparse())
                        #print('Global df')
                        globaldf = pd.concat([globaldf, chapterparse(textloc).transpose()], sort = True)

                        #out_file.truncate(0)
                    if not globaldfcreated:
                        #print(chapterparse())
                        out_file.close()
                        globaldf = chapterparse(textloc).copy()                        #creates global df if not created
                        globaldf = globaldf.transpose()
                        globaldfcreated = True
                        #print ('Not global df')
                else:
                    out_file.write(line)
                    #print(line)
    globaldf = globaldf.drop('\n', axis = 1)
    globaldf.to_csv('grippercsv.csv')
    dfhtml = globaldf.to_html()
    with io.open('dfhtmlfile.txt', mode = 'w+', encoding = 'utf-8') as writefile:
        writefile.write(dfhtml)
if __name__ == "__main__":
   main()


import ast

import core.file_interaction as fi
import core.technology_switch as tech_sw
import output_generators.logger as logger
import output_generators.traceability as traceability
import tmp.tmp as tmp

def set_information_flows(dfd) -> dict:
    """Goes through outgoing endpoints and matches them against incoming ones.
    """

    if not used_in_application():
        return

    if tmp.tmp_config.has_option("DFD", "information_flows"):
        information_flows = ast.literal_eval(tmp.tmp_config["DFD"]["information_flows"])
    else:
        information_flows = dict()

    incoming_endpoints = get_incoming_endpoints(dfd)
    add_endpoints_tagged_values(incoming_endpoints, dfd)
    outgoing_endpoints, information_flows = get_outgoing_endpoints(information_flows, dfd)
    new_information_flows = match_incoming_to_outgoing_endpoints(incoming_endpoints, outgoing_endpoints, dfd)

    for ni in new_information_flows.keys():
        try:
            id = max(information_flows.keys()) + 1
        except:
            id = 0
        information_flows[id] = new_information_flows[ni]

    tmp.tmp_config.set("DFD", "information_flows", str(information_flows))
    return information_flows

def used_in_application():
    if len(fi.search_keywords("RestTemplate")) > 0:
        return True
    return False

def get_incoming_endpoints(dfd) -> list:
    """Returns incoming API-endpoints of a repository using RestTemplate. Detection based on keywords '@[Request, Post, Get, Patch, Delete, Put]Mapping'
    """

    endpoints = set()
    files = fi.search_keywords("RequestMapping")

    for file in files.keys():

        f = files[file]
        if f["name"].split(".")[-1] != "java":
            continue
        else:
            service = tech_sw.detect_microservice(f["path"], dfd)

            bracket_count = 0               # variable for number of curly brackets to detect nested @RequestMappings
            current_parts = []              # list of "parts" of the path (e.g. /a/b/c -> ["a", "b", "c"])
            last_bc = -1                    # var to compare against last added endpoint

            for l in range(len(f["content"])):
                line = f["content"][l]
                mappings = ["RequestMapping", "GetMapping", "PostMapping", "PutMapping", "DeleteMapping", "PatchMapping"]
                mapping_in_line = False
                for m in mappings:
                    if m in line:
                        mapping_in_line = True
                        method = m.split("Mapping")[0]
                if mapping_in_line and not "import" in line:
                    endpoint_part = extract_endpoint_part(line)

                # manages the list of path-parts
                    if bracket_count > last_bc:
                        current_parts.append(endpoint_part)
                    elif bracket_count == last_bc:
                        current_parts = current_parts[:-1]
                        current_parts.append(endpoint_part)
                    elif bracket_count < last_bc:
                        dif = last_bc - bracket_count
                        current_parts = current_parts[:-dif]
                        current_parts.append(endpoint_part)

                # adds new endpoint
                    complete_endpoint = "/" + ("".join(current_parts).strip("/"))
                    if not complete_endpoint in [a for (a, b, c, d, e, f) in endpoints if b == service]:
                        endpoints.add((complete_endpoint, service, method, files[file]["path"], files[file]["line_nr"], files[file]["span"]))

                    last_bc = bracket_count

                bracket_count = adjust_bracket_count(bracket_count, line)

    tmp.tmp_config.set("DFD", "endpoints", str(endpoints))
    return endpoints

def extract_endpoint_part(line: str) -> str:
    endpoint_part = ""
    if "path" in line:          # not found in documentation, but used in piggy to name endpoint
        endpoint_part = line.split("path")[1].split(",")[0].split('\"')[1]
    elif "value" in line:       # usual keyword to describe path
        endpoint_part = line.split("value")[1].split(",")[0].split('\"')[1]
    elif not "," in line and "/" in line:       # only for the "/" endpoint
        endpoint_part = line.split('\"')[1]
    return endpoint_part

def adjust_bracket_count(bracket_count: int, line: str) -> int:
    """Helper function keeping track of number of opened brackets.
    """

    bracket_count += line.count("{")
    bracket_count -= line.count("}")
    return bracket_count

def add_endpoints_tagged_values(endpoint_tuples: list, dfd):
    """Adds tagged values containing the endpoitns to the microservices.
    """

    microservices = tech_sw.get_microservices(dfd)
    ordered_endpoints = dict()

    for endpoint_tuple in endpoint_tuples:
        if endpoint_tuple[1] in ordered_endpoints.keys():
            ordered_endpoints[endpoint_tuple[1]].add(endpoint_tuple[0])
        else:
            ordered_endpoints[endpoint_tuple[1]] = {endpoint_tuple[0]}

    for endpoint in ordered_endpoints.keys():
        for m in microservices.keys():
            if microservices[m]["servicename"] == endpoint:
                if "tagged_values" in microservices[m].keys():
                    microservices[m]["tagged_values"].append(('Endpoints', list(ordered_endpoints[endpoint])))
                else:
                    microservices[m]["tagged_values"] = [('Endpoints', list(ordered_endpoints[endpoint]))]
    tmp.tmp_config.set("DFD", "microservices", str(microservices))

def get_outgoing_endpoints(information_flows: dict, dfd) -> set:
    """Finds API calls from one service to another if restTemplate.exchange() is used in the application.
    """

    microservices = tech_sw.get_microservices(dfd)

    if microservices != None:
        microservices = [microservices[x]["servicename"] for x in microservices.keys()]
    else:
        microservices = list()
    outgoing_endpoints = set()

    commands = ["restTemplate.exchange", "restTemplate.getForObject"]
    for command in commands:
        files = fi.search_keywords(command)
        for file in files.keys():
            f = files[file]
            if "README" in f["name"] or "test" in f["path"].casefold():
                continue
            microservice = tech_sw.detect_microservice(f["path"], dfd)
            for line in range(len(f["content"])):
                if command in f["content"][line]:
                    func_inp = f["content"][line].split(command)[1]
                    if "," in func_inp:
                        new_outgoing_endpoint = func_inp.split(",")[0].strip()
                        line_nr = line
                    else:           # commands is multiline, looking for comma in next lines
                        found = False
                        i = 0
                        while not found and i < (len(f["content"]) - line):
                            if "," in f["content"][line + i]:
                                new_outgoing_endpoint = f["content"][line + i].split(",")[0].strip()
                                found = True
                                line_nr = line + i
                            i += 1

                    new_outgoing_endpoint, information_flows = find_rst_variable(new_outgoing_endpoint, f, line_nr, information_flows, microservice, dfd)
                    if new_outgoing_endpoint:
                        outgoing_endpoints.add((new_outgoing_endpoint, microservice,  files[file]["path"], files[file]["line_nr"], files[file]["span"]))
                    else:
                        logger.write_log_message("\t\tSomething didn't work", "debug")

    return outgoing_endpoints, information_flows

def find_rst_variable(parameter: str, file: dict, line_nr: int, information_flows: dict, microservice: str, dfd):

    # check if service name in parameter, if yes, add flow directly
    microservices = tech_sw.get_microservices(dfd)
    for m in microservices.keys():
        if microservices[m]["servicename"] in parameter:
            try:
                id = max(information_flows.keys()) + 1
            except:
                id = 0
            information_flows[id] = dict()

            information_flows[id]["sender"] = microservice
            information_flows[id]["receiver"] = microservices[m]["servicename"]
            information_flows[id]["stereotype_instances"] = ["restful_http"]

            trace = dict()
            trace["item"] = microservice + " -> " + microservices[m]["servicename"]
            trace["file"] = file["path"]
            trace["line"] = file["line_nr"]
            trace["span"] = file["span"]
            traceability.add_trace(trace)

    variable = False
    if "+" in parameter:    # string consisting of multiple parts
        parameters = parameter.split("+")
    else:           # only one part, but put it in list to make compatible with multi-part-case
        parameters = [parameter]

    for p in range(len(parameters)):    # Treat each part individually
        parameters[p] = parameters[p].strip()
        if "(" in parameters[p] or ")" in parameters[p]:
            logger.write_log_message("\tPart of the string is return value of a function. Can not determine this statically.", "debug")
            return False, information_flows
        elif check_if_variable_is_input(parameters[p], file, line_nr):
            parameters[p] = "{" + parameters[p] + "}"
        elif parameters[p][0] == "\"" and parameters[p][-1] == "\"" and parameters[p].count("\"") == 2:     # it's a string, no change needed
            parameters[p] = parameters[p].strip().strip("\"")
        elif "." in parameters[p]:               # means that it refers to some other file or class -> look for that file, then go through lines
            try:
                parameter_variable = parameters[p].split(".")[-1]
                parameter_class = parameters[p].split(".")[-2]
                files_containing_class = fi.search_keywords("class " + str(parameter_class))
                correct_file = None
                for filec in files_containing_class.keys():
                    fc = files_containing_class[filec]
                    for linec in range(len(fc["content"])):
                        if "class" in fc["content"][linec] and parameter_class in fc["content"][linec]:
                            correct_file = fc["name"]
                            inside_class_definition = True
                            lines_class = len(fc["content"]) - linec
                            i = 0
                            while inside_class_definition and i < lines_class:
                                if "}" in fc["content"][i]:
                                    inside_class_definition = False
                                i += 1
                                if parameter_variable in fc["content"][linec + i] and "=" in fc["content"][linec + i]:
                                    parameters[p] = fc["content"][linec + i].split("=")[1].strip().strip(";").strip().strip("\"")
                                    print("\t\tFound " + str(parameters[p]) + " in file " + str(correct_file))
                                    if parameters[p][0] != "\"" or parameters[p][-1] != "\"":
                                        parameters[p], x = find_rst_variable(parameters[p], fc, linec)     # recursive step
            except:
                print("\tCould not find a definition for " + str(parameters[p]) + ".")
                return False, information_flows
        else:           # means that it's a variable in this file -> go through lines to find it
            found = False
            line = 0
            parameter_variable = parameters[p]
            while found == False and line < len(file["content"]):
                # Assignment of var
                if parameter_variable in file["content"][line] and "=" in file["content"][line]:
                    parameters[p] = file["content"][line].split("=")[1].strip().strip(";").strip()
                    if parameters[p].strip("\"").strip() != "":
                        if parameters[p][0] != "\"" or parameters[p][-1] != "\"":
                            parameters[p], x = find_rst_variable(parameters[p], file, line)      # recursive step
                        if parameters[p] != False:
                            parameters[p] = parameters[p].strip("\"").strip()
                            logger.write_log_message("\t\tFound " + str(parameters[p]) + " in this file.", "info")
                        found = True
                # Var injection via @Value
                elif parameter_variable in file["content"][line]:
                    if "@Value" in file["content"][line - 1]:
                        # injected = file["content"][line - 1].split("@Value(")[1].strip(")")
                        # look in config file
                        pass

                line += 1
            if found == False:
                print("\tCould not find a definition for " + str(parameters[p]) + ".")
                return False, information_flows
    invalid = False
    for p in parameters:
        if p == None or p == False:
            invalid = True
    if not invalid:
        variable = "".join(parameters)      # put together parts for complete URL
    return variable, information_flows

def check_if_variable_is_input(variable: str, file, line_nr: int) -> bool:
    """Detects if a string in a given line is an input parameter.
    """

    open_curly_brackets = 0
    while open_curly_brackets != 1 and line_nr > 0:
        line = file["content"][line_nr]
        if "}" in line:
            open_curly_brackets -= 1
        if "{" in line:
            open_curly_brackets += 1
        if open_curly_brackets == 1:
            if "if" in line or "else" in line or "else if" in line:
                open_curly_brackets -= 1
        if open_curly_brackets == 1:
            inputs = line.split("{")[0].strip().split("(")[-1].strip().strip(")").strip().split(",")
            for i in inputs:
                if variable in i:
                    return True
        line_nr -= 1
    return False

def match_incoming_to_outgoing_endpoints(incoming_endpoints: list, outgoing_endpoints: list, dfd) -> dict:
    """ Find information flows by matching incomgin to outgoing endpoints. Returns list of flows.
    """

    microservices = tech_sw.get_microservices(dfd)
    information_flows_set = set()
    information_flows = dict()
    for o in outgoing_endpoints:
        for i in incoming_endpoints:
            if i[0] in o[0] and i[1] in o[0]:
                information_flows_set.add((o[1], i[1], i[0]))       # (sending service, receiving service, receving endpoint)

                trace = dict()
                trace["item"] = o[0] + " -> " + i[1]
                trace["file"] = o[2]
                trace["line"] = o[3]
                trace["span"] = o[4]
                traceability.add_trace(trace)

    # turn it into dict
    for i in information_flows_set:

        # check for load balancer, circuit breaker, authentication, and SSL
        stereotype_instances = list()
        stereotype_instances.append("restful_http")
        tagged_values = list()
        for m in microservices.keys():
            if microservices[m]["servicename"] == i[0]:
                for prop in microservices[m]["properties"]:
                    if prop[0] == "load_balancer":
                        stereotype_instances.append("load_balanced_link")
                        tagged_values.append(("Load Balancer", prop[1]))
                    elif prop[0] == "circuit_breaker":
                        stereotype_instances.append("circuit_breaker_link")
                        tagged_values.append(("Circuit Breaker", prop[1]))
                for s in microservices[m]["stereotype_instances"]:
                    if s == "authentication_scope_all_requests":
                        stereotype_instances.append("authenticated_request")
                    elif s == "ssl_enabled":
                        stereotype_instances.append("ssl_secured")

        # set flow
        try:
            id = max(information_flows.keys()) + 1
        except:
            id = 0
        information_flows[id] = dict()

        information_flows[id]["sender"] = i[0]
        information_flows[id]["receiver"] = i[1]
        information_flows[id]["endpoint"] = i[2]

        if stereotype_instances:
            information_flows[id]["stereotype_instances"] = stereotype_instances
            information_flows[id]["tagged_values"] = tagged_values

    return information_flows


INPUT_S ='''/
110011110101

101010101101
111001111000
001011111101
101111010110
111110100011
111011111010
010101001111
000011001110
111010011011
110111111010
100011101110
000110111001
111010110101
010001011001
011011111111
111101001011
001111110001
110100001110
101000100001
101011001111
100110101010
100011101011
001000110100
'''

#For o2 generator :
#Take for the position of the bit the most common bit from the input
#If there is the same number of 0 and 1, take 1
#Then keep only the numbers with this bit in this position

binary = [str(line) for line in INPUT_S.splitlines()]

def delNoLen(subList) :
    for i in subList :
        if len(i) == 0 or len(i) == 1 :
            subList.remove(i)
    return subList

def countMoreForIndex(index, listBin) :
    zero = 0
    one = 0
    for j in listBin :
        if( j[index] == '0') :
            zero += 1
        else :
            one += 1
    if zero > one :
        return '0'
    else :
        return '1'

def selectWithParam(param, index, listBin) :
    nbDel = 0
    subList = listBin.copy()
    for j in range(len(listBin)) :
        if listBin[j][index] != param :
            del subList[j - nbDel]
            nbDel += 1
    return subList

def findO2(listBin) :
    subList = delNoLen(listBin)
    for index in range(len(subList[0])) :
        if(len(subList) == 1) :
            return subList[0]
        countmore = countMoreForIndex(index,subList)
        subList = selectWithParam(countmore,index,subList)
    return subList[0]

def countLessForIndex(index, listBin) :
    zero = 0
    one = 0
    for j in listBin :
        if( j[index] == '0') :
            zero += 1
        else :
            one += 1
    if zero > one :
        return '1'
    else :
        return '0'

def findCO2(listBin) :
    subList = delNoLen(listBin)
    for index in range(len(subList[0])) :
        if(len(subList) == 1) :
            return subList[0]
        countless = countLessForIndex(index,subList)
        subList = selectWithParam(countless,index,subList)
    return subList[0]

def bintodec(num) :
    value = 0
    for i in range(len(num)-1,-1,-1) :
        if num[i] == '0' :
            continue
        else :
            if i == len(num)-1 :
                value += 1
            else :
                value += 2**(len(num)-i-1)
    return value

o2 = bintodec(findO2(binary))
co2 = bintodec(findCO2(binary))
res = o2 * co2
print(res)


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

flights = pd.read_csv("./data/flights.csv")
airports = pd.read_csv("./data/airports.csv", index_col="Orig")

pd.set_option('display.max_columns', None)
airports["MaxArrDelay"] = flights.groupby('Origin')['ArrDelay'].max()
airports.dropna(subset=['MaxArrDelay'], inplace=True)
sorted_airports = airports.sort_values(by='TotalSeats', ascending=False)
# sorted_airports = sorted_airports.head(30)

sns.catplot(x="MaxArrDelay",
            y="Orig",
            kind="strip",
            data=sorted_airports,
            order=sorted_airports.index, #airports["TotalSeats"].sort_values(ascending=True).index, # flights['Origin'].value_counts().index
            height=8,
            aspect=1,
            palette='coolwarm_r')

for code in ["HNL", "CLT"]:
    plt.text(sorted_airports.loc[code, "MaxArrDelay"], sorted_airports.index.get_loc(code), f"{code}, {sorted_airports.loc[code, 'MaxArrDelay']}", ha='right')

# for index, row in sorted_airports.iterrows():
#     plt.text(row["MaxArrDelay"], row["TotalSeats"], index, fontsize=8, color='black')

plt.yticks(rotation=45)
plt.yticks(fontsize=10)
plt.show()


class ScorePartWiseMixin(object):

    score_block_open  = '\\score { \n <<'
    score_block_close = '\n >> } \n'

    @property
    def parts(self):
        return self.part[:]

    @property
    def score_block_contents(self):
        result = []
        for elt in self.part_list.content():
            result.append(elt.score_block_format)
        return result

    def format_parts(self):
        result = []
        for part in self.parts:
            result.append(part.lilypond_format)
        return '\n'.join(result)

    def format_lyrics(self):
        result = []
        for part in self.parts:
            result.append(part.format_lyrics)
        return '\n'.join(result)

    def format_score_block(self):
        result = []

        for score_part in self.part_list.score_part[:]:
            score_part.part = self.get_corresponding_part(score_part)

        result.append(self.score_block_open)
        result.extend(self.score_block_contents)
        result.append(self.score_block_close)

        return '\n'.join(result)

    def get_corresponding_part(self, score_part):
        try:
            return filter(lambda x: x.part_id == score_part.part_id, self.parts)[0]
        except:
            return None

# flow: -> a) part_contents, b) score_representation


import sbibm
import torch
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
import random

from sbibm.utils.io import get_tensor_from_csv, save_float_to_csv
from valdiags.plot_pdfs import multi_corner_plots

from utils import fwd_flow_transform_obs, inv_flow_transform_obs

import os

if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser(
        description="Run L-C2ST on sbi-benchmarking example."
    )
    parser.add_argument(
        "--experiment",
        "-e",
        type=str,
        default="multirun/2023-03-02/13-00-57",
        help='Experiment name: "multirun/yyyy-mm-dd/hh-mm-ss"',
    )
    parser.add_argument(
        "--num_observation",
        "-no",
        type=int,
        default=1,
        help="Observation number between 1 and 10.",
    )
    parser.add_argument(
        "--task", "-t", type=str, default="gaussian_mixture", help="sbibm task name"
    )

    parser.add_argument(
        "--cal_size",
        "-cs",
        type=int,
        default=10000,
        help="calbration set size used to train lc2st.",
    )
    parser.add_argument(
        "--test_size",
        "-ts",
        type=int,
        default=10000,
        help="number of base-dist samples for l-c2st evaluation.",
    )

    parser.add_argument(
        "--n_trials_null",
        "-nt",
        type=int,
        default=100,
        help="number of trials under the null hypothesis.",
    )
    parser.add_argument(
        "--n_ensemble",
        "-ne",
        type=int,
        default=10,
        help="number of models for ensemble-prediction.",
    )

    parser.add_argument(
        "--run_htest",
        "-r",
        action="store_true",
        help="Whether to run the lc2st or just generate plots.",
    )

    parser.add_argument(
        "--correct_posterior",
        "-c",
        action="store_true",
        help="Whether to run posterior corretion or not.",
    )

    parser.add_argument(
        "--n_rej_trials",
        "-nr",
        type=int,
        default=1,
        help="How many times to run rejection sampling.",
    )

    parser.add_argument(
        "--z_space",
        "-z",
        action="store_true",
        help="Whether to run lc2st in z-space or not.",
    )

    parser.add_argument(
        "--clf_name",
        "-cn",
        type=str,
        default="mlp_sbi",
        help="Which classifier to use: one of 'mlp_sbi', 'mlp_base'.",
    )

    args = parser.parse_args()

    # Seeding
    torch.manual_seed(1)
    random.seed(1)
    np.random.seed(1)

    PATH_EXPERIMENT = Path.cwd() / args.experiment / "lc2st_results"
    if not os.path.exists(PATH_EXPERIMENT):
        os.mkdir(PATH_EXPERIMENT)

    PATH_EXPERIMENT_OBS = PATH_EXPERIMENT / f"{args.num_observation - 1}"
    if not os.path.exists(PATH_EXPERIMENT_OBS):
        os.mkdir(PATH_EXPERIMENT_OBS)

    PATH_EXPERIMENT_REF = Path.cwd() / args.experiment / "0"

    task = sbibm.get_task(args.task)
    prior = task.get_prior()
    simulator = task.get_simulator()
    observation = task.get_observation(num_observation=args.num_observation)

    posterior_samples = task.get_reference_posterior_samples(args.num_observation)

    # loaf global objects that should stay the same over all observations
    # (this is for amortized algorithms)

    posterior_est = torch.load(PATH_EXPERIMENT_REF / "posterior_est.pkl")
    posterior_est.flow = posterior_est.flow.set_default_x(observation)

    inv_flow_samples_ref = inv_flow_transform_obs(
        posterior_samples, observation, posterior_est.flow
    )

    if os.path.exists(PATH_EXPERIMENT_OBS / "algorithm_posterior_samples.pkl"):
        algorithm_posterior_samples = torch.load(
            PATH_EXPERIMENT_OBS / "algorithm_posterior_samples.pkl"
        )
    else:
        algorithm_posterior_samples = fwd_flow_transform_obs(
            posterior_est.flow.net._distribution.sample(
                len(posterior_samples)
            ).detach(),
            observation,
            posterior_est.flow,
        )
        torch.save(
            algorithm_posterior_samples,
            PATH_EXPERIMENT_OBS / "algorithm_posterior_samples.pkl",
        )

    cal_set = torch.load(PATH_EXPERIMENT_REF / "calibration_dataset.pkl")
    x_cal = cal_set["x"][: args.cal_size]
    theta_cal = cal_set["theta"][: args.cal_size]
    dim = theta_cal.shape[-1]

    base_dist_samples_cal = torch.load(PATH_EXPERIMENT_REF / "base_dist_samples.pkl")[
        : args.cal_size
    ]

    if os.path.exists(PATH_EXPERIMENT / "algorithm_posterior_samples_cal.pkl"):
        algorithm_posterior_samples_cal = torch.load(
            PATH_EXPERIMENT / "algorithm_posterior_samples_cal.pkl"
        )
    else:
        algorithm_posterior_samples_cal = []
        for z, x in zip(base_dist_samples_cal, x_cal):
            z, x = z[None, :], x[None, :]
            # algorithm_posterior_samples_cal.append(est.sample(x=x).detach())
            # # this is not the same as transforming...
            algorithm_posterior_samples_cal.append(
                fwd_flow_transform_obs(z, x, posterior_est.flow)
            )
        algorithm_posterior_samples_cal = torch.stack(algorithm_posterior_samples_cal)[
            :, 0, :
        ]
        torch.save(
            algorithm_posterior_samples_cal,
            PATH_EXPERIMENT / "algorithm_posterior_samples_cal.pkl",
        )

    if os.path.exists(PATH_EXPERIMENT / "inv_flow_samples_cal.pkl"):
        inv_flow_samples_cal = torch.load(PATH_EXPERIMENT / "inv_flow_samples_cal.pkl")
    else:
        inv_flow_samples_cal = []
        for theta, x in zip(theta_cal, x_cal):
            theta, x = theta[None, :], x[None, :]
            inv_flow_samples_cal.append(
                inv_flow_transform_obs(theta, x, posterior_est.flow)
            )
        inv_flow_samples_cal = torch.stack(inv_flow_samples_cal)[:, 0, :]
        torch.save(inv_flow_samples_cal, PATH_EXPERIMENT / "inv_flow_samples_cal.pkl")

    if os.path.exists(
        PATH_EXPERIMENT / f"trained_clfs_z_{args.z_space}_{args.clf_name}.pkl"
    ):
        trained_clfs = torch.load(
            PATH_EXPERIMENT / f"trained_clfs_z_{args.z_space}_{args.clf_name}.pkl"
        )
    else:
        trained_clfs = []

    if args.z_space:
        path_probas_null = (
            Path.cwd()
            / "probas_null_lc2st_z"
            / f"{args.cal_size}"
            / f"{args.task}"
            / f"lc2st_probas_null_z_True_{args.clf_name}.pkl"
        )
    else:
        path_probas_null = (
            PATH_EXPERIMENT_OBS / f"lc2st_probas_null_z_False_{args.clf_name}.pkl"
        )

    if os.path.exists(path_probas_null):
        probas_null = torch.load(path_probas_null)
    else:
        probas_null = []

    # # =============== Reference plots ==================

    # # True conditional distributions: norm, inv-flow
    # from valdiags.localC2ST_old import flow_vs_reference_distribution

    # # embedding not intergrated in transform method (includes standardize)

    # if dim <= 2:
    #     flow_vs_reference_distribution(
    #         samples_ref=base_dist_samples_cal,
    #         samples_flow=inv_flow_samples_ref,
    #         z_space=True,
    #         dim=dim,
    #         hist=False,
    #     )
    #     plt.savefig(PATH_EXPERIMENT_OBS / "z_space_reference.pdf")
    #     plt.show()

    # samples_list = [base_dist_samples_cal, inv_flow_samples_ref]
    # legends = [
    #     r"Ref: $\mathcal{N}(0,1)$",
    #     r"NPE: $T_{\phi}^{-1}(\Theta;x_0) \mid x_0$",
    # ]
    # colors = ["blue", "orange"]
    # multi_corner_plots(
    #     samples_list,
    #     legends,
    #     colors,
    #     title=r"Base-Distribution vs. Inverse Flow-Transformation (of $\Theta \mid x_0$)",
    #     labels=[r"$z$" f"_{i+1}" for i in range(dim)],
    #     domain=(torch.ones(dim) * -5, torch.ones(dim) * 5),
    # )
    # plt.savefig(PATH_EXPERIMENT_OBS / "z_space_reference_corner.pdf")
    # plt.show()

    # # True vs. estimated posterior samples
    # if dim <= 2:
    #     flow_vs_reference_distribution(
    #         samples_ref=posterior_samples,
    #         samples_flow=algorithm_posterior_samples,
    #         z_space=False,
    #         dim=dim,
    #         hist=False,
    #     )
    #     plt.savefig(PATH_EXPERIMENT_OBS / "theta_space_reference.pdf")
    #     plt.show()

    # samples_list = [posterior_samples, algorithm_posterior_samples]
    # legends = [r"Ref: $p(\Theta \mid x_0)$", r"NPE: $p(T_{\phi}(Z;x_0))$"]
    # colors = ["blue", "orange"]
    # multi_corner_plots(
    #     samples_list,
    #     legends,
    #     colors,
    #     title=r"True vs. Estimated distributions at $x_0$",
    #     labels=[r"$\theta$" + f"_{i+1}" for i in range(dim)],
    #     # domain=(torch.tensor([-15, -15]), torch.tensor([5, 5])),
    # )
    # plt.savefig(PATH_EXPERIMENT_OBS / "theta_space_reference_corner.pdf")
    # plt.show()

    # plt.close("all")

    # =============== Hypothesis test and ensemble probas ================
    metrics = ["probas_mean", "w_dist", "TV"]

    if args.run_htest:
        print("Running L-C2ST...")
        from valdiags.localC2ST_old import lc2st_htest_sbibm

        test_size = args.test_size

        if args.clf_name == "mlp_base":
            clf_kwargs = {"alpha": 0, "max_iter": 25000}
        else:
            clf_kwargs = None

        if args.z_space:
            P = base_dist_samples_cal
            Q = inv_flow_samples_cal
            if os.path.exists(PATH_EXPERIMENT_OBS / f"P_eval_z_{args.z_space}.pkl"):
                P_eval = torch.load(
                    PATH_EXPERIMENT_OBS / f"P_eval_z_{args.z_space}.pkl"
                )
            else:
                P_eval = posterior_est.flow.net._distribution.sample(test_size).detach()
            null_dist = posterior_est.flow.net._distribution
            null_samples_list = None
        else:
            P = algorithm_posterior_samples_cal
            Q = theta_cal
            if os.path.exists(PATH_EXPERIMENT_OBS / f"P_eval_z_{args.z_space}.pkl"):
                P_eval = torch.load(
                    PATH_EXPERIMENT_OBS / f"P_eval_z_{args.z_space}.pkl"
                )
            else:
                P_eval = algorithm_posterior_samples[:test_size]
            null_dist = None

            null_samples_list = []
            for _ in range(args.n_trials_null):
                samples_z = posterior_est.flow.net._distribution.sample(
                    args.cal_size
                ).detach()
                null_samples_list.append(
                    fwd_flow_transform_obs(samples_z, observation, posterior_est.flow)
                )

        (
            p_values,
            test_stats,
            probas_ens,
            probas_null,
            t_stats_null,
            trained_clfs,
            run_time,
        ) = lc2st_htest_sbibm(
            P,
            Q,
            cal_set["x"],
            P_eval=P_eval,
            x_eval=observation,
            null_dist=null_dist,
            null_samples_list=null_samples_list,
            test_stats=metrics,
            n_trials_null=args.n_trials_null,
            n_ensemble=args.n_ensemble,
            clf_kwargs=None,
            probas_null=probas_null,
            trained_clfs=trained_clfs,
        )
        lc2st_htest_results = {
            "p_values": p_values,
            "test_stats": test_stats,
            "t_stats_null": t_stats_null,
        }
        torch.save(
            lc2st_htest_results,
            PATH_EXPERIMENT_OBS
            / f"lc2st_htest_results_z_{args.z_space}_{args.clf_name}.pkl",
        )
        torch.save(
            probas_ens,
            PATH_EXPERIMENT_OBS
            / f"lc2st_probas_ensemble_z_{args.z_space}_{args.clf_name}.pkl",
        )

        torch.save(P_eval, PATH_EXPERIMENT_OBS / f"P_eval_z_{args.z_space}.pkl")

        torch.save(probas_null, path_probas_null)
        torch.save(
            trained_clfs,
            PATH_EXPERIMENT / f"trained_clfs_z_{args.z_space}_{args.clf_name}.pkl",
        )

        if run_time != 0:
            save_float_to_csv(
                PATH_EXPERIMENT
                / f"run_time_1_clf_z_{args.z_space}_{args.clf_name}.csv",
                run_time,
            )

        print("Finished running L-C2ST.")

    P_eval = torch.load(PATH_EXPERIMENT_OBS / f"P_eval_z_{args.z_space}.pkl")
    probas_ens = torch.load(
        PATH_EXPERIMENT_OBS
        / f"lc2st_probas_ensemble_z_{args.z_space}_{args.clf_name}.pkl"
    )

    probas_null = torch.load(path_probas_null)

    lc2st_htest_results = torch.load(
        PATH_EXPERIMENT_OBS
        / f"lc2st_htest_results_z_{args.z_space}_{args.clf_name}.pkl"
    )
    test_stats = lc2st_htest_results["test_stats"]
    t_stats_null = lc2st_htest_results["t_stats_null"]
    p_values = lc2st_htest_results["p_values"]

    # # =============== Result plots ===============

    from valdiags.localC2ST_old import box_plot_lc2st

    for m in metrics:
        box_plot_lc2st(
            [test_stats[m]], t_stats_null[m], labels=["NPE"], colors=["red"],
        )
        plt.savefig(
            PATH_EXPERIMENT_OBS
            / f"lc2st_htest_box_plot_metric_{m}_z_{args.z_space}_{args.clf_name}.pdf"
        )
        plt.show()
        print(f"pvalues {m}:", p_values[m])

    from valdiags.localC2ST_old import pp_plot_lc2st

    pp_plot_lc2st([probas_ens], probas_null, labels=["NPE"], colors=["red"])
    plt.savefig(
        PATH_EXPERIMENT_OBS / f"lc2st_pp_plot_z_{args.z_space}_{args.clf_name}.pdf"
    )
    plt.show()

    # =============== Interpretability plots ==================
    if dim <= 2:
        # High / Low probability regions
        from valdiags.localC2ST_old import eval_space_with_proba_intensity

        eval_space_with_proba_intensity(
            probas_ens, probas_null, P_eval, dim=dim, z_space=args.z_space
        )
        plt.savefig(
            PATH_EXPERIMENT_OBS
            / f"eval_with_lc2st_proba_intensity_z_{args.z_space}_{args.clf_name}.pdf"
        )
        plt.show()

    # =============== Posterior correction ==================

    if args.correct_posterior:
        from valdiags.posterior_correction import (
            rejection_sampling,
            clf_ratio_obs,
            corrected_pdf,
            flow_sampler,
            uniform_sampler,
        )
        from functools import partial

        flow_transform = partial(
            fwd_flow_transform_obs, observation=observation, flow=posterior_est.flow
        )

        inv_flow_transform = partial(
            inv_flow_transform_obs, observation=observation, flow=posterior_est.flow
        )

        base_dist_sampler = posterior_est.flow.net._distribution.sample

        if args.z_space:

            ## ====== BASE DISTRIBUTION SPACE =======

            # proposal = base_dist = normal
            proposal_sampler = base_dist_sampler
            # f = ratio
            f = partial(clf_ratio_obs, x_obs=observation, clfs=trained_clfs)

            # sample from normal_pdf * ratio = p(z|x_obs)
            acc_rej_samples_normal = []
            for _ in range(args.n_rej_trials):
                acc_rej_samples_normal.append(
                    rejection_sampling(proposal_sampler=proposal_sampler, f=f)
                )

            samples_list = [P_eval.numpy()] + acc_rej_samples_normal
            legends = ["normal: Z"] + [
                "corrected normal acc_rej_normal"
            ] * args.n_rej_trials
            colors = ["grey"] + ["red"] * args.n_rej_trials

            if dim < 3:
                # proposal = uniform
                # --> very long in high dimensions
                proposal_sampler = partial(uniform_sampler, dim=dim)
                # f = ratio * normal_pdf = p(z|x_obs)
                f = partial(
                    corrected_pdf,
                    dist=posterior_est.flow.net._distribution,
                    x_obs=observation,
                    clfs=trained_clfs,
                )
                # sample from ratio * normal_pdf \approx p(z|x_obs)
                acc_rej_samples_uniform = []
                for _ in range(args.n_rej_trials):
                    acc_rej_samples_uniform.append(
                        rejection_sampling(proposal_sampler=proposal_sampler, f=f)
                    )

                samples_list += acc_rej_samples_uniform
                legends += ["corrected normal acc_rej_uniform"] * args.n_rej_trials
                colors += ["green"] * args.n_rej_trials

            samples_list += [inv_flow_samples_ref.numpy()]
            legends += [r"Reference: $T_{\phi}^{-1}(\Theta, x_0)\mid x_0$"]
            colors += ["orange"]
            multi_corner_plots(
                samples_list,
                legends,
                colors,
                title="correction in z-space",
                labels=[r"$z$" + f"_{i+1}" for i in range(dim)],
                domain=(torch.ones(dim) * -5, torch.ones(dim) * 5),
            )
            plt.savefig(
                PATH_EXPERIMENT_OBS / f"z_space_correction_corner_{args.clf_name}.pdf"
            )
            plt.show()

            ## ======== PARAMETER SPACE =========
            flow_thetas = flow_sampler(
                args.test_size, base_dist_sampler, flow_transform
            )

            # proposal = flow: samples = \Theta
            proposal_sampler = partial(
                flow_sampler,
                base_dist_sampler=base_dist_sampler,
                flow_transform=flow_transform,
            )
            # f = ratio r(T_{\phi}^{-1}(\Theta))
            f = partial(
                clf_ratio_obs,
                x_obs=observation,
                clfs=trained_clfs,
                inv_flow_transform=inv_flow_transform,
            )
            # sample from ratio * flow \approx p(\theta | x_obs)
            acc_rej_samples_flow = []
            for _ in range(args.n_rej_trials):
                acc_rej_samples_flow.append(
                    rejection_sampling(proposal_sampler=proposal_sampler, f=f)
                )
            torch.save(
                acc_rej_samples_flow,
                PATH_EXPERIMENT_OBS
                / f"acc_rej_samples_flow_z_{args.z_space}_{args.clf_name}.pkl",
            )

            # acc_rej_samples_approx_flow = []
            # for _ in range(args.n_rej_trials):
            #     acc_rej_samples_approx_flow.append(
            #         rejection_sampling(
            #             proposal_sampler=proposal_sampler, f=f, approximate=True
            #         )
            #     )

            samples_list = (
                [flow_thetas.detach().numpy()]
                + acc_rej_samples_flow
                # + acc_rej_samples_approx_flow
            )

            legends = (
                [r"NPE: $T_{\phi}(Z;x_0)$"]
                + ["corrected NPE acc_rej_flow"] * args.n_rej_trials
                # + ["corrected NPE acc_rej_approx_flow"] * args.n_rej_trials
            )

            colors = (
                ["orange"]
                + ["red"] * args.n_rej_trials
                # + ["purple"] * args.n_rej_trials
            )

            if dim < 3:
                # --> still very long in high dimensions
                # proposal = uniform, samples = T_phi(U)
                # --> not U to get into the right range of flow-pdf-values
                proposal_sampler = partial(
                    uniform_sampler, dim=dim, flow_transform=flow_transform,
                )
                # for T_phi(u) the proposal distribution is p(u)|detJT_phi^-1|, we only need q_phi/det = N(u)
                f = partial(
                    corrected_pdf,
                    # dist=posterior_est.flow,
                    dist=posterior_est.flow.net._distribution,
                    x_obs=observation,
                    clfs=trained_clfs,
                    inv_flow_transform=inv_flow_transform,
                )

                # from valdiags.posterior_correction import corrected_pdf_old
                # # f = r(u)*q_phi(T_phi(u))
                # # --> doing f = r(T_phi^{-1}(u)*q_phi(u) takes too much time, doesn't converge...
                # f = partial(
                #     corrected_pdf_old,
                #     dist=posterior_est.flow,
                #     x_obs=observation,
                #     clfs=trained_clfs,
                #     inv_flow_transform=inv_flow_transform,
                # )

                # sample from ratio * flow \approx p(\theta | x_obs)
                acc_rej_samples_uniform = []
                for _ in range(args.n_rej_trials):
                    acc_rej_samples_uniform.append(
                        rejection_sampling(proposal_sampler=proposal_sampler, f=f)
                    )

                samples_list += acc_rej_samples_uniform

                legends += ["corrected NPE acc_rej_uniform"] * args.n_rej_trials

                colors += ["green"] * args.n_rej_trials

            samples_list += [posterior_samples]
            legends += [r"Reference: $\Theta \mid x_0$"]
            colors += ["blue"]

            multi_corner_plots(
                samples_list,
                legends,
                colors,
                title="correction in z-space",
                labels=[r"$\theta$" + f"_{i+1}" for i in range(dim)]
                # domain=(torch.tensor([-15, -15]), torch.tensor([5, 5])),
            )
            plt.savefig(
                PATH_EXPERIMENT_OBS
                / f"posterior_correction_z_space_corner_{args.clf_name}.pdf"
            )
            plt.show()

        else:

            # proposal = flow: samples = \Theta
            proposal_sampler = partial(
                flow_sampler,
                base_dist_sampler=base_dist_sampler,
                flow_transform=flow_transform,
            )
            # f = ratio r(\Theta)
            f = partial(clf_ratio_obs, x_obs=observation, clfs=trained_clfs,)
            # sample from ratio * flow_pdf \approx p(\theta | x_obs)
            acc_rej_samples_flow = []
            for _ in range(args.n_rej_trials):
                acc_rej_samples_flow.append(
                    rejection_sampling(proposal_sampler=proposal_sampler, f=f)
                )

            torch.save(
                acc_rej_samples_flow,
                PATH_EXPERIMENT_OBS
                / f"acc_rej_samples_flow_z_{args.z_space}_{args.clf_name}.pkl",
            )

            # acc_rej_samples_approx_flow = []
            # for _ in range(args.n_rej_trials):
            #     acc_rej_samples_approx_flow.append(
            #         rejection_sampling(
            #             proposal_sampler=proposal_sampler, f=f, approximate=True
            #         )
            #     )

            samples_list = (
                [P_eval.numpy()]
                + acc_rej_samples_flow
                # + acc_rej_samples_approx_flow
            )

            legends = (
                [r"NPE: $\Theta \sim q_{\phi}(\theta \mid x_0)$"]
                + ["corrected NPE acc_rej_flow"] * args.n_rej_trials
                # + ["corrected NPE acc_rej_approx_flow"] * args.n_rej_trials
            )

            colors = (
                ["orange"]
                + ["red"] * args.n_rej_trials
                # + ["purple"] * args.n_rej_trials
            )

            if dim < 3:
                # --> still very long in high dimensions
                # proposal = uniform, samples = T_phi(U)
                # --> not U to get into the right range of flow-pdf-values
                # --> still very long in high dimensions
                proposal_sampler = partial(
                    uniform_sampler, dim=dim, flow_transform=flow_transform,
                )
                # for T_phi(u) the proposal distribution is p(u)|detJT_phi^-1|, we only need q_phi/det = N(u)
                f = partial(
                    corrected_pdf,
                    # dist=posterior_est.flow,
                    dist=posterior_est.flow.net._distribution,
                    x_obs=observation,
                    clfs=trained_clfs,
                    inv_flow_transform=inv_flow_transform,
                    z_space=False,
                )

                # from valdiags.posterior_correction import corrected_pdf_old
                # # f = r(u)*q_phi(T_phi(u))
                # # --> doing f = r(T_phi^{-1}(u)*q_phi(u) takes too much time, doesn't converge...
                # f = partial(
                #     corrected_pdf_old,
                #     dist=posterior_est.flow,
                #     x_obs=observation,
                #     clfs=trained_clfs,
                # )

                # sample from ratio * flow \approx p(\theta | x_obs)
                acc_rej_samples_uniform = []
                for _ in range(args.n_rej_trials):
                    acc_rej_samples_uniform.append(
                        rejection_sampling(proposal_sampler=proposal_sampler, f=f)
                    )

                samples_list += acc_rej_samples_uniform

                legends += ["corrected NPE acc_rej_uniform"] * args.n_rej_trials

                colors += ["green"] * args.n_rej_trials

            samples_list += [posterior_samples]
            legends += [r"Reference: $\Theta \sim p(\theta \mid x_0)$"]
            colors += ["blue"]

            multi_corner_plots(
                samples_list,
                legends,
                colors=colors,
                title="correction in parameter space",
                labels=[r"$\theta$" + f"_{i+1}" for i in range(dim)]
                # domain=(torch.tensor([-5, -5]), torch.tensor([5, 5])),
            )
            plt.savefig(
                PATH_EXPERIMENT_OBS
                / f"posterior_correction_theta_space_corner_{args.clf_name}.pdf"
            )
            plt.show()


def formarBinario(real):
    inteiro = int(real)
    decimal = real - inteiro
    binario = ""
    newBIN = ""

    while decimal > 0.0:
        restante = decimal * 2.0
        if restante >= 1.0:
            binario += "1"
            decimal = restante - 1
        else:
            binario += "0"
            decimal = restante

    newBIN = binario
    binario = ""
    for z in range(0, 12):
        binario += newBIN[z]

    return (binario)

def aproxMaior(binario):
    newBIN = ""
    editado = [".",".",".",".",".",".",".",".",".",".",".",".","."]
    casa = len(binario) - 1
    original = 0

    for x in range(casa, 0, -1):
        if binario[x] == "1":
            editado.insert(x, binario[x].replace("1","0"))
        else:
            editado.insert(x, binario[x].replace("0","1"))
            original = x
            break

    editado = str(editado).replace(".","").replace("[","").replace("'"
    ,"").replace("]","").replace(",","").replace("","").replace(" ","")

    for y in range(0, original):
        newBIN += binario[y]

    return (newBIN+editado)

def formarExato(binario):
    bina = binario
    exato = 0.0

    for x in range(0, len(bina)):
        if bina[x] == "1":
            exato += 2 ** -(x+1)

    return exato

def formarErro(real,exato):
    numDECIMAL = real
    numEXATO = exato
    erro = float(str(((numDECIMAL - numEXATO) / numDECIMAL)*100).replace("-",""))

    return erro

##############################################################################################33
while True:

    real = float(input("\n\nDigite um valor entre 0 e 1: "))
    bits = 0

    if real > 0.0 and real < 1.0:
        binario = formarBinario(real)
        maior = ""
        newMENOR = ""

        for _ in range(0, len(binario)):
            maior += binario[_]
            newMENOR += binario[_]
            newMAIOR = aproxMaior(maior)

            bits += 1

            if bits >= 5:
                print(f"\nCom {_+1} bits")
                print(f"Aproximação a menor: {newMENOR} -> {formarExato(newMENOR)} "
                f"com erro = {formarErro(real,formarExato(newMENOR)):.2f}%")
                print(f"Aproximação a maior: {newMAIOR} -> {formarExato(newMAIOR)} "
                f"com erro = {formarErro(real,formarExato(newMAIOR)):.2f}%\n")
            if bits >= 12:
                break
    else:
        print("\nO número deve ser maior que 0 e menor que 1\n")

    repetir = input("Repetir? [S/N]: ").lower()
    if repetir[0] != "s":
        break


#Imagine you're writing the software for an inventory system for
#a store. Part of the software needs to check to see if inputted
#product codes are valid.
#
#A product code is valid if all of the following conditions are
#true:
#
# - The length of the product code is a multiple of 4. It could
#   be 4, 8, 12, 16, 20, etc. characters long.
# - Every character in the product code is either an uppercase
#   character or a numeral. No lowercase letters or punctuation
#   marks are permitted.
# - The character sequence "A1" appears somewhere in the
#   product code.
#
#Write a function called valid_product_code. valid_product_code
#should have one parameter, a string. It should return True if
#the string is a valid product code, and False if it is not.

#Add your code here!
def valid_product_code(a):
    for i in a:
        if (ord(str(i)) >= 65 and ord(str(i))<=90) or (ord(str(i)) >=48 and ord(str(i))<=57):
            K =1
        else:
            return False

    if len(a)%4 == 0 and "A1"in a:
        #print(len(a)%4)
        return True
    else:
        return False
    return True

#Below are some lines of code that will test your function.
#You can change the value of the variable(s) to test your
#function with different inputs.
#
#If your function works correctly, this will originally
#print: True, True, False, False, False
print(valid_product_code("A12B44BP"))
print(valid_product_code("BFDSAUSA98932RWEFOEWA9FEAA1DSFSF"))
print(valid_product_code("A1BBD5"))
print(valid_product_code("BDD5664S"))
print(valid_product_code("66aBSaA1fdsv"))

5.2  Control Structures/Exam/9 Valid_product_code.py


import itertools

N, M, D = list(map(int,input().split()))
arr = [[] for i in range(N)]
for i in range(N):
    arr[i] = list(map(int,input().split()))
max_cnt = 0

for archers in itertools.combinations(range(M), 3):
    #print(archers)
    cnt = 0
    enemy = [[] for i in range(N)]
    for i in range(N):
        enemy[i] = arr[i][:]
    while(1):
        targets = []
        B = len(enemy)
        for archer in archers:
            target=[]
            for j in range(B):
                for k in range(M):
                    dist = abs(B-j) + abs(k-archer)
                    if enemy[j][k] == 1 and dist <= D:
                        target.append([dist, k, j])
            target.sort()
            if target != []:
                targets.append(target[0])
        for attack_target in targets:
            if enemy[attack_target[2]][attack_target[1]] == 1:
                cnt += 1
                enemy[attack_target[2]][attack_target[1]] = 0
        enemy.pop()
        if enemy ==[]:
            break
    if cnt > max_cnt:
        max_cnt = cnt
print(max_cnt)


from __future__ import division
from math import sqrt
import random
""" Functions for bananas that don't need PandaEPL, so can actually be tested reasonably!
Includes functions for testing distance, figuring out banana placement, and determining
reward level dependent on banana positions
"""

def get_distance(p0, p1):
    """
    (tuple, tuple) -> float
    Returns the distance between 2 points. p0 is a tuple with (x, y)
    and p1 is a tuple with (x1, y1), works with negative points
    """
    dist = sqrt((float(p0[0]) - float(p1[0]))**2 + (float(p0[1]) - float(p1[1]))**2)
    return dist

def get_random_xy(pos_list, avatar=(0, 0), config=None, area=None):
    # pos_list is all of the current fruit positions
    # avatar is the current avatar position
    # config is dict with minimum entries:
    # 'tooClose' how close fruit can be to other fruit or avatar
    # 'avatarRadius' how big the avatar is (additional distance to tooClose for avatar)
    # 'environ' tells us shape of environment
    # if environ is rectangle, need min_x, min_y, max_x, max_y for x and y of corners
    # if environ is circle, need radius (assumes center at 0,0)
    # area is a list of numbers signifying what subset of area requesting. so far only
    # true for rectangle. 9 sections, so can be up to nine numbers (full area or just send
    # None for whole area)
    if config is None:
        config = {}
        execfile('config.py', config)
    whole_area = False
    if area is None or area == [10]:
        whole_area = True
    # print('pos list', pos_list)
    # print('avatar', avatar)
    # print('config', config)
    # print('area', area)
    # first check stuff that can return right away, circle has no sub-areas
    if 'circle' in config.get('environ', ''):
        # print 'circle'
        x, y = get_circle_point(pos_list, avatar, config)
        # print 'after point'
        return x, y
    # using whole area
    if whole_area or len(area) == 9:
        # print 'user whole area'
        # use entire area
        while True:
            x = random.uniform(config['min_x'], config['max_x'])
            y = random.uniform(config['min_y'], config['max_y'])
            # print x, y, pos_list, avatar
            if check_distances_good(x, y, pos_list, avatar, config):
                return x, y
    # need to figure out geometry. may be easier to exclude areas if using
    # most of field
    x_y_limits = []
    total_set = range(1, 10)
    non_area = [num for num in total_set if num not in area]
    # get lists of min, max for x, y.
    # if area is large, we will check if not in sub-area instead
    test_areas = area
    exclude = False
    if len(area) > 4:
        test_areas = non_area
        # print 'non-area', test_areas
        exclude = True

    for sub_area in test_areas:
        x_y_limits.append(get_x_y_sub_area(config, sub_area))

    # if area (not test_area) just one section, return random number from that section
    if len(area) == 1:
        # print 'use one section'
        while True:
            x = random.uniform(x_y_limits[0][0], x_y_limits[0][1])
            y = random.uniform(x_y_limits[0][2], x_y_limits[0][3])
            if check_distances_good(x, y, pos_list, avatar, config):
                return x, y

    # If more than one section, get random number
    # from large area and then check to see if in correct
    # sub_area (or not in non_areas)
    if exclude:
        x, y = get_random_xy_not_subarea(pos_list, avatar, config, x_y_limits, test_areas)
    else:
        x, y = get_random_xy_subarea(pos_list, avatar, config, x_y_limits, test_areas)
    # print 'random_xy returning', x, y
    return x, y

def get_random_xy_subarea(pos_list, avatar, config, x_y_limits, area):
    # print 'get random xy in subarea'
    # print x_y_limits
    while True:
        x = random.uniform(config['min_x'], config['max_x'])
        y = random.uniform(config['min_y'], config['max_y'])
        # make sure in correct sub-area, check each area it can be in,
        # go until match
        # print x_y_limits
        for x_y in x_y_limits:
            if check_distances_good(x, y, pos_list, avatar, config) and point_inside_square(x, y, x_y):
                return x, y

def get_random_xy_not_subarea(pos_list, avatar, config, x_y_limits, area):
    # print 'get random xy not in subarea'
    # print x_y_limits
    while True:
        x = random.uniform(config['min_x'], config['max_x'])
        y = random.uniform(config['min_y'], config['max_y'])

        # make sure in correct sub-area, check each area
        # to make sure not in any excluded areas, makes it through all tests,
        # return
        for x_y in x_y_limits:
            # using non_areas, so need to go through all subareas,
            # and make sure x, y not in any of them. If inside an
            # area, try again. Or if too close to anything else
            if point_inside_square(x, y, x_y) or not check_distances_good(x, y, pos_list, avatar, config):
                break
        else:
            # print 'returning', x, y
            return x, y

def point_inside_square(x, y, limits):
    """ determine if a point is inside a given square or not
    limits is a tuple, (x_min, x_max, y_min, y_max)"""
    inside_x = False
    inside_y = False
    # print x, y
    # print limits
    if limits[0] < x < limits[1]:
        # print 'x in square'
        inside_x = True
    if limits[2] < y < limits[3]:
        # print 'y in square'
        inside_y = True
    # print inside_x and inside_y
    return inside_x and inside_y

def check_distances_good(x, y, pos_list, avatar=(0, 0), config=None):
    """

    Verifies a point (x,y) is more than the minimum distance set by tooClose
    in the config.py file from existing points in pos_list. Also cannot be too
    close to the avatar, which has additional radius
    Returns True or False,
    """

    # print('check distances', config)
    too_close = config['tooClose']
    dist_avatar = config['avatarRadius'] + too_close
    if config.get('fruit_to_remember'):
        too_close = max(config['distance_goal']) + 0.5
    # print('distance away from other fruit', too_close)
    # print('x, y', x, y)

    # check the distance to points already on the list and to the avatar
    if pos_list:
        # print 'pos_list', pos_list
        for x1, y1 in pos_list:
            # if either too close to other bananas or avatar, get new points.
            if get_distance((x, y), (x1, y1)) < too_close or get_distance((x, y), avatar) < dist_avatar:
                # print 'set xy too close'
                # print 'bad distance is ', get_distance((x, y), (x1, y1))
                # print 'or', get_distance((x, y), avatar)
                # print x,y
                return False
        else:
            # print 'distance is ', get_distance((x, y), (x1, y1))
            return True
    else:
        # check the distance to the avatar if there is no list yet
        if get_distance((x, y), avatar) < dist_avatar:
            # print 'try again set_xy, no list', pos_list, avatar, config
            return False
        return True

def get_circle_point(pos_list, avatar, config):
    # print 'in circle'
    radius = config['radius']
    while True:
        x, y = random.uniform(-radius, radius), random.uniform(-radius, radius)
        if check_distances_good(x, y, pos_list, avatar, config) and get_distance((x, y), (0, 0)) < radius:
            return x, y

def get_x_y_sub_area(config, area_key):
    # divides space into 9 sections, corresponding to number key pad.
    # get total area, gets outer boundary from config file, returns sub-area
    # that corresponds to area_key, which is a single number.
    min_x = config['min_x']
    max_x = config['max_x']
    min_y = config['min_y']
    max_y = config['max_y']
    # distances for x and y in new sections
    x_dist = get_distance((min_x, min_y), (max_x, min_y)) / 3
    y_dist = get_distance((min_x, min_y), (min_x, max_y)) / 3
    if area_key == 1:
        return min_x, min_x + x_dist, min_y, min_y + y_dist
    elif area_key == 2:
        return min_x + x_dist, min_x + 2 * x_dist, min_y, min_y + y_dist
    elif area_key == 3:
        return min_x + 2 * x_dist, min_x + 3 * x_dist, min_y, min_y + y_dist
    elif area_key == 4:
        return min_x, min_x + x_dist, min_y + y_dist, min_y + 2 * y_dist
    elif area_key == 5:
        return min_x + x_dist, min_x + 2 * x_dist, min_y + y_dist, min_y + 2 * y_dist
    elif area_key == 6:
        return min_x + 2 * x_dist, min_x + 3 * x_dist, min_y + y_dist, min_y + 2 * y_dist
    elif area_key == 7:
        return min_x, min_x + x_dist, min_y + 2 * y_dist, min_y + 3 * y_dist
    elif area_key == 8:
        return min_x + x_dist, min_x + 2 * x_dist, min_y + 2 * y_dist, min_y + 3 * y_dist
    elif area_key == 9:
        return min_x + 2 * x_dist, min_x + 3 * x_dist, min_y + 2 * y_dist, min_y + 3 * y_dist


#!/usr/bin/env python3

import re
from itertools import chain

def load_file(filename):
    with open(filename, 'r') as f:
        lines = f.readlines()

    lines = [ _.strip() for _ in lines ]
    lines = filter(lambda _: _ != '' and _[0] != '#', lines)
    cmds = chain.from_iterable( _.split(',') for _ in lines )
    return expand_cmds(cmds)

def expand_cmds(cmds):
    for cmd in cmds:
        m = re.fullmatch(r'^((?P<repeat>[0-9]+)-)?(?P<cmd>.*)$', cmd)

        if m is None:
            m = { 'repeat': 1, 'cmd': '' }
        else:
            m = m.groupdict()

        if m['repeat'] is None:
            m['repeat'] = 1

        for i in range(int(m['repeat'])):
            yield m['cmd']

def gen_cmds(cmds):
    last_cmd = next(cmds)
    last_count = 1

    for cmd in cmds:
        if cmd == last_cmd:
            last_count += 1
            continue

        yield last_count, last_cmd

        last_cmd = cmd
        last_count = 1

    yield last_count, last_cmd

def gen_tweets(cmds, max_cmds=350):
    tweet_cmds = []
    tweet_count = 0

    for count, cmd in gen_cmds(cmds):
        tweet_count += count
        tweet_over = 0 if tweet_count < max_cmds else tweet_count - max_cmds

        if tweet_over > 0:
            tweet_cmds.append((count-tweet_over, cmd))
            yield tweet_cmds

            tweet_cmds = []
            tweet_count = tweet_over
            count = tweet_over

        tweet_cmds.append((count, cmd))

    if len(tweet_cmds) > 0:
        yield tweet_cmds

def format_cmd(count, cmd):
    if count > 1:
        return f'{count}-{cmd}'
    return cmd

cmds = load_file('./play.txt')
for i, tweet in enumerate(gen_tweets(cmds), start=1):
    with open(f'./tweet-{i:03d}.txt', 'w') as f:
        f.write(','.join( format_cmd(*_) for _ in tweet ))
        f.write('\n')

cmds = load_file('./play.txt')
with open(f'./input.txt', 'w') as f:
    for cmd in expand_cmds(cmds):
        # leading comma is jntentional!...
        # otherwise we loose the first frame
        f.write(f',{cmd}')
    f.write('#doomreplay-docker#')