#!/usr/bin/env python
# Muyuan Chen 2022-08
from EMAN2 import *
import numpy as np
import scipy.spatial.distance as scipydist
from scipy.optimize import minimize

def gather_metadata(options):
	info3d=[]
	info2d=[]
	data=load_lst_params(options.ptcls)

	if options.exclude:
		data2=[]
		print("exclude particles around {}".format(options.exclude))
		exl=load_lst_params(options.exclude)
		e1=EMData(options.ptcls,0, True)
		e2=EMData(options.exclude,0, True)
		scale2=e2["apix_x"]/e1["apix_x"]
		print(f"{len(exl)} particles, scale by {scale2:.2f}")

		fnames=np.unique([i["src"] for i in data])
		fnames=[base_name(f) for f in fnames]

		for fname in fnames:
			i3d1=[i for i in data if base_name(i["src"])==fname]
			n0=len(i3d1)
			pos1=[EMData(i["src"], i["idx"], True) for i in i3d1]
			pos1=np.array([p["ptcl_source_coord"] for p in pos1])

			i3d2=[i for i in exl if base_name(i["src"])==fname]
			pos2=[EMData(i["src"], i["idx"], True) for i in i3d2]
			pos2=np.array([p["ptcl_source_coord"] for p in pos2])*scale2
			dst=scipydist.cdist(pos1,pos2)
			torm=np.argmin(dst, axis=0)
			i3d1=[i3 for i,i3 in enumerate(i3d1) if i not in torm]
			print("  excluding {} out of {} 3d particles. Average distnace {:.1f} px".format(n0-len(i3d1), n0, np.mean(np.min(dst, axis=0))))
			data2.extend(i3d1)

		print("total {} out of {} particles excluded".format(len(data)-len(data2), len(data)))
		data=data2

	if "xform.align3d" in data[0]:
		print("Using 3d alignment from the input lst instead of image header.")
		xflst=True
	else:
		xflst=False

	for ii,dt in enumerate(data):
		img=EMData(dt["src"], dt["idx"], True)
		imgsrc=img["class_ptcl_src"]
		imgidx=img["class_ptcl_idxs"]

		try: rhdrs=EMData.read_images(imgsrc,imgidx,IMAGE_UNKNOWN,True)
		except:
			print(f"couldn't read {imgidx} from {imgsrc}")
			return

		idx2d=[]
		for k,i in enumerate(imgidx):
			e=rhdrs[k]
			dc={"src":imgsrc,"idx":i,
				"idx3d":ii, "xform.projection":e["xform.projection"], "tilt_id":e["tilt_id"]}
			idx2d.append(len(info2d))
			info2d.append(dc)

		if xflst:
			xfali=dt["xform.align3d"]
		else:
			xfali=img["xform.align3d"]

		if img.has_attr("orig_class"):
			cls=img["orig_class"]
		else:
			cls=ii%2
		dc={"src":dt["src"], "idx":dt["idx"],
			"coord":img["ptcl_source_coord"], "idx2d":idx2d,
			"class":cls, "xform.align3d":xfali
		}

		info3d.append(dc)

		sys.stdout.write("\r {}/{}".format(ii+1, len(data)))
		sys.stdout.flush()
	print()
	return info2d, info3d

def main():

	usage="""
	Gather metadata for spt refinement. Take into account the pre-determined particle orientation in particle header (generated using e2spt_extract.py with the --jsonali option), and interpolate the 2D subtilt movement from the existing subtilt alignment of any particles from the same tomograms. For example,

	e2spt_gathermeta.py --ptcls sets/ptcls.lst --ali2d spt_00/aliptcls2d_07.lst

	will compile metadata in a new spt_xx directory. To do spt refinement from it, run

	e2spt_refine_new.py --path spt_xx --continuefrom 0.5 --localrefine

	with all other desired options for e2spt_refine_new.py
	"""
	parser = EMArgumentParser(usage=usage,version=EMANVERSION)
	parser.add_argument("--ptcls", type=str,help="input 3d particles from sets/", default=None)
	parser.add_argument("--ali2d", type=str,help="existing aligned 2d particles from spt_xx, used to interpolate local subtilt translation", default=None)
	parser.add_argument("--ali3d", action="store_true", default=False, help="use align3d from the list in place of the info from --ptcls header.")
	parser.add_argument("--exclude", type=str,help="exclude particle around a given set of existing particles", default=None)
	parser.add_argument("--path", type=str,help="new refinement path", default=None)
	parser.add_argument("--smooth", type=float,help="factor to smooth the movement field from the --ali2d refinement. Bigger is smoother, default is 10", default=10)
	parser.add_argument("--userot", action="store_true", default=False, help="use rotational subtilt alignment as well. very slow and may not be as useful..")
	parser.add_argument("--skipcheck", action="store_true", default=False, help="skip the sanity check...")

	(options, args) = parser.parse_args()

	logid=E2init(sys.argv)

	if options.path==None: options.path=num_path_new("spt_")
	print("Writing in {}".format(options.path))

	print("Gather metadata from {}".format(options.ptcls))
	info2d1, info3d1 = gather_metadata(options)
	print("Total {} 3d particles and {} 2d particles".format(len(info3d1), len(info2d1)))

	fali2d=options.ali2d
	path0=os.path.dirname(fali2d)
	p=fali2d.rfind('.')
	itr=int(fali2d[p-2:p])
	fali3d=[f"{path0}/aliptcls3d_{i:02d}.lst" for i in range(itr)]
	fali3d=[f for f in fali3d if os.path.isfile(f)]
	fali3d=fali3d[-1]
	finfo3=f"{path0}/particle_info_3d.lst"
	print("Reading previous alignment")
	print(f"Loading particle info from {finfo3}")
	print(f"        3d alignment from {fali3d}")
	print(f"        2d alignment from {fali2d}")
	info3d0=load_lst_params(finfo3)
	ali2d0=load_lst_params(fali2d)
	ali3d0=load_lst_params(fali3d)
	missing=False
	for a in ali2d0:
		if "dxf" not in a:
			a["dxf"]=Transform()
			missing=True
	if missing: print(f"Some particles from {fali2d} do not contain subtilt alignment info...")

	options.cmd=' '.join(sys.argv)
	fm=f"{options.path}/0_spt_gathermeta_params.json"
	js=js_open_dict(fm)
	js.update(vars(options))
	js.close()

	e0=EMData(info3d0[0]["src"], info3d0[0]["idx"], True)
	e1=EMData(info3d1[0]["src"], info3d1[0]["idx"], True)
	scale=e1["apix_x"]/e0["apix_x"]
	print(f"Scale from old to new alignment {scale:.3f}")

	if not options.skipcheck:
		print("Sanity check on one tomogram")
		fname=base_name(info3d0[0]["src"])
		i3d0=[i for i in info3d0 if base_name(i["src"])==fname]
		i3d1=[i for i in info3d1 if base_name(i["src"])==fname]
		pos0=np.array([i["coord"] for i in i3d0])
		pos1=np.array([i["coord"] for i in i3d1])
		pos1*=scale
		tid=10
		print(f"tomogram {fname}, tilt id {tid}")
		a2d0=[i for i in ali2d0 if base_name(i["src"])==fname]
		v0=np.array([a["dxf"].get_trans() for a in a2d0 if a["tilt_id"]==tid])
		dst=scipydist.cdist(pos0,pos1)
		print(f"{len(pos0)} particles from old refinement, {len(v0)} movement trajectories, {len(pos1)} particles from new refinement")
		print("mean neighbor distance between particles from two refinement: {:.4f}".format(np.mean(np.min(dst, axis=0))))
		dst=np.exp(-dst/options.smooth)
		dst=dst/np.sum(dst,axis=0)
		v1=np.matmul(v0.T,dst).T
		print("mean subtilt translation {:.4f} from old refinement".format(np.mean(np.linalg.norm(v0, axis=1))))
		print("mean subtilt translation {:.4f} from new refinement".format(np.mean(np.linalg.norm(v1, axis=1))))

	ali3d1=[]
	for a in info3d1:
		dc={"src":a["src"],"idx":a["idx"],"xform.align3d":a["xform.align3d"]}
		if "class" in a:
			dc["class"]=a["class"]

		ali3d1.append(dc)

	ali2d1=[]
	for a in info2d1:

		dc2={"src":a["src"],"idx":a["idx"],
			"ptcl3d_id":a["idx3d"],
			"tilt_id":a["tilt_id"],
			"score":0,
			"dxf":Transform()}

		i3=info3d1[a["idx3d"]]
		if "class" in i3:
			dc2["class"]=i3["class"]
		else:
			dc2["class"]=a["idx3d"]%2

		ali2d1.append(dc2)

	nnb=15
	def test_rot(x):
		xfr=Transform({"type":"xyz","xtilt":x[0],"ytilt":x[1],"ztilt":x[2]}).inverse()
		drspin=[(a*xfr).get_params("spin")["omega"] for a in dr]
		scr=np.dot(drspin, ds)
		return scr

	print("Compute subtilt translation for new refinement")
	fnames=np.unique([i["src"] for i in info3d1])
	fnames=[base_name(f) for f in fnames]

	for fname in fnames:
		# i2d1=[i for i in info2d1 if base_name(i["src"])==fname]
		i3d1=[i for i in info3d1 if base_name(i["src"])==fname]
		i3d0=[i for i in info3d0 if base_name(i["src"])==fname]
		print(fname, len(i3d0), len(i3d1))
		if len(i3d0)==0 or len(i3d1)==0:
			print("no particles in this tomogram. skip...")
			continue

		a2d0=[[ali2d0[i] for i in i3["idx2d"]] for i3 in i3d0]
		i2d1=[[info2d1[i] for i in i3["idx2d"]] for i3 in i3d1]
		a2d1=[[ali2d1[i] for i in i3["idx2d"]] for i3 in i3d1]

		txfs=[d["xform.align3d"].inverse() for d in i3d1]

		pos0=np.array([i["coord"] for i in i3d0])
		pos1=np.array([i["coord"] for i in i3d1])*scale

		tids=[a["tilt_id"] for a1 in i2d1 for a in a1]
		for tid in sorted(np.unique(tids)):
			ad0=[a for a2 in a2d0 for a in a2 if a["tilt_id"]==tid]
			if1=[a for a1 in i2d1 for a in a1 if a["tilt_id"]==tid]
			ad1=[a for a1 in a2d1 for a in a1 if a["tilt_id"]==tid]
			v0=np.array([a["dxf"].get_trans() for a in ad0])
			i0=[tid in [a["tilt_id"] for a in a2] for a2 in a2d0 ]
			p0=pos0[i0]
			i1=[tid in [a["tilt_id"] for a in a1] for a1 in a2d1 ]
			p1=pos1[i1]
			if len(v0)!=len(p0):
				print(f"skip tilt {tid} from tomogram {fname}")
				continue

			dst=scipydist.cdist(p0,p1)
			dst=np.exp(-dst/options.smooth)
			dst=dst/np.sum(dst,axis=0)
			v1=np.matmul(v0.T,dst).T
			v1/=scale

			scr=np.array([a["score"] for a in ad0])
			scr=np.dot(scr, dst)

			if options.userot:
				rts=[]
				for ip in range(len(ad1)):
					nid=np.argsort(-dst[:,ip])[:nnb]
					ds=dst[nid, ip].copy()
					ds/=np.sum(ds)
					dr=[Transform(ad0[i]["dxf"].get_rotation()) for i in nid]
					x0=[0,0,0]
					res=minimize(test_rot, x0,
							method='Powell',options={'ftol': 1e-3, 'disp': False, "maxiter":5})
					rts.append(res.x)
				rts=np.array(rts)
			else:
				rts=np.zeros((len(ad1),  3))

			xfpj=[a["xform.projection"] for a in if1]
			xfraw=[a*b for a,b in zip(xfpj, txfs)]

			dxf=[Transform({"type":"xyz","xtilt":x[0],"ytilt":x[1],"ztilt":x[2],"tx":v[0], "ty":v[1]}) for x,v in zip(rts,v1)]
			xfali=[d*x for x, d in zip(xfraw, dxf)]

			for i,a in enumerate(ad1):
				a["dxf"]=dxf[i]
				a["xform.projection"]=xfali[i]
				a["score"]=float(scr[i])

	save_lst_params(ali3d1, "{}/aliptcls3d_01.lst".format(options.path))
	save_lst_params(ali2d1, "{}/aliptcls2d_01.lst".format(options.path))
	save_lst_params(info2d1, "{}/particle_info_2d.lst".format(options.path))
	save_lst_params(info3d1, "{}/particle_info_3d.lst".format(options.path))

	#if options.lstin:
		#lst0=load_lst_params(options.lstin)
		#key0=["{}_{:04d}".format(l["src"], l["idx"]) for l in lst0]
		#dic0={k:i for i,k in enumerate(key0)}
	#lst1=load_lst_params(options.ptcls)

	#lout3d=[]
	#lout2d=[]
	#info3d=[]
	#info2d=[]
	"""
	ndxf=0
	for li,l in enumerate(lst1):
		e=EMData(l["src"], l["idx"], True)
		ky="{}_{:04d}".format(e["orig_ptcl"], e["orig_idx"])

		if options.lstin:
			ii=dic0[ky]
			l0=lst0[ii]
			scr=l0["score"]
			if "orig_idx" in l0:
				ii=l0["orig_idx"]
		else:
			scr=1
			ii=li

		if "xform.align3d" in l:
			xf3d=l["xform.align3d"]
		else:
			xf3d=e["xform.align3d"]

		dc3={"src":l["src"], "idx":l["idx"],
			"score":scr, "xform.align3d":xf3d,
			"orig_idx":ii}
		lout3d.append(dc3)

		imgsrc=e["class_ptcl_src"]
		imgidx=e["class_ptcl_idxs"]
		coord=e["ptcl_source_coord"]
		boxsz=e["nx"]

		rhdrs=EMData.read_images(imgsrc,imgidx,IMAGE_UNKNOWN,True)
		idx2d=[]
		for k,i in enumerate(imgidx):
			h=rhdrs[k]
			xf=Transform(h["xform.projection"])
			xf=xf*(xf3d.inverse())
			dc2={"src":imgsrc,"idx":i, "class":ii%2,
				"ptcl3d_id":li, "xform.projection":xf,
				"tilt_id":h["tilt_id"]}
			if h.has_attr("orig_dxf"):
				dc2["dxf"]=h["orig_dxf"]
				ndxf+=1
			else:
				dc2["dxf"]=Transform()

			dc={"src":imgsrc,"idx":i,
				"idx3d":li,
				"xform.projection":Transform(h["xform.projection"]), "tilt_id":h["tilt_id"]}

			idx2d.append(len(lout2d))
			lout2d.append(dc2)
			info2d.append(dc)

		dc={"src":l["src"], "idx":l["idx"],
			"coord":coord, "idx2d":idx2d, "xform.align3d":xf3d}
		info3d.append(dc)

		sys.stdout.write("\r {}/{}".format(li+1, len(lst1)))
		sys.stdout.flush()

	if options.make3d:
		for eo in ["even", "odd"]:
			run(f"e2spa_make3d.py --input {options.path}/aliptcls2d_01.lst --output {options.path}/threed_00_{eo}.hdf --clsid {eo} --parallel thread:32")

	"""

	E2end(logid)

if __name__ == '__main__':
	main()


from django.db import models
from django.contrib.postgres.fields import ArrayField
# Create your models here.

class List(models.Model):
        list_owner = models.CharField(max_length=30)
        list_items = ArrayField(
            ArrayField(
                models.CharField(max_length=20, blank=True),
                size=20,
            ),
            size=20
        )

lists = [
    List("Ben Baker",['apple','orange','chicken thighs','yogurt']),
    List("Brenna Langille", ['pickles','green cola','sausages','peppers'],
    List("Devin Larsen",['tempeh','grains','ointment','toothpaste']))
]


from django.db import models

from backend.constants.field_restrictions import NAME_MAX_LENGTH

class User(models.Model):
    name = models.CharField(
        help_text="Name of the user.",
        max_length=NAME_MAX_LENGTH,
        unique=True
    )
    dota_id = models.IntegerField(
        help_text="ID of the user in DOTA 2.",
        unique=True
    )

    #  Relationships.
    games = models.ManyToManyField(
        "Game",
        through="PlayerStats"
    )

    def __repr__(self):
        return f"<User(" \
               f"pk={self.pk}, " \
               f"dota_id={self.dota_id}, " \
               f"name={self.name} " \
               f")>"

    def __str__(self):
        return self.__repr__()


from collections import defaultdict
import sys

sys.setrecursionlimit(10**6)

N, X, Y = (int(x) for x in input().split())
g = defaultdict(list)
for _ in range(N-1):
  u, v = (int(x)-1 for x in input().split())
  g[u].append(v)
  g[v].append(u)

prev = [-1] * N
def dfs(node, dest, path=[], parent=-1):
  prev[node] = parent
  if node == dest:
    return

  for nb in g[node]:
    if nb == parent:
      continue

    dfs(nb, dest, path, node)

dfs(X-1, Y-1, [])
ans = [Y]
cur = Y-1
while cur != X-1:
  cur = prev[cur]
  ans.append(cur+1)

print(*ans[::-1])


import pytest
import pprint
import requests
from .utils.pdf import snapshot_pdf

LATEX_HELLO_WORLD = (
    "\\documentclass{article}\n\\begin{document}\nHello World\n\\end{document}"
)
SAMPLE_HELLO_WORLD = "hello_world"

COMPIL_UPLATEX_JAPANESE = "% !TEX uplatex\n\\documentclass[uplatex]{jsarticle}\n\n\\title{up\\LaTeX\\ 実験}\n\\author{林蓮枝}\n\n\\begin{document}\n\n\\maketitle\n\n\\begin{abstract}\n本稿では、文書組版システムup\\LaTeX{}の使い方を解説します。\nup\\LaTeX{}を利用するときには、あらかじめ文章中に\\TeX{}コマンドと呼ばれる組版用の指示を混在させ\\ldots\n\\end{abstract}\n\n\\section{導入}\nこんにちは世界\n\n\\end{document}"
SAMPLE_HELLO_JAPANESE = "hello_japanese"

LATEX_HELLO_WORLD_WITH_IMAGE = "\\documentclass{article}\n \\usepackage{graphicx}\n \\begin{document}\n Hello World\n \\includegraphics[height=2cm,width=7cm,keepaspectratio=true]{logo.png}\n \\end{document}"
SAMPLE_IMAGE_CONTENT = requests.get(
    "https://www.ytotech.com/images/ytotech_logo.png"
).content

LATEX_MULTI_RESOURCES = "\\documentclass{article}\n \\usepackage{graphicx}\n  \\begin{document}\n Hello World\\\\\n \\includegraphics[height=2cm,width=7cm,keepaspectratio=true]{logo.png}\n \\include{page2}\n \\end{document}"
LATEX_MULTI_RESOURCES_PAGE2 = "VGhpcyBpcyB0aGUgc2Vjb25kIHBhZ2UsIHdoaWNoIHdhcyBwYXNzZWQgYXMgYSBiYXNlNjQgZW5jb2RlZCBmaWxl"

def test_querystring_hello_world(latex_on_http_api_url):
    """
    Compile a simple Latex document with querystring API by an encoded Latex document content.
    """
    # Create a query string request.
    r = requests.get(
        latex_on_http_api_url + "/builds/sync",
        params={"content": LATEX_HELLO_WORLD},
    )
    assert r.status_code == 201

def test_querystring_hello_world_compiler(latex_on_http_api_url):
    """
    Compile a simple Latex document with querystring API by an encoded Latex document content,
    and specifying the compiler.
    """
    # Create a query string request.
    r = requests.get(
        latex_on_http_api_url + "/builds/sync",
        params={"content": LATEX_HELLO_WORLD, "compiler": "lualatex"},
    )
    assert r.status_code == 201
    snapshot_pdf(r.content, SAMPLE_HELLO_WORLD)

def test_querystring_hello_japanese(latex_on_http_api_url):
    """
    Compile a japanese Latex document with querystring API by an encoded Latex document content,
    and specifying the compiler.
    """
    # Create a query string request.
    r = requests.get(
        latex_on_http_api_url + "/builds/sync",
        params={"content": COMPIL_UPLATEX_JAPANESE, "compiler": "uplatex"},
    )
    assert r.status_code == 201

# Add resources
# &resource-path[]=logo.png&resource-value[]=https://www.ytotech.com/images/ytotech_logo.png

def test_querystring_full_spec_image(latex_on_http_api_url):
    """
    Compile a Latex document containing another image resource with querystring API
    by passing a complete resources specification and specifying the compiler.
    """
    # Create a query string request.
    r = requests.get(
        latex_on_http_api_url + "/builds/sync",
        params={
            "content": LATEX_HELLO_WORLD_WITH_IMAGE,
            "compiler": "pdflatex",
            "resource-path[]": "logo.png",
            "resource-type[]": "url",
            "resource-value[]": "https://www.ytotech.com/images/ytotech_logo.png",
        },
    )
    # import pprint

    # pprint.pprint(r.json())
    assert r.status_code == 201

def test_querystring_multi_resources(latex_on_http_api_url):
    """
    Compile a Latex document containing multiple annex resources with querystring API,
    by passing a complete resources specification and specifying the compiler.
    """
    # Create a query string request.
    r = requests.get(
        latex_on_http_api_url + "/builds/sync",
        params={
            "content": LATEX_MULTI_RESOURCES,
            "compiler": "pdflatex",
            "resource-path[]": ["logo.png", "page2.tex"],
            "resource-type[]": ["url", "base64"],
            "resource-value[]": [
                "https://www.ytotech.com/images/ytotech_logo.png",
                LATEX_MULTI_RESOURCES_PAGE2,
            ],
        },
    )
    if r.status_code != 201:
        pprint.pprint(r.text)
        # pprint.pprint(r.json())
    assert r.status_code == 201

# TODO Specify output file name?


import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
from ipywidgets import interact
from sklearn.preprocessing import scale
from Helper_Functions.OrthoViewer import OrthoAxes
import itertools
from scipy.stats import percentileofscore as inv_quantile
import ipywidgets as widgets

def plot_dff_traces(signal,times,indices,dff):
    """Plot signal and a dff trace selected with a slider from a list of possible indices.

    Parameters :
    ------------
    signal : 1d array
        external signal, shape (n_timepoints)

    times : 1d array
        timepoints of signal and dff, shape (n_timepoints)

    indices : 1d array
        indices of the neurons that can be selected with the slider

    dff : 2d array
        rescaled fluorescence traces for all neurons, shape (n_neurons,n_timepoints)
    """
    @interact(neuron=(0,len(indices)-1,1))
    def _plot_dff_traces(neuron=0):
        plt.close()
        fig,ax=plt.subplots()
        ax.plot(times,scale(signal),label='external signal')
        ax.plot(times,scale(dff[indices[neuron]]),'k',label='neuron $\Delta F/F$')
        ax.set_xlim(times[0],times[-1])
        ax.set_xlabel('time (s)')
        ax.legend()
        plt.show()

def plot_dff_raster(signal,times,indices,dff):
    """Plot dff of neurons with certain indices in a raster plot, also plot signal for comparison.

    Parameters :
    ------------
    signal : 1d array
        external signal, shape (n_timepoints)

    times : 1d array
        timepoints of signal and dff, shape (n_timepoints)

    dff : 2d array
        rescaled fluorescence traces for all neurons, shape (n_neurons,n_timepoints)

    indices : 1d array
        indices of the neurons that can be selected with the slider
    """
    fig,ax=plt.subplots()
    divider=make_axes_locatable(ax)
    tax=divider.append_axes('top',size='10%',pad=0.1,sharex=ax)
    cax=divider.append_axes('right',size='2%',pad=0.1)

    dt=np.mean(np.diff(times))
    extent=[times[0]-dt/2,times[-1]+dt/2,len(indices)-0.5,-0.5]
    cmap='inferno'

    tax.imshow(signal.reshape(1,-1),cmap=cmap,aspect='auto',interpolation='none',extent=extent)
    tax.tick_params(axis='both',which='both',bottom=False,left=False,labelbottom=False,labelleft=False)
    tax.set_title('signal')

    im=ax.imshow(dff[indices],cmap=cmap,interpolation='none',aspect='auto',extent=extent)
    cbar=plt.colorbar(im,cax=cax)
    cbar.set_label(r'$\Delta F/F$')
    ax.set_xlabel('time (s)')
    ax.set_ylabel('neurons')
    plt.show()

def plot_brain_layers(coords,opacity,mask=None,alpha_out=0.5,c='blue',s=4):
    """Plot neuron positions in a single layer that can be selected with a slider.
    Opacity values are given as inputs. They are cropped to positive valuesand rescaled to the range [0,1].
    Optionally a mask can be given so that neurons outside the mask are plotted in light grey.

    Parameters :
    ------------
    coords : 2d array
        neuron positions, shape (3,n_neurons)

    opacity : 1d array
        opacity values for each neuron

    mask : 1d array
        boolean array to select which neurons will be plotted in color
        default :  None

    alpha_out : float
        opacity of neurons outside the mask
        default : 0.5

    c : string
        color of the dots
        default : 'blue'

    s : float
        size of the dots
        default : 4
    """
    zs=np.unique(coords[2])
    zs=-np.sort(-zs)
    alpha=opacity/np.max(opacity)
    alpha[alpha<0]=0
    @interact(layer=(0,len(zs)-1,1))
    def _plot_brain_layer(layer=0):
        plt.close()
        fig,ax=plt.subplots()

        if mask is None:
            x_layer=coords[0,coords[2]==zs[layer]]
            y_layer=coords[1,coords[2]==zs[layer]]
            alpha_layer=alpha[coords[2]==zs[layer]]
            if len(x_layer)>0:
                ax.scatter(x_layer,y_layer,s=s,c=c,alpha=alpha_layer,edgecolors='none')

        else:
            x_layer=coords[0,(coords[2]==zs[layer])&(~mask)]
            y_layer=coords[1,(coords[2]==zs[layer])&(~mask)]
            if len(x_layer)>0:
                ax.scatter(x_layer,y_layer,s=s,c='lightgrey',alpha=alpha_out,edgecolors='none')

            x_layer=coords[0,(coords[2]==zs[layer])&(mask)]
            y_layer=coords[1,(coords[2]==zs[layer])&(mask)]
            alpha_layer=alpha[(coords[2]==zs[layer])&(mask)]
            if len(x_layer)>0:
                ax.scatter(x_layer,y_layer,s=s,c=c,alpha=alpha_layer,edgecolors='none')

        ax.set_aspect('equal')
        ax.set_xlim(np.min(coords[0]),np.max(coords[0]))
        ax.set_ylim(np.min(coords[1]),np.max(coords[1]))
        ax.set_title('$z = $'+str(round(zs[layer]))+' μm')
        ax.set_xlabel('$x$ (μm)')
        ax.set_ylabel('$y$ (μm)')
        plt.show()

def plot_brain_projections(coords,opacity,mask=None,alpha_out=0.1,c='blue',s=2,interactive=False):
    """Plot neuron positions projected in three orthogonal planes.
    Opacity values are given as inputs. They are cropped to positive values and rescaled to the range [0,1].
    Optionally a mask can be given so that neurons outside the mask are plotted in light grey.

    Parameters :
    ------------
    coords : 2d array
        neuron positions, shape (3,n_neurons)

    opacity : 1d array
        opacity values for each neuron

    mask : 1d array
        boolean array to select which neurons will be plotted in color
        default :  None

    alpha_out : float
        opacity of neurons outside the mask
        default : 0.1

    c : string
        color of the dots
        default : 'blue'

    s : float
        size of the dots
        default : 2

    interactive : boolean
        flag for interactive plotting
        default : False
    """
    alpha=opacity/np.max(opacity)
    alpha[alpha<0]=0
    fig=plt.figure()
    ortho=OrthoAxes(fig,coords,interactive=interactive)
    if mask is None:
        ortho.scatter(coords,c=c,alpha=alpha,s=s)
    else:
        alpha=alpha[mask]
        ortho.scatter(coords[:,~mask],c='lightgrey',alpha=alpha_out,s=s)
        ortho.scatter(coords[:,mask],c=c,alpha=alpha,s=s)
    plt.show()
    if interactive:
        return ortho

def plot_brain_projections_colorbar(coords,color,mask,cmap='Blues',alpha_in=0.3,alpha_out=0.1,s=3,vmin=0,vmax=10):
    """Plot neuron positions projected in three orthogonal planes, with colorbar.
    Color values are given as inputs.
    Neurons outside the mask are plotted in light grey.

    Parameters :
    ------------
    coords : 2d array
        neuron positions, shape (3,n_neurons)

    color : 1d array
        color values for each neuron

    mask : 1d array
        boolean array to select which neurons will be plotted in color
        default :  None

    cmap : string
        colormap
        default : 'Blues'

    alpha_in : float
        opacity of neurons inside the mask, of all neurons if no mask is given
        default : 0.3

    alpha_out : float
        opacity of neurons outside the mask
        default : 0.1

    s : float
        size of the dots
        default : 2

    interactive : boolean
        flag for interactive plotting
        default : False
    """
    fig,ax=plt.subplots()
    divider=make_axes_locatable(ax)
    ax2=divider.append_axes('right',size='40%',pad=0,sharey=ax)
    ax3=divider.append_axes('top',size='20%',pad=0,sharex=ax)
    cax=divider.append_axes('right',size='5%',pad=0)

    ax.scatter(coords[0,~mask],coords[1,~mask],s=s,c='lightgrey',alpha=alpha_out,edgecolors='none')
    im=ax.scatter(coords[0,mask],coords[1,mask],s=s,c=color[mask],vmin=vmin,vmax=vmax,cmap=cmap,alpha=alpha_in,edgecolors='none')

    ax.set_aspect('equal')
    ax.set_xlabel('$x$ (μm)')
    ax.set_ylabel('$y$ (μm)')

    ax2.scatter(coords[2,~mask],coords[1,~mask],s=s,c='lightgrey',alpha=alpha_out,edgecolors='none')
    ax2.scatter(coords[2,mask],coords[1,mask],s=s,c=color[mask],vmin=vmin,vmax=vmax,cmap=cmap,alpha=alpha_in,edgecolors='none')

    ax2.tick_params(left=False,labelleft=False)
    ax2.set_aspect('equal')
    ax2.set_xlabel('$z$ (μm)')

    ax3.scatter(coords[0,~mask],coords[2,~mask],s=s,c='lightgrey',alpha=alpha_out,edgecolors='none')
    ax3.scatter(coords[0,mask],coords[2,mask],s=s,c=color[mask],vmin=vmin,vmax=vmax,cmap=cmap,alpha=alpha_in,edgecolors='none')

    ax3.tick_params(bottom=False,labelbottom=False)
    ax3.set_aspect('equal')
    ax3.set_ylabel('$z$ (μm)')

    cbar=plt.colorbar(im,cax=cax)
    cbar.set_label('colorbar')
    plt.show()

def plot_brain_projections_color(coords,color,mask=None,cmap='coolwarm',alpha_in=0.5,alpha_out=0.1,s=2,interactive=False):
    """Plot neuron positions projected in three orthogonal planes.
    Color values are given as inputs.
    Optionally a mask can be given so that neurons outside the mask are plotted in light grey.

    Parameters :
    ------------
    coords : 2d array
        neuron positions, shape (3,n_neurons)

    color : 1d array
        color values for each neuron

    mask : 1d array
        boolean array to select which neurons will be plotted in color
        default :  None

    cmap : string
        colormap
        default : 'coolwarm'

    alpha_in : float
        opacity of neurons inside the mask, of all neurons if no mask is given
        default : 0.5

    alpha_out : float
        opacity of neurons outside the mask
        default : 0.1

    s : float
        size of the dots
        default : 2

    interactive : boolean
        flag for interactive plotting
        default : False
    """
    fig=plt.figure()
    ortho=OrthoAxes(fig,coords,interactive=interactive)
    if mask is None:
        ortho.scatter(coords,c=color,cmap=cmap,
                      vmin=-np.std(color),vmax=np.std(color),alpha=alpha_in,s=s)
    else:
        color=color[mask]
        ortho.scatter(coords[:,~mask],color='lightgrey',alpha=alpha_out,s=s)
        ortho.scatter(coords[:,mask],c=color,cmap=cmap,
                      vmin=-np.std(color),vmax=np.std(color),alpha=alpha_in,s=s)
    plt.show()
    if interactive:
        return ortho

def plot_coefficients(coords,coef,mask=None,interactive=False,**kwargs):
    """Plot neuron positions projected in three orthogonal planes.
    Different sets of color values, corresponding to different regressors can be given as inputs and selected with a slider.
    Optionally a mask can be given so that neurons outside the mask are plotted in light grey.

    Parameters :
    ------------
    coords : 2d array
        neuron positions, shape (3,n_neurons)

    coef : 1d or 2d array
        color values for each neuron, possibly multiple sets corresponding to different regressors, shape (n_neurons) or (n_neurons,n_regressors)

    mask : 1d array
        boolean array to select which neurons will be plotted in color
        default :  None

    interactive : boolean
        flag for interactive plotting
        default : False
    """
    if len(coef.shape)==1:
        ortho=plot_brain_projections_color(coords,coef,mask,interactive=interactive,**kwargs)
        if interactive:
            return ortho
    else:
        @interact(regressor=(0,coef.shape[1]-1))
        def _plot_coefficients(regressor=0):
            plt.close('all')
            ortho=plot_brain_projections_color(coords,coef[:,regressor],mask,interactive=interactive,**kwargs)
            if interactive:
                return ortho

def plot_neurons_per_label(neuron_labels,indices,opacity,coords,regressors,dff,times,interactive=False):
    """For a given regression label inputted as a string: plot position of neurons having that label and their average activity.

    Parameters :
    ------------
    neuron_labels : 2d array
        1 for positive coefficient, -1 for negative, 0 for not significant, shape (n_selected_neurons,n_regressors)

    indices : 1d
        indices of neurons for which labels are given, shape (n_selected_neurons)

    opacity : 1d array
        opacity values for all neuron, shape (n_neurons)

    coords : 2d array
        neuron positions for all neuron, shape (3,n_neurons)

    regressors : 2d array
        array of regressors, shape (n_timepoints,n_regressors)
        default :  None

    dff : 2d array
        rescaled fluorescence traces for all neurons, shape (n_neurons,n_timepoints)

    times : 1d array
        timepoints of regressors and dff, shape (n_timepoints)

    interactive : boolean
        flag for interactive plotting
        default : False
    """
    n_regressors=len(regressors)
    all_possible_labels=list(itertools.product([0,1,-1],repeat=n_regressors)) #get all possible combinations of 0, 1 and -1
    n_neurons_per_label=[]
    text_labels=[]
    for label in all_possible_labels:
        n_neurons_per_label.append(np.sum(np.all(neuron_labels==label,axis=1))) #number of neurons with a certain label
        text_labels.append(str(label)) #each label saved as a string
    n_neurons_per_label=np.array(n_neurons_per_label)
    text_labels=np.array(text_labels)

    @interact(label=text_labels[np.argsort(n_neurons_per_label)[-1]])
    def _plot_neurons_per_label(label):

        i=np.nonzero(text_labels==label)[0]
        if len(i)==0:
            print('invalid combination')
        else:
            i=int(i)
            label_i=all_possible_labels[i]
            mask_label=np.zeros(len(dff))
            mask_label[indices[np.all(neuron_labels==label_i,axis=1)]]=1
            mask_label=mask_label.astype(bool)
            print('number of neurons: '+str(n_neurons_per_label[i]))
            if n_neurons_per_label[i]>0:
                plt.close('all')
                ortho=plot_brain_projections(coords,opacity,mask_label,interactive=interactive)
                fig,ax=plt.subplots()
                for n,regressor in enumerate(regressors):
                    ax.plot(times,scale(regressor),label='regressor '+str(n))
                ax.plot(times,scale(dff[mask_label].mean(axis=0)),'k',label='average $\Delta F/F$ with '+label)
                ax.set_xlim(times[0],times[-1])
                ax.set_xlabel('time (s)')
                ax.legend()
                plt.show()
                if interactive:
                    return ortho

class ComplexRaster:
    def __init__(self, ax, X,
                 signal=None, times=None, order=None, weights=None,
                 X_params={"cmap":"plasma", "vmin":None, "vmax":None},
                 signal_params={"cmap":"plasma", "vmin":None, "vmax":None},
                 weights_params={"cmap":"plasma", "vmin":None, "vmax":None},
                ):
        self.ax = ax
        self.X = X
        self.signal = signal
        self.times = times
        self.order = order
        self.weights = weights

        self._X_params = X_params
        self._signal_params = signal_params
        self._weights_params = weights_params

        assert self.X.ndim==2
        self._n, self._t  = self.X.shape

        divider = make_axes_locatable(ax)
        if self.signal is not None:
            assert self.signal.ndim==1
            assert len(self.signal)==self._t
            self._ax_sig = divider.append_axes('top',size=0.2,pad=0.1,sharex=ax)
            self._ax_sig.tick_params(axis='both',which='both',bottom=False,left=False,labelbottom=False,labelleft=False)

        if self.weights is not None:
            assert self.weights.ndim==1
            assert len(self.weights)==self._n
            self._ax_wei = divider.append_axes('left',size=0.2,pad=0.1,sharey=ax)
            self._ax_wei.tick_params(axis='both',which='both',bottom=False,left=True,labelbottom=False,labelleft=True)
            ax.tick_params(axis='both',which='both',bottom=True,left=False,labelbottom=True,labelleft=False)
            self._ax_wei.set_ylabel("Neurons & Coefficients (re-ordered)")
        else:
            ax.set_ylabel("Neurons")

        if self.times is not None:
            assert self.times.ndim==1
            assert len(self.times)==self._t
            ax.set_xlabel("Time (s)")
        else:
            self.times = np.arange(self.X.shape[1])
            ax.set_xlabel("Time (frame)")
        dt = np.mean(np.diff(self.times))
        self._extent = [self.times[0]-dt/2,self.times[-1]+dt/2,self.X.shape[0]-0.5,-0.5]

        if (self.weights is not None) and (self.order is None):
            self.order = np.argsort(self.weights)[::-1]
        if self.order is not None:
            assert self.order.ndim==1
            assert len(self.order)==self._n
            self.X = self.X[self.order]
            if self.weights is not None:
                self.weights = self.weights[self.order]

        self._im_dff = self.ax.imshow(
            self.X,
            **self._X_params,
            interpolation='none', aspect='auto', extent=self._extent)
        if self.signal is not None:
            self._im_sig = self._ax_sig.imshow(
                self.signal.reshape(1,-1),
                **self._signal_params,
                aspect='auto', interpolation='none', extent=self._extent
            )
        if self.weights is not None:
            self._im_wei = self._ax_wei.imshow(
                self.weights.reshape(-1,1),
                cmap="seismic", vmin=-0.01, vmax=+0.01,
                aspect='auto', interpolation='none', extent=self._extent
            )

    @classmethod
    def update_img(cls, ax_img, img):
        """update the data of an matplotlib.image.AxesImage. """
        ax_img.set_data(img)

    def update_order(self, order):
        self.update_img(self._im_dff, self.X[order])
        if self.weights is not None:
            self.update_img(self._im_wei, self.weights[order].reshape(-1,1))

class PCA_raster(ComplexRaster):
    def __init__(self, ax, X, pca, k=0, times=None):
        self.pca = pca
        self.k = k
        self.x = X
        self.Y = self.pca.transform(X.T)
        super().__init__(
            ax,
            self.x,
            signal=self.Y[:,self.k],
            times=times,
            weights=self.pca.components_[self.k],
            X_params={"cmap":"inferno", "vmin":0, "vmax":0.7},
            signal_params={"cmap":"inferno", "vmin":-10, "vmax":+10},
            weights_params={"cmap":"plasma", "vmin":None, "vmax":None},
        )

    def change_component(self,k):
        print(self.X.shape)
        self.k = k
        self.update_img(self._im_sig, self.Y[:,self.k].reshape(1,-1))
        self.weights = self.pca.components_[self.k]
        order = np.argsort(self.weights)[::-1]
        self.update_img(self._im_wei, self.weights[order].reshape(-1,1))
        self.update_img(self._im_dff, self.x[order])

def plot_angle_colorbar(mappable, ax=None, label=""):
    """Add a circular colorbar to a plot.

    :mappable: matplotlib.cm.ScalarMappable
        see `plt.colorbar` or matplotlib.figure.Figure.colobar for more details
    :ax: ~.axes.Axes
        matplotlib parent axis
    :label: str
        label of the colorbar.
    """
    from matplotlib.projections.polar import PolarAxes
    angles = mappable.get_array()
    angles = np.unique(angles[np.isfinite(angles)])

    rad = np.linspace(0.9, 1.1, 2)
    rg, tg = np.meshgrid(rad,angles)

    ax = plt.gca()
    divider = make_axes_locatable(ax)
    _ax = divider.append_axes('right',size="20%",pad=0.5, axes_class=PolarAxes)
    _ax.set_title(label)

    vmin, vmax = mappable.get_clim()
    _ax.pcolormesh(np.deg2rad(angles), rad, tg.T, cmap=mappable.get_cmap(), vmin=vmin, vmax=vmax)
    t = np.rad2deg(_ax.get_xticks())
    t[t > 180] -= 360
    _ax.set_xticklabels([f"{int(tt)}°" for tt in t], fontdict={'fontweight':"bold"})
    _ax.axes.get_yaxis().set_visible(False)
    _ax.grid(False)
    _ax.axes.spines['polar'].set_visible(False)

class JointPlot:
    def __init__(self, ax, X, Y, tx=0, ty=0, **kwargs):
        self.X = X
        self.Y = Y
        self._n = len(self.X)
        self.ax_joint = ax
        divider = make_axes_locatable(self.ax_joint)
        self._ax_mx = divider.append_axes('top',size="20%",pad=0,sharex=self.ax_joint, ylabel="Density")
        self._ax_my = divider.append_axes('right',size="20%",pad=0,sharey=self.ax_joint, xlabel="Density")
        self._ax_my.tick_params(axis='both',which='both',bottom=True,left=False,labelbottom=True,labelleft=False)
        self._ax_mx.tick_params(axis='both',which='both',bottom=False,left=True,labelbottom=False,labelleft=True)

        self._scatt = self.ax_joint.scatter(
            self.X,
            self.Y,
            edgecolor="none",
            alpha=0.1*np.ones(self._n),
            c=np.zeros(self._n, dtype=np.int_),
            #cmap="flag_r", vmin=0, vmax=1,
            **kwargs,
            s=5,
        )
        _hx,_,_ = self._ax_mx.hist(self.X, bins=100, color="k", density=True);
        _hy,_,_ = self._ax_my.hist(self.Y, bins=100, color="k", orientation="horizontal", density=True);

        if tx is not None:
            self._x, self._y = tx,ty
            self._linex = self.ax_joint.axvline(self._x, color="red")
            self._linemx = self._ax_mx.axvline(self._x, color="red")
            self._liney = self.ax_joint.axhline(self._y, color="red")
            self._linemy = self._ax_my.axhline(self._y, color="red")
            self._textmx = self._ax_mx.text(self._x, _hx.max()+10,
                                            "50%", ha="center", va="bottom",
                                            color="red")
            self._textmy = self._ax_my.text(_hy.max()+10, self._y,
                                            "50%", ha="left", va="center",
                                            rotation=-90, color="red")
            self.change_thresh(self._x, self._y)

    def change_thresh(self, tx=0, ty=0, sidex="t", sidey="t"):
        maskX = (self.X > tx) if sidex=="t" else(self.X < tx)
        maskY = (self.Y > ty) if sidey=="t" else(self.Y < ty)
        mask = maskX.astype(np.uint8)+maskY.astype(np.uint8)*2
        self._scatt.set_array(mask)
        self._scatt.set_alpha(np.where(mask, 0.5, 0.1))
        self._x, self._y = tx,ty
        self._linex.set_xdata([self._x]) ; self._linemx.set_xdata([self._x])
        self._liney.set_ydata([self._y]) ; self._linemy.set_ydata([self._y])
        self._textmx.set_x(self._x) ; self._textmy.set_y(self._y)
        self._textmx.set_text(f"{inv_quantile(self.X, self._x):0.1f}%")
        self._textmy.set_text(f"{inv_quantile(self.Y, self._y):0.1f}%")
        return mask

def widgets_for_pca(n_componants=5):
    v = []
    for p in range(n_componants):
        button = widgets.ToggleButton(value=False,description=f'PC{p}')
        side = widgets.RadioButtons(options=['top', 'bottom'], layout={'width': 'max-content'})
        slider = widgets.FloatSlider(
            value=10,
            min=0,
            max=100,
            step=1,
            continuous_update=False,
            #readout_format='.2f',
        )
        unit = widgets.Label(value="%")
        h = widgets.HBox([button,side, slider, unit])
        v.append(h)
    return widgets.VBox(v)

def params_from_widgets(widg):
    n = len(widg.children)
    ons = np.zeros(n, dtype=np.bool_)
    side = np.zeros(n, dtype=str)
    lims = np.zeros(n)
    for p,c in zip(range(n), widg.children):
        ons[p] = c.children[0].value
        side[p] = c.children[1].value[0]
        lims[p] = np.array(c.children[2].value)/100
    return ons, side, lims

def mask_from_quantile(distrib, q=0.01, side="t"):
    assert distrib.ndim == 1, ":distrib: should be a 1D vector."
    if side == "t":
        q = 1-q
    elif side == "b":
        pass
    else:
        raise TypeError(f":side: should be 't' or 'b'. You gave {side}.")

    thresh = np.quantile(distrib, q)

    if side == "t":
        mask = distrib > thresh
    elif side == "b":
        mask = distrib < thresh

    return mask

def mask_from_widgets(pca, widg):
    onoff, side, quant = params_from_widgets(widg)

    if (~onoff).all():
        return np.zeros(pca.components_.shape[1], dtype=np.bool_)

    mask = np.ones(pca.components_.shape[1], dtype=np.bool_)
    for p in range(len(onoff)):
        if onoff[p]:
            submask = mask_from_quantile(pca.components_[p], quant[p], side=side[p])
            mask *= submask
    return mask

def recursive_observe(widg, func):
    for c in widg.children:
        if hasattr(c, "value"):
            c.observe(func)
        else:
            recursive_observe(c, func)


from typing import Optional

import requests

from cp_6.env_configuration import settings

def main():
    choice = input("[R]eport weather or [s]ee reports? [exit] to quit!")

    while choice != "exit":
        if choice.lower().strip() == "r":
            post_report()

        elif choice.lower().strip() == "s":
            get_report()

        elif choice.lower() == "exit":
            quit

        else:
            print(f"{choice} not implemented yet!")
            choice = input("\n[R]eport weather or [s]ee reports? [exit] to quit!")

def post_report():
    desc = input("O que você gostaria de reportar?")
    city = input("Em qual cidade está acontecendo?")
    data = dict(
        description=desc,
        location=dict(
            city=city,
        )
    )
    resp = __connector(action="post", data=data)
    resp.raise_for_status()
    result = resp.json()
    print(f"Novo evento reportado: {result.get('id')}")

def get_report():
    resp = __connector(action='get')
    resp.raise_for_status()

    data = resp.json()
    for r in data:
        print(f"{r.get('location').get('city')} has {r.get('description')}")

def __connector(action: str, data: Optional[dict] = None):
    url = settings.url
    endpoint = '/api/reports'
    url = {url} + endpoint
    if action == "post":
        return requests.post(url, json=data)
    elif action == "get":
        return requests.get(url)

if __name__ == '__main__':
    main()


""" You are given an undirected graph (the "original graph") with n nodes labeled from 0 to n - 1. You decide to subdivide each edge in the graph into a chain of nodes, with the number of new nodes varying between each edge.

The graph is given as a 2D array of edges where edges[i] = [ui, vi, cnti] indicates that there is an edge between nodes ui and vi in the original graph, and cnti is the total number of new nodes that you will subdivide the edge into. Note that cnti == 0 means you will not subdivide the edge.

To subdivide the edge [ui, vi], replace it with (cnti + 1) new edges and cnti new nodes. The new nodes are x1, x2, ..., xcnti, and the new edges are [ui, x1], [x1, x2], [x2, x3], ..., [xcnti-1, xcnti], [xcnti, vi].

In this new graph, you want to know how many nodes are reachable from the node 0, where a node is reachable if the distance is maxMoves or less.

Given the original graph and maxMoves, return the number of nodes that are reachable from node 0 in the new graph.

Example 1:

Input: edges = [[0,1,10],[0,2,1],[1,2,2]], maxMoves = 6, n = 3
Output: 13
Explanation: The edge subdivisions are shown in the image above.
The nodes that are reachable are highlighted in yellow.
Example 2:

Input: edges = [[0,1,4],[1,2,6],[0,2,8],[1,3,1]], maxMoves = 10, n = 4
Output: 23
Example 3:

Input: edges = [[1,2,4],[1,4,5],[1,3,1],[2,3,4],[3,4,5]], maxMoves = 17, n = 5
Output: 1
Explanation: Node 0 is disconnected from the rest of the graph, so only node 0 is reachable. """

import heapq
from typing import List

class Solution:
    def reachableNodes(self, edges: List[List[int]], maxMoves: int, n: int) -> int:
        """构建邻接表"""
        adj = [[] for _ in range(n)]
        for u, v, w in edges:
            adj[u].append((v, w))
            adj[v].append((u, w))

        """Dijkstra"""
        dist = [float('inf')] * n
        dist[0] = 0
        pq = [(0, 0)]
        while pq:
            d, u = heapq.heappop(pq)
            if d > dist[u]:
                continue
            for v, w in adj[u]:
                if d + w + 1 < dist[v]:
                    dist[v] = d + w + 1
                    heapq.heappush(pq, (dist[v], v))
        print(dist)
        """计算结果"""
        ans = 0
        for u, v, w in edges:
            if dist[u] > maxMoves and dist[v] > maxMoves:
                continue
            ans += min(dist[u] + dist[v] + w, maxMoves) - max(dist[u], dist[v])
            if dist[u] < maxMoves:
                ans += 1
            if dist[v] < maxMoves:
                ans += 1
        for i in range(n):
            if dist[i] <= maxMoves:
                ans += 1
        return ans

print(Solution().reachableNodes([[0,1,4],[1,2,6],[0,2,8],[1,3,1]], 10, 4))


import pygame

# 飞船类
class Ship:
    # screen传入为整个屏幕对象，目的是指出飞船的绘制地点
    def __init__(self, screen, ai_setting, ships, mode=0):
        """初始化飞船并设置其初试位置"""
        self.setting = ai_setting
        self.screen = screen
        self.image = pygame.image.load('images/ship.bmp')
        # 返回一个rect对象，pygame以矩形为处理对象的的基本，如果一个图形不是矩形，则获得该图像的外接矩形
        # 获得飞船图像的外接矩形
        self.rect = self.image.get_rect()
        # 获得屏幕的外接矩形
        self.screen_rect = screen.get_rect()
        # 操作者控制的飞船初化初始化
        if not mode:
            self.init_pos()
        elif mode == 1:
            self.init_icon_ship(ships)

    def blitme(self):
        """绘制图像"""
        # 在制定位置绘制图像
        self.screen.blit(self.image, self.rect)

    def update_pos(self):
        """处理连续按压"""
        if self.continue_right and self.rect.right < self.screen_rect.right:
            self.centerx += self.setting.ship_speed
        elif self.continue_left and self.rect.left > 0:
            self.centerx -= self.setting.ship_speed
        elif self.continue_up and self.rect.top > 0:
            self.centery -= self.setting.ship_speed
        elif self.continue_down and self.rect.bottom < self.screen_rect.bottom:
            self.centery += self.setting.ship_speed
        #     更新
        self.rect.center = (self.centerx, self.centery)

    def init_pos(self):
        """初始化飞船的位置"""
        self.rect.centerx = self.screen_rect.centerx
        self.rect.bottom = self.screen_rect.bottom
        # self.rect.centery = self.screen_rect.centery
        # self.rect.center = self.screen_rect.center
        # rect的center属性为图像的中心点坐标，为一个元组
        # 同样centerx，centery属性为图像中心点的x,y轴的坐标
        # print(type(self.rect.center))
        # print(type(self.rect.centerx))
        # print(type(self.rect.bottom))
        # print(self.screen_rect.right)
        # 控制键盘按键持续移动的变量
        self.continue_right = False
        self.continue_left = False
        self.continue_up = False
        self.continue_down = False
        # 小数的方式更加精细的控制
        self.centerx = float(self.rect.centerx)
        self.centery = float(self.rect.centery)

    def init_icon_ship(self, ships):
        """初始化ships显示的位置"""
        ships_len = len(ships)
        self.rect.left = ships_len * self.rect.width
        self.rect.top = self.setting.ship_icon_top

    @staticmethod
    def init_ships_group(ships, screen, ai_setting):
        """初始化飞船组"""
        while len(ships) < ai_setting.ship_allow_number:
            ship = Ship(screen, ai_setting, ships, 1)
            ship.init_icon_ship(ships)
            ships.append(ship)

    @staticmethod
    def remove_ship(current_left, ships):
        """对ships飞船组里面的飞船进行移除"""
        if len(ships) == current_left:
            pass
        else:
            remove_number = len(ships) - current_left
            while remove_number != 0:
                if len(ships):
                    ships.pop()
                    remove_number -= 1


import numpy as np
from skimage.transform import radon, iradon, iradon_sart
import utils
from scipy.optimize import curve_fit
from track import Lattice
from preprocess import Preprocess
import tensorflow as tf
from neural_net import FeedBack

class Reconstruct():
    def __init__(self,
                 process):
        self.process = process
        self.projections = process.projections.T
        self.thetas = process.thetas
        self.ks = process.ks

    def MLEM(self, iterations):
            """
            The MLEM function takes in the number of iterations and returns a reconstructed image.
            The MLEM function uses the Radon transform to project an image onto a sinogram, then backproject it using
            the inverse Radon transform. The ratio between the original projection and this new projection is used to
            correct for errors in each iteration.

            :param self: Bind the method to the object
            :param iterations: Determine how many times the algorithm will run
            :return: A 2d array
            :doc-author: Trelent
            """
            n_iters=iterations
            mlem_rec = np.ones((self.projections.shape[0], self.projections.shape[0]))
            sino_ones = np.ones(self.projections.shape)
            sens_image = iradon(sino_ones, theta=-self.thetas, circle=True, filter_name = None)

            for p in range(n_iters):

                fp = radon(mlem_rec, -self.thetas, circle=True)
                ratio = self.projections/(fp+0.000001)
                correction = iradon(ratio, -self.thetas, circle=True, filter_name=None)/(sens_image+0.000001)
                mlem_rec = mlem_rec*correction
            xs = mlem_rec
            return xs

    def SART(self, iterations):
        """
        The SART function takes the projections and angles of a given object,
        and returns an image of that object. The function uses the iradon_sart
        method from scikit-image to reconstruct the image.

        :param self: Bind the method to an object
        :param iterations: Determine how many times the sart algorithm will run
        :return: The reconstructed image
        :doc-author: Trelent
        """
        xs = np.zeros((len(self.projections),len(self.projections)))
        for p in range(iterations):
            xs = iradon_sart(self.projections, theta = -self.thetas, image = xs)
        xs[xs<0] = 0
        return xs

    def FBP(self):
        """
        The FBP function takes the projections and thetas from a given object,
        and uses them to reconstruct an image using filtered backprojection.

        :param self: Bind the method to an object
        :return: The reconstructed image
        :doc-author: Trelent
        """
        xs = iradon(self.projections, theta = -self.thetas)
        xs[xs<0]=0
        return xs

    def fit_profiles(self):
        """
        The fit_profiles function fits a Gaussian profile to the unscaled projections of the process.
        The function returns an array of sigmas, which are used in the calculation of kurtosis.

        :param self: Refer to the instance of a class
        :return: The sigmas array, which is the standard deviation of each projection
        :doc-author: Trelent
        """
        sigma= []
        for k in range(len(self.ks)):
            X = self.process.x_new
            Y = self.process.unscaled_projections[k,:]
            coeffs,_ = utils.gaussian_profile_fit(X, Y)
            sigma.append(coeffs[2])
        self.sigmas  = np.array(sigma)

    def quad_rec_matrix(self):
        """
        The quad_rec_matrix function creates a matrix of the form:

        :param self: Bind the method to an object
        :return: The pseudo-inverse of the matrix a
        :doc-author: Trelent
        """
        A = []
        d = self.process.sequence['drift'][0]
        l = self.process.sequence['quad'][0]
        for k in self.ks:
            seq = {'quad':[l,k], 'drift':[d]}
            lattice = Lattice()
            M = lattice.create_lattice(seq)
            if len(A)==0:
                A = np.array([M[0,0]**2, +2*M[0,0]*M[0,1], M[0,1]**2])
            else:
                A = np.vstack((A, np.array([M[0,0]**2, +2*M[0,0]*M[0,1], M[0,1]**2])))
        self.A_i = np.linalg.pinv(A)

    def QuadScanRec(self, sigmas = None):
        """
        The QuadScanRec function takes the sigmas from a quad scan and returns the reconstructed epsilon, alpha, beta, gamma values.

        :param self: Bind the method to an object
        :param sigmas: Calculate the inverse of the a matrix
        :return: The epsilon, alpha, beta and gamma parameters of the quadrupole
        :doc-author: Trelent
        """
        self.fit_profiles()
        if sigmas is None:
            sigmas = self.sigmas
        self.quad_rec_matrix()
        s11i, s12i, s22i = np.dot(self.A_i,sigmas.T**2)
        eps = np.sqrt(abs(s11i*s22i-s12i**2))
        alf = -s12i/eps
        bet = s11i/eps
        gam = s22i/eps
        return eps, alf, bet, gam


"""
Uses the NASA API to get images from Curiosity's cameras.
"""

from requests_html import HTMLSession
import os
import json
from urllib.parse import urlparse

if not os.path.exists("color"):
    os.mkdir("color")

# template for getting images
# camera = "mast"
solRaw = "https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos?sol={sol}&camera=mast&api_key=DEMO_KEY"

session = HTMLSession()

#  get images from first 1000 sols

"""
Can reach end of Sol 40 from 1 before hitting the rate limit.
Change 'start' by ~40 each time the ratelimit resets, or refer to the Sol the process stalled at.
"""
start = 160

for sol in range(start, 1000):

    print(f"Getting images for Sol: {sol}")

    solLink = solRaw.format(sol = sol)

    r = session.get(solLink)

    data_json = json.loads(r.content)

    try:

        for item in data_json["photos"]:

            rawImgUrl = item["img_src"]

            a = urlparse(rawImgUrl)
            newFilename = os.path.basename(a.path)

            print(f"Found image from {rawImgUrl}")
            if os.path.isfile(f"color/{newFilename}"):
                print("Already downloaded, passing")
                continue

            else:
                rawImg = session.get(rawImgUrl).content
                print(rawImgUrl, "downloaded")

                with open(f"color/{newFilename}", "wb") as imageOut:
                    imageOut.write(rawImg)

    except KeyError:

        if data_json["error"]:
            print(f"Error: {data_json['error']['code']}")
            break
        else:
            print(f"No images found for sol: {sol}.")

print("Process end")


import http.client

print("---THIS-PROGRAM-FINDS-THE-URL-OF-A-SERVER---\n")

host = input("---INSERT-THE-HOSTS-IP---\n")
port = input("---INSERT-THE-PORT(default:80)---\n")
url = input("---INSERT-THE-URL---\n")

if(port == ""):
	port = 80

try:
    connection = http.client.HTTPConnection(host, port)
    connection.request('GET', url)
    response = connection.getresponse()
    print('---SERVER-RESPONSE---\n',response.status)
    connection.close()
except ConnectionRefusedError:
      print("\n---CONNECTION-FAILED---")


from pathlib import Path
from typing import Dict, List
import shutil

from dipy.data import (
    fetch_stanford_hardi,
    fetch_stanford_labels,
    fetch_stanford_t1,
    get_fnames,
)

def download_small_dwi_data(download_dir: Path) -> Dict[str, List[Path]]:
    """Download small test dwi data, no t1 or labels are provided

    Args:
        download_dir: specify folder where data is copied
    """
    download_dir.mkdir(exist_ok=True)
    files = []
    for f in get_fnames(name="small_25"):
        files.append(Path(download_dir) / Path(f).name)
        shutil.copyfile(Path(f), files[-1])
    return {"dwi": files}

def download_stanford_data(download_dir: Path) -> Dict[str, List[Path]]:
    """Download standford dwi data, t1 image and labelfield

    Args:
        download_dir: specify folder where data is copied
    """

    def _fetch_and_copy(fetch_fun):
        files, dipy_dir = fetch_fun()
        for f in files.keys():
            shutil.copyfile(Path(dipy_dir) / f, Path(download_dir) / f)
        return [download_dir / f for f in files.keys()]

    download_dir.mkdir(exist_ok=True)
    dwi_files = _fetch_and_copy(fetch_stanford_hardi)
    t1_files = _fetch_and_copy(fetch_stanford_t1)
    label_files = _fetch_and_copy(fetch_stanford_labels)
    return {"dwi": dwi_files, "t1": t1_files, "labels": label_files}

if __name__ == "__main__":
    output_dir = Path("/Users/lloyd/Models/StandfordData")
    files = download_stanford_data(download_dir=output_dir)

    for f in output_dir.glob("*.*"):
        print(f)


import pandas as pd
import click
import io
import os
pd.options.display.float_format = '{:.0f}'.format

@click.command()
@click.option('--input', type=click.Path(exists=True), help='Input path.')
@click.option('--output', type=click.Path(), help='Output path.')
def lovd(input, output):
    """From Rudzik with LOVD."""
    df = pd.read_csv(input, sep='\t', skiprows=0, header=1, low_memory=False)
    if os.path.exists(output):
        os.remove(output)
    # with open("C:/Users/Engineering/Documents/Rudzik/work/LOVD/FFBupload_empty.txt") as fh:
    #     txt = fh.read()
    # this piece of code is to avoid closing the file manually! Normally it would look like this:
    # fh = open("C:/Users/Engineering/Documents/Rudzik/work/LOVD/Tracewska 2019/FFBupload_empty.txt")python LOVD.py --input  "C:\Users\Engineering\Documents\Rudzik\work\LOVD\Hosono 2018\Hosono-2018.txt" --output “C:\Users\Engineering\Documents\Rudzik\work\LOVD\Hosono 2018\booo.txt”
    # txt = fh.read()
    # fh.close()
    txt1 = '''### LOVD-version 3000-060 ### Full data download ### To import, do not remove or alter this header ### \r\n
    ## Genes ## Do not remove or alter this header ## \r\n
    ## Transcripts ## Do not remove or alter this header ## \r\n
    ## Diseases ## Do not remove or alter this header ##\r\n
    ## Genes_To_Diseases ## Do not remove or alter this header ##\r\n
    ## Individuals ## Do not remove or alter this header ##'''
    data = io.StringIO(txt1)  # this tells me it is an IO object
    txt2 = pd.read_csv(data, sep="\t", header=0)  # this reads the data into CSV
    txt2.to_csv(output, index=False, sep='\t',
                float_format='%d', mode='a')  # this outputs the data into tab delimited text
    df1 = df.iloc[:, 0:19]
    df1 = df1.dropna(subset=['{{panel_size}}'])
    df1.drop_duplicates(subset=['{{id}}'])
    df1 = df1.to_csv(output, index=False, sep='\t',
                     float_format='%d', mode='a')
    txt3 = '''## Individuals_To_Diseases ## Do not remove or alter this header ##'''
    df2_header = io.StringIO(txt3)
    txt3 = pd.read_csv(df2_header, sep="\t")
    txt3 = txt3.to_csv(output, index=False, sep='\t',
                       float_format='%d', mode='a')
    txt31 = '''{{individualid}}\t{{diseaseid}}'''
    df2_header2 = io.StringIO(txt31)
    txt31 = pd.read_csv(df2_header2, sep="\t")
    txt31 = txt31.to_csv(output, index=False,
                         sep='\t', float_format='%d', mode='a')
    df2 = df.iloc[:, 19:21]  ## Individuals_To_Diseases ##
    df2 = df2.dropna()
    df2 = df2.drop_duplicates(subset=['{{individualid}}'])
    df2.to_csv(output, header=0, index=False,
               sep='\t', float_format='%d', mode='a')
    txt4 = '''## Phenotypes ## Do not remove or alter this header ##'''
    df3_header = io.StringIO(txt4)
    txt4 = pd.read_csv(df3_header, sep="\t")
    txt4 = txt4.to_csv(output, index=False, sep='\t',
                       float_format='%d', mode='a')
    df3 = df.iloc[:, 19:34]  ## Phenotypes ## Do not remove or alter this header ##
    df3 = df3.dropna(subset=['{{individualid}}'])
    df3.columns = df3.columns.str.replace(r"(\.)(\d)", '', regex=True)
    df3.to_csv(output, index=False, sep='\t',
               float_format='%d', mode='a')
    txt5 = '''## Screenings ## Do not remove or alter this header ##'''
    df4_header = io.StringIO(txt5)
    txt5 = pd.read_csv(df4_header, sep="\t")
    txt5 = txt5.to_csv(output, index=False, sep='\t',
                       float_format='%d', mode='a')
    df4 = df.iloc[:, 34:43]  ## Screenings ## Do not remove or alter this header ##
    df4.columns = df4.columns.str.replace(r"(\.)(\d)", '', regex=True)
    df4 = df4.drop_duplicates(subset=['{{id}}'])
    df4 = df4.dropna(subset=['{{individualid}}'])
    df4.to_csv(output, index=False, sep='\t',
               float_format='%d', mode='a')
    txt6 = '''## Screenings_To_Genes ## Do not remove or alter this header ##'''
    df5_header = io.StringIO(txt6)
    txt6 = pd.read_csv(df5_header, sep="\t")
    txt6 = txt6.to_csv(output, index=False, sep='\t', float_format='%d', mode='a')
    df5 = df.iloc[:, 43:45]  ## Screenings_To_Genes ## Do not remove or alter this header ##
    df5 = df5.dropna(subset=['{{screeningid}}'])
    df5 = df5.drop_duplicates(subset=['{{screeningid}}'])
    df5.to_csv(output, index=False, sep='\t',
               float_format='%d', mode='a')
    txt7 = '''## Variants_On_Genome ## Do not remove or alter this header ##'''
    df6_header = io.StringIO(txt7)
    txt7 = pd.read_csv(df6_header, sep="\t")
    txt7 = txt7.to_csv(output, index=False, sep='\t',
                       float_format='%d', mode='a')

    df6 = df.iloc[:, 53:76]  ## Variants_On_Genome ## Do not remove or alter this header ##
    df6.columns = df6.columns.str.replace(r"(\.)(\d)", '', regex=True)
    df6 = df6.dropna(subset=['{{id}}'])

    df6.to_csv(output, index=False, sep='\t',
               float_format='%d', mode='a')

    txt8 = '''## Variants_On_Transcripts ## Do not remove or alter this header ##'''
    df7_header = io.StringIO(txt8)
    txt8 = pd.read_csv(df7_header, sep="\t")
    txt8 = txt8.to_csv(output, index=False, sep='\t',
                       float_format='%d', mode='a')

    df7 = df.iloc[:, 46:53]  ## Variants_On_Transcripts ## Do not remove or alter this header ##
    df7.columns = df7.columns.str.replace(r"(\.)(\d)", '', regex=True)
    df7 = df7.dropna(subset=['{{id}}'])
    df7.to_csv(output, index=False, sep='\t',
               float_format='%d', mode='a')
    txt9 = '''## Screenings_To_Variants ## Do not remove or alter this header ##\r\n'''
    df8_header = io.StringIO(txt9)
    txt9 = pd.read_csv(df8_header, sep="\t")
    txt9 = txt9.to_csv(output, index=False, sep='\t',
                       float_format='%d', mode='a')
    txt10 = '''{{screeningid}}\t{{variantid}}'''
    df8_header2 = io.StringIO(txt10)
    txt10 = pd.read_csv(df8_header2, sep="\t")
    txt10 = txt10.to_csv(output, index=False,
                         sep='\t', float_format='%d', mode='a')
    df8 = df.iloc[:, 45:47]  ## Screenings_To_Variants ## Do not remove or alter this header ##
    df8.columns = df8.columns.str.replace(r"(\.)(\d)", '', regex=True)
    df8 = df8.dropna(subset=['{{id}}'])
    df8.to_csv(output, header=0, index=False, sep='\t', float_format='%d', mode='a')

if __name__ == '__main__':
    lovd()


# -*- coding: utf-8 -*-
import json

from flask import (render_template, g, request, current_app, flash, redirect,
                   url_for, abort)
from flask.ext.login import login_required, current_user
from shapely.geometry import mapping

from models import Trip
from login_views import create_login_views
from filters import create_filters
from parse_gpx import parse_gpx

TRIP_TYPES = {
    'hiking': u'Fjelltur',
    'jogging': u'Joggetur',
    'walking': u'Gåtur',
    'cycling': u'Sykling',
    'nordicski': u'Skitur',
    'car': u'Biltur',
    'swimming': u'Svømmetur',
    'rollerskate': u'Rulleskøyter',
    'snowshoeing': u'Truger',
    'motorbike': u'Motorsykkel',
    'snowmobiling': u'Snøscooter',
    'atv': u'ATV',
    'default': u'Annet',
}

def create_views(app):

    create_filters(app)
    create_login_views(app)

    @app.before_request
    def before_request():
        g.user = current_user

    @app.route('/')
    def index():
        if current_user.is_authenticated():
            return redirect(url_for('trips'))
        return render_template('index.html')

    @app.route('/editprofile', methods=['GET', 'POST'])
    def editprofile():
        if request.method == 'GET':
            return render_template(
                'editprofile.html',
                user=current_user,
                errors={},
                edit=True
            )

        if request.form['password'] and request.form['password'] != '':
            current_user.set_password(
                request.form['password'],
                request.form['password2']
            )
        current_user.email = request.form['email'],
        current_user.fullname = request.form['fullname']

        if current_user.validate():
            current_app.db_session.add(current_user)
            current_app.db_session.commit()
            flash('Profilen ble oppdatert!')

        return render_template(
            'editprofile.html',
            errors=current_user.validation_errors,
            user=current_user,
            edit=True
        )

    @app.route('/trips')
    @login_required
    def trips():
        trips = [trip.serialize_with_point() for trip in current_user.trips]
        return render_template('trips.html', trips=json.dumps(trips))

    ALLOWED_EXTENSIONS = set(['gpx'])

    def allowed_file(filename):
        return '.' in filename and \
            filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS

    @app.route('/upload', methods=['GET', 'POST'])
    @login_required
    def upload():
        errors = {}
        data = {}
        if request.method == 'POST':

            file = request.files['file']
            title = request.form['title']
            type = request.form['type']
            description = request.form['description']

            if not title or title == '':
                errors['title'] = 'Oppgi en tittel'
            if not file:
                errors['file'] = u'Du må angi en fil.'
            elif not allowed_file(file.filename):
                errors['file'] = u'Ugyldig filtype! (må være en av %s)' % \
                    ', '.join(ALLOWED_EXTENSIONS)
            data['title'] = title
            data['type'] = type
            data['description'] = description
            if not errors:
                try:
                    points = parse_gpx(file)
                    trip = Trip(
                        user=current_user,
                        title=title,
                        description=description,
                        type=type,
                        start=points[0].time,
                        stop=points[-1].time,
                    )
                    trip.points = points
                    current_app.db_session.add(trip)
                    current_app.db_session.commit()
                    flash(u'Turen ble lagret!')
                    return redirect(url_for('trip_detail', id=trip.id))
                except ValueError:
                    flash(u'Filen du lastet opp er ikke gyldig GPX!')

        return render_template(
            'upload.html',
            trip_types=TRIP_TYPES,
            errors=errors,
            data=data
        )

    @app.route('/trips/<int:id>')
    def trip_detail(id):

        trip = current_app.db_session.query(Trip).get(id)
        if not trip:
            abort(404)
        return render_template(
            'trip_detail.html',
            trip=trip,
            trip_types=TRIP_TYPES,
            geom=json.dumps(mapping(trip.geom))
        )


import numpy as np
import random
import Gridenv
import copy
import matplotlib.pyplot as plt
from matplotlib.pyplot import figure, Rectangle
import seaborn as sns
import statistics as stats

def obs_trp_lists():
    obs_lst = []
    for row in range(10):
        for col in range(10):
            if env.GridWorld["state"][row, col] == "obstacle":
                obs_lst.append((col, row))

    # list of traps#
    trp_lst = []
    for row in range(10):
        for col in range(10):
            if env.GridWorld["state"][row][col] == "trap":
                trp_lst.append((col, row))
    return (obs_lst, trp_lst)

env = Gridenv.Grid()

##---------------------------Tabular Q-learning  ----------------------------##

def Q_learning(epsilon1, epsilon2):
    learning_rate = 0.2
    discount_rate = 0.9
    epsilon1 = epsilon1
    epsilon2 = epsilon2

    episode_goal = []
    q_table = np.zeros([100, 4])
    no_episodes = 100000
    times_goal = 0
    times_traped = 0
    for episodes in range(0, no_episodes):
        terminal_state = 0
        env.reset()

        # env.position = (0,0)
        position = env.position
        state = ((list(position)[0] * 10) + list(position)[1])

        while True:
            ####------------------choosing_action-----------------------########

            if random.uniform(0, 1) < epsilon1:
                chosen_action = random.randint(0, 3)

            else:
                chosen_action = np.argmax(q_table[state, :], axis=0)

            # taking action
            if state == 99:
                print(chosen_action)
            list_next_state = env.step(chosen_action, epsilon2)
            if list_next_state[3]:
                # print("goal reached")
                episode_goal.append(1)
                times_goal = times_goal + 1

            if list_next_state[-1] and (not list_next_state[3]):
                # print("trapped")
                episode_goal.append(0)
                times_traped = times_traped + 1

            reward = list_next_state[2]
            position = copy.deepcopy(list_next_state[0])
            terminal_state = list_next_state[-1]
            next_state = ((list(position)[0] * 10) + list(position)[1])

            # Recalculate
            q_value = q_table[state, chosen_action]

            max_value = np.max(q_table[next_state, :])
            new_q_value = (1 - learning_rate) * q_value + learning_rate * (reward + discount_rate * max_value)

            q_table[state, chosen_action] = new_q_value
            state = next_state

            if terminal_state:
                break
            # print(q_table)

    return q_table

def get_maxQ_array(q_table):
    list_maxQ = []
    for i in range(0, 100):
        max_q = np.amax(q_table[i, :], axis=0)
        list_maxQ.append(max_q)

    maxQ_array = np.array(list_maxQ)
    maxQ_array = maxQ_array.reshape((10, 10))
    return maxQ_array

def get_variance(q_table):
    list_var = []
    for i in range(0, 100):
        list_var.append(stats.stdev(q_table[i, :]))
    var_array = np.array(list_var)
    var_array = var_array.reshape((10, 10))
    return var_array

epsilon1 = [0.1, 0.2, 0.3]
epsilon2 = [0.05, 0.1, 0.15]
counter = 0
fig1, ax1 = plt.subplots(3, 3, figsize=(20, 20))
fig2, ax2 = plt.subplots(3, 3, figsize=(20, 20))

for i, p in enumerate(epsilon1, 0):
    for j, q in enumerate(epsilon2, 0):
        rows = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
        col = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
        q_table = Q_learning(p, q)
        maxQ_array = get_maxQ_array(q_table)
        var_array = get_variance(q_table)
        var_array = np.around(var_array, decimals=2)
        var_array = var_array.astype(np.float)
        heatmap_max = sns.heatmap(maxQ_array, annot=True, cmap="YlGnBu", ax=ax1[i, j])
        ax1[i, j].set_title("epsilon = %f and p = %f" % (round(p, 2), round(q, 2)))
        heatmap_var = sns.heatmap(var_array, annot=True, ax=ax2[i, j])
        ax2[i, j].set_title("epsilon = %f and p = %f" % (round(p, 2), round(q, 2)))
        # counter = counter + 1
        obs_lst, trp_lst = obs_trp_lists()

        for r in obs_lst:
            heatmap_max.add_patch(Rectangle(r, 1, 1, fill=False, edgecolor='green', lw=3))
        for s in trp_lst:
            heatmap_max.add_patch(Rectangle(s, 1, 1, fill=True, edgecolor='black', lw=3))
            heatmap_max.add_patch(Rectangle((9, 9), 1, 1, fill=False, edgecolor='red', lw=3))
        for r in obs_lst:
            heatmap_var.add_patch(Rectangle(r, 1, 1, fill=False, edgecolor='green', lw=3))
        for s in trp_lst:
            heatmap_var.add_patch(Rectangle(s, 1, 1, fill=True, edgecolor='black', lw=3))
            heatmap_var.add_patch(Rectangle((9, 9), 1, 1, fill=False, edgecolor='red', lw=3))
fig1.savefig('MaxQ.jpeg', bbox="tight", dpi=200)
fig1.show()
fig2.savefig('variance.jpeg', bbox="tight", dpi=200)
fig2.show()

# fig2.savefig("hi")

# ---------------- ploting heatmap --------------------#

# rows = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
# col = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
#
# sns.set(style = "whitegrid")
# heat_map = sns.heatmap(maxQ_array, annot= True, cmap="YlGnBu")
#
# # list of obstacle#
# plt.show()

# #### testing the learned policy  ###############

# print("now lets test the policy we have created")
#
# list_steps = []
# goal_steps = []
# trap_steps = []
# test_goal = 0
#
# for episodes in range(0, 100):
#
#     # print("episode number %i running" % episodes)counter
#     terminal_state = 0
#     steps = 0
#     times_traped = 0
#     env.reset()
#     # env.position = (0,0)
#     position = env.position
#     print((position[0] + 1, position[1] + 1))
#     state = ((list(position)[0] * 10) + list(position)[1])
#
#     while True:
#         chosen_action = np.argmax(q_table[state, :], axis=0)
#
#         list_next_state = env.step(chosen_action)
#         steps = steps + 1
#         if list_next_state[3]:
#             print("goal reached")
#             # print(steps)
#             test_goal = test_goal + 1
#         if (list_next_state[-1] and (not list_next_state[3])):
#             # print("trapped")
#             times_traped = times_traped + 1
#
#         position = copy.copy(list_next_state[0])
#         # print(position)
#         terminal_state = list_next_state[-1]
#         next_state = ((list(position)[0] * 10) + list(position)[1])
#         state = next_state
#
#         if terminal_state:
#             break
#     print("while loop exited--------------------------")
# print(test_goal)
# # print(q_table)
# # plt.plot(list_steps, label = 'normal steps')
# #
# # # plt.show()


import unittest

from regions import Regions

regionsHtml = """
<TD>
   <select name="state">
    <OPTION value="World" Selected>World</OPTION>
    <OPTION value="North" >Northern Hemisphere</OPTION>
    <OPTION value="South" >Southern Hemisphere</OPTION>
    <optgroup label="Continent">
    <option value="Afr">Africa</option>
    <option value="Ames">America (South)</option>
    <option value="Amen">America (North and Central)</option>
    <option value="Anta">Antarctica</option>
    <option value="Asi">Asia</option>
    <option value="Eur">Europe</option>
    <option value="Pacs">Australia and Pacific</option>
    </optgroup>
    <optgroup label="State">
      <!-- Esto sirve para poner como activo una opcion adecuada teniendo en cuenta lo obtenido por geoip -->
<OPTION value='Afg' >Afghanistan</option>
"""

class TestRegions(unittest.TestCase):
    def test_get_regions(self):
        """
        Test that we can parse the regions
        """
        regions1 = Regions(regionsHtml)
        regionsList = regions1.getRegions()

        self.assertEqual(len(regionsList), 10)

    def test_get_regions_names(self):
        """
        Test that we can parse the region names
        """
        regions1 = Regions(regionsHtml)
        regionsList = regions1.getRegions()

        self.assertEqual(regionsList[0][0], "World")
        self.assertEqual(regionsList[0][1], "World")
        self.assertEqual(regionsList[1][0], "North")
        self.assertEqual(regionsList[1][1], "Northern Hemisphere")
        self.assertEqual(regionsList[9][0], "Pacs")
        self.assertEqual(regionsList[9][1], "Australia and Pacific")

if __name__ == '__main__':
    unittest.main()


from requests import Request, Session
from json import dumps
from json.decoder import JSONDecodeError
from datetime import datetime
from hashlib import sha1, md5
import hmac
from base64 import b64encode, b64decode

class SpektrixCredentials(object):
    def __init__(self, client_name, api_user, api_key):
        self.client_name = client_name
        self.api_user = api_user
        self.api_key = api_key

class SpektrixAnonymous(object):
    def __init__(self, client_name):
        self.client_name = client_name
        self.api_user = None
        self.api_key = None

class SpektrixRequest(object):
    def __init__(self, endpoint, credentials):
        self.spektrix_api_user = credentials.api_user
        self.spektrix_api_key = credentials.api_key
        self.has_credentials = isinstance(credentials, SpektrixCredentials)

        base_url = "https://system.spektrix.com/" + credentials.client_name + "/api/v3/"
        self.url = base_url + endpoint

    def get(self):
        self.method = "GET"
        response = self._make_request()
        return response

    def post(self, payload=None):
        self.method = "POST"
        response = self._make_request(payload)
        return response

    def patch(self, payload):
        self.method = "PATCH"
        response = self._make_request(payload)
        return response

    def put(self, payload):
        self.method = "PUT"
        response = self._make_request(payload)
        return response

    def delete(self, payload=None):
        self.method = "DELETE"
        response = self._make_request(payload)
        return response

    def _generate_auth_headers(self, payload=None):
        if not self.has_credentials:
            return {}

        date = datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S GMT")

        string_to_sign = self.method + "\n" + self.url + "\n" + date

        if self.method != "GET":
            body_string = dumps(payload).encode("utf-8")
            body_string = md5(body_string).digest()
            body_string = str(b64encode(body_string), "utf-8")

            string_to_sign = string_to_sign + "\n" + body_string

        decoded_key = b64decode(self.spektrix_api_key)
        string_to_sign = string_to_sign.encode("utf-8")

        signature = hmac.new(decoded_key, string_to_sign, sha1).digest()
        signature = b64encode(signature).decode("utf-8")

        headers = {}
        headers["Date"] = date
        headers["Authorization"] = "SpektrixAPI3 {}:{}".format(
            self.spektrix_api_user, signature
        )

        return headers

    def _make_request(self, payload=None):
        if payload == None:
            # Spektrix assumes any non-GET request must have a body.
            payload = {}
        else:
            payload = [payload]

        headers = self._generate_auth_headers(payload)

        session = Session()
        req = Request(method=self.method, url=self.url, json=payload, headers=headers)

        response = session.send(req.prepare())

        response.raise_for_status()

        try:
            return response.json()
        except JSONDecodeError:
            # There is one endpoint which returns non-JSON content (instances/{}/status/detail)
            return response.content


import requests
import time as py_time
from bs4 import BeautifulSoup
import datetime as dt
import pandas as pd
import json

"""
earnings.py for all your earning needs. Includes the fetch.py module which was originally
separated.

Class:
    Earnings: meant to be the main api to interact with all the scraped data
    YahooEarningsCalendar: Yahoo earnings calendar api. Returns ticker+time only... yahoo sucks
    ZachsEarningsCalendar: Earnings calendar from zachs... Thank god for zachs
"""

class Earnings:
    """Api to interact with earnings data

    :arg path (os.path): path to the earnings.json file
    :arg data (dict): the contents of the earnings.json file

    Functions:
        update: updates the file to today
        get_dates: Gets the infomration for the dates given (list)
        effective date: returns all info for the given effective date
        all_stocks: returns all stocks as a list
        save: saves the data dict
    """
    def __init__(self, path):
        self.path = path
        with open(path, 'r') as read:
            self.data = json.load(read)

    def update(self):
        """Updates the earnings data to today"""

        last_available = dt.datetime.strptime(list(self.data.keys())[-1], '%Y-%m-%d').date()
        dates = [
            last_available + dt.timedelta(days=days)  # +1 to get to today
            for days in range(0, (dt.datetime.today().date()-last_available).days+1)
        ]
        self.get_dates(dates)

    def get_dates(self, dates: list):
        """Get all the data for the given list of dates, will overwrite duplicates"""

        for date in dates:
            print(f'fetching date {date}')
            cal = ZachsEarningsCalendar(date)
            # Will only append dates if not empty
            if not cal.earnings.empty:
                self.data.update({
                    date.strftime('%Y-%m-%d'): cal.earnings.to_dict(orient='index')
                })

    def effective_date(self, date):
        """Effective date means the date that the earnings report impacts

        I.e. if earnings call is amc on feb 2, the effective date is feb 3
        """
        try:  # Try catch incase date doesnt exist, will return empty dict
            bmo = self.data[date.strftime('%Y-%m-%d')].items()
        except KeyError:
            bmo = {}
        try:
            amc = self.data[(date - dt.timedelta(days=1)).strftime('%Y-%m-%d')].items()
        except KeyError:
            amc = {}
        output = {}
        for stock, data in bmo:
            if data['time'] == 'bmo':
                output[stock] = data
        for stock, data in amc:
            if data['time'] == 'amc':
                output[stock] = data
        return output

    def save(self):
        """Saves the data file to the given path"""

        with open(self.path, 'w') as write:
            json.dump(self.data, write, indent=4, sort_keys=True)

    def all_stocks(self):
        """List all the stocks in the earnings file"""

        stocks = {
            stock
            for date in self.data for stock in self.data[date].keys()
        }
        return stocks

class YahooEarningsCalendar:
    """Earnings date information scraped from yahoo finance

    Attributes:
        DELAY (int): delay between traversing pages
        CALL_TIME_DICT (dict): translate yahoo lingo into shortened
        date (str): date of interest
        earnings (dict): the final output of the class. A dictionary of all earnings for that date
        url (str): url to yahoo
        offset (int): offset used in the url
        num_stocks (int): number of stocks on current day
        num_pages (int): not useful, mainly used for convenience, number of pages on yahoo
    """
    DELAY = 0.5  # delay in seconds between url calls
    CALL_TIME_DICT = {
        'Time Not Supplied': 'N/A',
        'Before Market Open': 'BMO',
        'After Market Close': 'AMC',
        'TAS': 'AMC'
    }

    def __init__(self, date: object):
        self.date = date.strftime('%Y-%m-%d')
        self.earnings = {'date': self.date, 'tickers': {}}
        self.url = None
        self._soup = None
        self.offset = 0
        self.num_stocks = 0
        self.num_pages = 0
        self.run()

    def getsoup(self):
        self.url = f'https://finance.yahoo.com/calendar/earnings?day={self.date}&offset={self.offset}&size=100'
        yahoo = requests.get(self.url)
        if yahoo.status_code != 200:
            raise ConnectionError(f'code {yahoo.status_code}')
        src = yahoo.content
        self._soup = BeautifulSoup(src, 'html.parser')

    def pages(self):
        """gets number of pages and stocks that exists on the yahoo site"""

        self.getsoup()  # get soup to extract data
        results = self._soup.find('span', {'class': 'Mstart(15px) Fw(500) Fz(s)'}).text
        self.num_stocks = int(results[results.index('of') + 3: -len('results')])
        self.num_pages = int((self.num_stocks - 1) / 100)

    def filter_data(self):
        """Filters soup data and returns dict {ticker: BMO, ticker2: AMC, etc...}"""

        # Results white and results_alt are due to the fact that yahoo chart splits into grey and white
        # gets all the soup data from white lines
        results_white = self._soup.findAll('tr', {
            'class': 'simpTblRow Bgc($extraLightBlue):h BdB Bdbc($finLightGrayAlt) Bdbc($tableBorderBlue):h H(32px) '
                     'Bgc(white)'})

        # gets all the soup data from alternate (grey) lines
        results_alt = self._soup.findAll('tr', {
            'class': 'simpTblRow Bgc($extraLightBlue):h BdB Bdbc($finLightGrayAlt) Bdbc($tableBorderBlue):h H(32px) '
                     'Bgc($altRowColor)'})

        # filters results_white data into the main dict
        for i in results_white:
            ticker = i.find('a', {'class', 'Fw(600)'}).text
            time = i.find('td', {'class', 'Va(m) Ta(end) Pstart(15px) W(20%) Fz(s)'}).text
            time = self.CALL_TIME_DICT[time]
            self.earnings['tickers'][ticker] = time

        # filters results_alt data into the main dict
        for i in results_alt:
            ticker = i.find('a', {'class', 'Fw(600)'}).text
            time = i.find('td', {'class', 'Va(m) Ta(end) Pstart(15px) W(20%) Fz(s)'}).text
            time = self.CALL_TIME_DICT[time]
            self.earnings['tickers'][ticker] = time

    def run(self):
        """Bread and budder, generates the earnings list"""

        self.pages()
        self.filter_data()
        for i in range(1, self.num_pages + 1):
            py_time.sleep(self.DELAY)
            self.offset = 100 * i
            self.getsoup()
            self.filter_data()

    def save_as_json(self, path, indent=4):
        with open(path, 'wb') as save:
            json.dump(self.earnings, save, indent=indent)

class ZachsEarningsCalendar:
    """Zachs Earnings Calendar

    Attributes:
        raw_data: raw data from zachs as a dict
        earnings: earnings data from zachs as a dataframe
        timestamp: timespamp of the input dated
        date: current date
        url: url to the data
    """
    HEADERS = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                             'Chrome/79.0.3945.130 Safari/537.36'}

    def __init__(self, date: dt.date):
        self.raw_data = None
        self.date = date
        self.earnings = None
        # dt.time(1,0) is the time zachs wants for the url. NOTE **1AM IS EST TIME**
        self.timestamp = int(dt.datetime.combine(date, dt.time(1, 0)).timestamp())
        self.url = 'https://www.zacks.com/includes/classes/z2_class_calendarfunctions_data.php?calltype=' \
                   f'eventscal&date={self.timestamp}&type=1'
        self.get_earnings()

    def get_earnings(self):
        """Gets and returns the data from zachs earnings calendar"""

        def parse_eps(text):  # EPS may not exist so cant always be a float
            try:
                return float(text)
            except ValueError:
                return text

        # Get raw data as dict
        data = requests.get(self.url, headers=self.HEADERS)
        if data.status_code != 200:
            raise ConnectionError(f'code {data.status_code}')
        soup = BeautifulSoup(data.content, 'html.parser')
        self.raw_data = json.loads(soup.text)['data']

        # To dataframe
        to_frame = {i[0]: {
            'time': i[3],
            'estimate': parse_eps(i[4]),
            'reported': parse_eps(i[5])
        } for i in self.raw_data}
        self.earnings = pd.DataFrame.from_dict(to_frame, orient='index')

if __name__ == '__main__':
    zachs = ZachsEarningsCalendar(dt.date(2020, 2, 4))
    zachs.get_earnings()
    print(zachs.earnings)


from __future__ import absolute_import, division, print_function

'''
Function: receive pkts, run act detection and send to next hop

Input: GRPC packet stream, packet meta:
        a list of {'box':[x0,y0,x1,y1], # in pixel position
                    'id': object track id,
                    'label': name of the object in str}

Internal data: ServerPkt (in server/server_packet.py)

Outputs: serialized GRPC packet (defined in network/data_packet)
        packet meta: a list of {'box':[x0,y0,x1,y1], # in pixel position
                                'id': object track id, (re-ided)
                                'label': name of the object in str}
'''

import sys
import os
import logging
from time import time, sleep
from multiprocessing import Process
from threading import Thread

import config.const_act as const
from server.server_packet_manager import ServerPktManager
from server.action_spatial import SpatialActDetector
from server.action_nn import NNActDetector
from server.action_comp import CompActDetector
from network.data_writer import DataWriter
from network.socket_client import NetClient
from network.socket_server import NetServer
from network.utils import Q

"""
Create result folder
"""
RES_FOLDER = 'res/{}/'.format(os.path.basename(__file__).split('.py')[0])
if not os.path.exists(RES_FOLDER):
    os.makedirs(RES_FOLDER)
print('Output to {}'.format(RES_FOLDER))

"""
Main function
"""
def main(running):
    server = NetServer(
        name='act',
        address=const.LOCAL_ADDR,
        port=const.LOCAL_PORT,
        buffer_size=const.QUEUE_SIZE,
    )
    server_proc = Process(target=server.run)
    server_proc.start()

    client = NetClient(
        client_name='act',
        server_addr=const.SERVER_ADDR,
        buffer_size=const.QUEUE_SIZE,
    )
    if const.UPLOAD_DATA:
        client_proc = Process(target=client.run)
        client_proc.start()

    data_savers = {}

    tube_queue = Q(const.QUEUE_SIZE)
    act_spatial_queue = Q(const.QUEUE_SIZE)
    act_nn_queue = Q(const.QUEUE_SIZE)
    act_comp_queue = Q(const.QUEUE_SIZE)
    filter_queue = Q(const.QUEUE_SIZE)

    tm = ServerPktManager(
        in_queue=server.data_queue,
        out_queue=tube_queue,
        track_list=const.TRACK_LABELS,
        overlap_list=const.ATTACH_LABELS,
    )
    tm_proc = Thread(target=tm.run)
    tm_proc.deamon = True
    tm_proc.start()

    spatial_act = SpatialActDetector(
        in_queue = tube_queue,
        out_queue=act_spatial_queue,
    )
    spatial_proc = Process(target=spatial_act.run)
    spatial_proc.deamon = True
    spatial_proc.start()

    nn_act = NNActDetector(
        in_queue=act_spatial_queue,
        out_queue=act_nn_queue,
        model_path=const.NN_ACT_MODEL_PATH,
        batch_size=const.NN_BATCH,
        tube_size=const.TUBE_SIZE,
        filter_queue=filter_queue,
    )
    nn_act_proc = Process(target=nn_act.run)
    nn_act_proc.deamon = True
    nn_act_proc.start()

    comp_act = CompActDetector(
        in_queue=act_nn_queue,
        out_queue=act_comp_queue,
        filter_queue=filter_queue,
    )
    comp_act_proc = Process(target=comp_act.run)
    comp_act_proc.deamon = True
    comp_act_proc.start()

    out_queue = act_comp_queue
    print('server starts')

    while running[0]:
        server_pkt = out_queue.read()
        if server_pkt is None:
            sleep(0.01)
            continue

        cid = server_pkt.cam_id
        if cid not in data_savers:
            data_savers[cid] = DataWriter(file_path=RES_FOLDER+'{}.npy'.format(cid))
            print('creat data_saver for video {}'.format(cid))

        logging.info("Cam-{}, Frame-{}, Acts-{}".format(
            server_pkt.cam_id,
            server_pkt.get_first_frame_id(),
            server_pkt.get_action_info()
        ))
        logging.info("--------------------------------")

        data_pkts = server_pkt.to_data_pkts()
        for p in data_pkts:
            if const.UPLOAD_DATA:
                client.send_data(p)

            if const.SAVE_DATA:
                data_savers[cid].save_data(frame_id=p.frame_id, meta=p.meta)

    if const.SAVE_DATA:
        for cid in data_savers:
            data_savers[cid].save_to_file()

    server.stop()
    print("server finished!")

if __name__ == '__main__':
    logging.basicConfig(filename='act_debug.log',
                        format='%(asctime)s %(message)s',
                        datefmt='%I:%M:%S ',
                        filemode='w',
                        level=logging.DEBUG)

    running = [True]
    th = Thread(target=main, args=(running,))
    th.start()
    while True:
        try:
            sleep(10)
        except (KeyboardInterrupt, SystemExit):
            running[0] = False
            break
    print('done')