import json
from django.test import TestCase, Client
from django.urls import reverse
from message.factories import SequenceMessagesFactory
from message.models import Message
from users.models import User
from chats.models import Chat, Member

class MessageTest(TestCase):

    def setUp(self):
        self.client = Client()

        self.first_user = User.objects.create(username='Test User N1', nick='greatNickname')
        self.second_user = User.objects.create(username='Test User N2', name='greatname')

        self.client.force_login(self.first_user)

        self.chat = Chat.objects.create(is_group_chat=False, topic='test topic')
        self.first_member = Member.objects.create(user_id=self.first_user.id, chat_id=self.chat.id, new_messages=0)
        self.second_member = Member.objects.create(user_id=self.second_user.id, chat_id=self.chat.id, new_messages=0)

        self.first_message = SequenceMessagesFactory.build(chat_id=self.chat.id, user_id=self.first_user.id)
        self.first_message.save()
        self.second_message = SequenceMessagesFactory.build(chat_id=self.chat.id, user_id=self.first_user.id)
        self.second_message.save()

    def test_read_message(self):
        response = self.client.post(reverse('read message'), {'user': self.first_user.id, 'chat': self.chat.id})
        self.assertTrue(response.status_code == 200)
        content = json.loads(response.content)
        self.assertGreaterEqual(content['data']['last read message'], 1)

    def test_send_message(self):
        response = self.client.post(reverse('send message'), {'user': self.first_user.id, 'chat': self.chat.id, 'content': 'test send message'})
        self.assertTrue(response.status_code == 200)
        content = json.loads(response.content)
        self.assertEqual(content['msg'], 'Сообщение отправлено')

    def test_get_message_list(self):
        response = self.client.get(reverse('messages', kwargs={'chat_id': self.chat.id}))
        self.assertTrue(response.status_code == 200)
        self.assertRaises(UnicodeDecodeError)
        self.assertJSONNotEqual(response.content, {'messages': []})
        content = json.loads(response.content)
        self.assertEqual(len(content['messages']), 2)

    def tearDown(self):
        print('messages test done')


import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
import time

hidden_sz = 32
d_grad_steps = 1
batch = 128
n_mix = 2

def discriminator(x, keep, reuse):
	with tf.variable_scope("discriminator", reuse=reuse):
		d_fc1 = tf.layers.dense(x,  hidden_sz, activation=tf.nn.relu)
		d_dropout = tf.nn.dropout(d_fc1, keep)
		d_fc2 = tf.layers.dense(d_dropout, hidden_sz, activation=tf.nn.relu)
		d_out = tf.sigmoid(tf.layers.dense(d_fc2, 1))
		return d_out, keep
def main():

	input_shape = [2]
	latent_shape = [2]

	with tf.variable_scope("generator"):
		g_in = tf.placeholder(dtype=tf.float32, shape=[None]+latent_shape,
			name="generator_latent")
		g_fc1 = tf.layers.dense(g_in,  hidden_sz, activation=tf.nn.relu)
		g_fc2 = tf.layers.dense(g_fc1, hidden_sz, activation=tf.nn.relu)
		g_out = tf.layers.dense(g_fc2, input_shape[0])

	d_keep = tf.placeholder(dtype=tf.float32, shape=())
	d_in_real = tf.placeholder(dtype=tf.float32, shape=[None]+input_shape,
		name="discriminator_real_input")
	d_real, d_keep = discriminator(d_in_real, d_keep, reuse=False)

	d_fake, _ = discriminator(g_out, d_keep, reuse=True)

	with tf.variable_scope("loss"):
		d_loss = -tf.reduce_mean(tf.log(d_real) + tf.log(1.0 - d_fake))
		g_loss = tf.reduce_mean(tf.log(1.0 - d_fake))

	vars = tf.trainable_variables()

	d_adam = tf.train.AdamOptimizer()
	d_step = tf.Variable(0, name="d_step", trainable=False)
	d_optimize = d_adam.minimize(d_loss, global_step=d_step,
		var_list=[v for v in vars if v.name.startswith("disc")])

	g_adam = tf.train.AdamOptimizer()
	g_step = tf.Variable(0, name="g_step", trainable=False)
	g_optimize = g_adam.minimize(g_loss, global_step=g_step,
		var_list=[v for v in vars if v.name.startswith("gen")])

	def random_gaussian(dim):
		randn = np.random.normal
		mean = 3*randn(size=dim)
		#cov_chol = randn(size=(dim,dim))
		#cov = np.matmul(cov_chol.T, cov_chol)
		cov = 0.3 * np.diag(1 + 2 * np.random.uniform(size=2))
		return mean, cov

	gaussians = [random_gaussian(input_shape[0]) for _ in range(n_mix)]

	#tf_gaussians = [tf.distributions.Normal(loc=m, scale=np.diag(c).flat)
		#for m, c in gaussians]
	#density_in = tf.placeholder(dtype=tf.float32, shape=[None]+input_shape)
	#true_density = tf.reduce_sum([g.prob(density_in) for g in tf_gaussians]) / float(n_mix)

	def sample(N):
		n = N // len(gaussians)
		assert n * len(gaussians) == N
		return np.vstack(
			np.random.multivariate_normal(mu, cov, size=n)
				for mu, cov in gaussians)

	sess = tf.Session()
	sess.run(tf.global_variables_initializer())

	def distmap():
		plt.clf()
		plt.hold(True)

		res = 64
		lim = 10
		t = np.linspace(-lim, lim, 64)
		x, y = np.meshgrid(t,t)
		mesh = np.float32(np.c_[x.flat, y.flat])

		#dens_true = sess.run(true_density, feed_dict={density_in: mesh})
		#dsurface = sess.run(d_real, feed_dict={d_in_real: mesh, d_keep: 1.0})
		#dsurface = dsurface.reshape(x.shape)

		r_sample = sample(n_mix * 10000)
		r_hist, _, _ = np.histogram2d(r_sample[:,0], r_sample[:,1],
			bins=res, range=[[-lim, lim], [-lim, lim]])

		g_latent = np.random.normal(size=[10000] + latent_shape)
		g_sample = sess.run(g_out, feed_dict={g_in: g_latent})
		g_hist, _, _ = np.histogram2d(g_sample[:,0], g_sample[:,1],
			bins=res, range=[[-lim, lim], [-lim, lim]])

		def normalize(x):
			m = np.max(x.flat)
			if m > 0:
				return x / m
			return x

		img = np.zeros((res,res,3))
		img[:,:,0] = normalize(r_hist)
		img[:,:,1] = normalize(g_hist)

		plt.imshow(img, extent=(-lim, lim, -lim, lim))

	n_batches = 40000
	for b in range(n_batches):
		# train the discriminator
		nstep = 100 if b == 0 else d_grad_steps
		for _ in range(nstep):
			# generate real data
			r_sample = sample(batch)

			# sample from generator
			g_latent = np.random.normal(size=[batch] + latent_shape)

			# train the discriminator
			_, d_loss_value = sess.run([d_optimize, d_loss],
				feed_dict={d_in_real: r_sample, g_in: g_latent, d_keep: 0.5})

		# train the generator
		g_latent = np.random.normal(size=[batch] + latent_shape)
		_, g_sample, g_loss_value = sess.run([g_optimize, g_out, g_loss],
			feed_dict={g_in: g_latent, d_keep: 1.0})

		if False and b % 100 == 0:
			plt.clf()
			plt.hold(True)
			lim = 10
			t = np.linspace(-lim, lim, 64)
			x, y = np.meshgrid(t,t)
			mesh = np.c_[x.flat, y.flat]
			dsurface = sess.run(d_real, feed_dict={d_in_real: mesh, d_keep: 1.0})
			dsurface = dsurface.reshape(x.shape)
			plt.imshow(dsurface, extent=(-lim, lim, -lim, lim), alpha=0.4)
			plt.scatter(r_sample[:,0], r_sample[:,1], color=(0.7, 0.1, 0.1))
			plt.scatter(g_sample[:,0], g_sample[:,1], color=(0.1, 0.6, 0.3))
			plt.show(block=False)
			plt.xlim([-lim, lim])
			plt.ylim([-lim, lim])
			plt.pause(0.001)

		if b % 100 == 0:
			distmap()
			plt.show(block=False)
			plt.pause(0.001)

	plt.show(block=True)

main()


from tkinter import *

root = Tk()
root.state('zoomed')
root.resizable(False,False)
root.title('SPC Controller')
root.config(bg='grey')
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()

# create all of the main containers
center = Frame(root, width=50, height=40)
center2 = Frame(root, width=50, height=40)
btm_frame2 = Frame(root, bg='#036360', height=30)

# layout all of the main containers
root.grid_rowconfigure(1, weight=1)
root.grid_columnconfigure(0, weight=1)

center.grid(row=0, sticky="nsew" )
center2.grid(row=1, sticky="nsew")
btm_frame2.grid(row=2, sticky="nsew")

# create the center widgets
center.grid_rowconfigure(0, weight=1)

ctr_left = Frame(center, bg='white', width=(screen_width/3.5), height=((screen_height-30)/2))
label1 = Text(ctr_left,bg='white',height=1)
label1.pack()
ctr_left.grid(row=0, column=0, sticky="nsew")

ctr_left2 = Frame(center2, bg='white', width=(screen_width/3.5), height=((screen_height-30)/2), padx=0, pady=0)
label1 = Label(ctr_left2,bg='white', text="Width").place(x=50,y=50)
ctr_left2.grid(row=1, column=0, sticky="nsew")

ctr_right = Frame(center, bg='#212121', width=(screen_width/1.42), height=((screen_height-30)/2))
label2 = Label(ctr_right,bg='white', text="Width").place(x=50,y=50)
ctr_right.grid(row=0, column=2, sticky="nsew")

ctr_right2 = Frame(center2, bg='#212121', width=(screen_width/1.42), height=((screen_height-30)/2))
label3 = Label(ctr_right2,bg='white', text="Width").place(x=50,y=50)
ctr_right2.grid(row=1, column=2, sticky="nsew")

# frame_top = Frame(root, width=400, height=250)
# frame_top.pack(side="top", expand=1, fill="both")

# ctr_bottom_frame = Frame(ctr_left_Bottom)
# bottomlabel = Label(ctr_bottom_frame,text="hello")
# bottomlabe2 = Label(ctr_bottom_frame,text="hello")
# bottomlabe3 = Label(ctr_bottom_frame,text="hello")
# bottomlabe4 = Label(ctr_bottom_frame,text="hello")
# bottomlabel.grid(row=0, column=0)
# bottomlabe2.grid(row=0, column=1)
# bottomlabe3.grid(row=1, column=0)
# bottomlabe4.grid(row=1, column=1)
# ctr_bottom_frame.bind('<Button-1>', lambda e: box("2"))
# ctr_bottom_frame.pack(fill='x')

#  labelDynamic1=Label(ctr_left_Bottom,text="Hello \t\t Hello \n abcd \n abcd",borderwidth=1,relief="solid",pady=1)
#     labelDynamic1.bind('<Button-1>', lambda e: box(labelDynamic1))
#     labelDynamic2=Label(ctr_left_Bottom,text="Hello \t\t Hello \n abcd \n abcd",borderwidth=1,relief="solid",pady=1)
#     labelDynamic2.bind('<Button-1>', lambda e: box(labelDynamic2))
#     labelDynamic1.pack(fill='x')
#     labelDynamic2.pack(fill='x')

# mainFrame= Frame(ctr_left_Bottom)
# mainFrame.pack(fill=BOTH,expand=1)
# my_canvas = Canvas(mainFrame)
# my_canvas.pack(side=LEFT, fill=BOTH, expand=1)
# myscrollbar=Scrollbar(mainFrame, orient="vertical", command=my_canvas.yview)
# myscrollbar.pack(side=RIGHT,fill=Y)
# my_canvas.configure(yscrollcommand=myscrollbar.set)
# my_canvas.bind('<Configure>', lambda e: my_canvas.configure(scrollregion = my_canvas.bbox("all")))
# second_frame = Frame(my_canvas)
# for i in range(20):
#     Label(second_frame,text="hello").pack(fill='x')
# my_canvas.create_window((0,0), window=second_frame, anchor="nw")

# f = Figure(figsize=(4,4), dpi=100)
#         a = f.add_subplot(111)
#         a.plot([1,2,3,4,5,6,7,8],[5,6,1,3,8,9,3,5])
#         a.set_title("fig" + str(i))
#         canvas = FigureCanvasTkAgg(f,master=ctr_right)
#         canvas.draw()
#         canvas.get_tk_widget().pack(side=TOP, fill=X, expand=1)
#         scrollable_frame.window_create(END, window=canvas.get_tk_widget())
#         scrollable_frame.insert(END, '\n')

root.mainloop()


#!/usr/bin/env python
# coding: utf-8

# In[2]:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
from sklearn.neighbors import KNeighborsRegressor
import numpy as np
from sklearn import metrics
from sklearn import neighbors
from sklearn.metrics import mean_squared_error
from math import sqrt
import statsmodels.api as sm
from scipy.stats import zscore
from sklearn.linear_model import BayesianRidge
from sklearn.linear_model import Lasso

# # Importing Data

# In[47]:

data = pd.read_csv(r"C:\Users\serka\Desktop\YTÜ\YTÜ 3-2\proje\notCodeSmell_merged.csv")
data

# # Removing Missing Values and Some Features

# In[48]:

data = data.dropna()
data = data.drop(["JIRA_KEY","HATA_KAYDI_OZET","Unnamed: 0","securityRating","reliabilityRating","Unnamed: 0.1", "KLOC_EFOR_y","ESTIMATED_EFOR_y","faultFixingCommitHash","effort_y","confirmedIssues","nloc","complexity","effort_x","linesAdded","linesRemoved"],axis=1)
data = data.drop_duplicates()
data = data.reset_index(drop=True)

# In[49]:

data

# # Dividing Real Effort and Estimated Effort and Plotting Our Formula

# In[36]:

div_lines = data["KLOC_EFOR_x"]/data["ESTIMATED_EFOR_x"]
data["bölüm"]=div_lines

# In[37]:

data["bölüm"].plot()

# In[39]:

print(data['bölüm'].skew())
data['bölüm'].describe()

# In[40]:

data_plot = pd.DataFrame()
data_plot["KLOC_EFOR"] = data["KLOC_EFOR_x"]
data_plot["ESTIMATED_EFOR"] = data["ESTIMATED_EFOR_x"]

# In[41]:

data_plot

# In[23]:

print(data_plot['ESTIMATED_EFOR'].skew())
data_plot['ESTIMATED_EFOR'].describe()

# In[43]:

data_plot = data_plot[data_plot["ESTIMATED_EFOR"]<4028]
data_plot = data_plot[data_plot["ESTIMATED_EFOR"]>269]

# In[44]:

lines = data_plot.plot.line()

# In[46]:

r2_score(data["KLOC_EFOR_x"], data["ESTIMATED_EFOR_x"])

# # Train Test Split

# In[50]:

x = data.drop(["KLOC_EFOR_x"],axis=1)
y = data["KLOC_EFOR_x"]

# In[51]:

X_train, X_test, y_train, y_test = train_test_split(x, y,test_size=0.3)

# In[52]:

y_train

# # Corelation Matrix

# In[53]:

plt.figure(figsize=(20,20))
cor = X_train.corr()
sns.heatmap(cor, annot=True, cmap=plt.cm.CMRmap_r)
plt.show()

# # Creating Datasets of Different Correlation Levels

# In[152]:

def correlation(dataset, threshold):
    col_corr = set()  # Set of all the names of correlated columns
    corr_matrix = dataset.corr()
    for i in range(len(corr_matrix.columns)):
        for j in range(i):
            if abs(corr_matrix.iloc[i, j]) > threshold: # we are interested in absolute coeff value
                colname = corr_matrix.columns[i]  # getting the name of column
                col_corr.add(colname)
    return col_corr

# In[153]:

corr_features = correlation(X_train, 0.3)
KLOC_data_clean_0_3_train = X_train.drop(corr_features,axis=1)
KLOC_data_clean_0_3_test = X_test.drop(corr_features,axis=1)
KLOC_data_clean_0_3_train

# In[154]:

corr_features = correlation(X_train, 0.4)
KLOC_data_clean_0_4_train = X_train.drop(corr_features,axis=1)
KLOC_data_clean_0_4_test = X_test.drop(corr_features,axis=1)
KLOC_data_clean_0_4_train

# In[156]:

corr_features = correlation(X_train, 0.55)
KLOC_data_clean_0_5_train = X_train.drop(corr_features,axis=1)
KLOC_data_clean_0_5_test = X_test.drop(corr_features,axis=1)
KLOC_data_clean_0_5_train

# In[159]:

corr_features = correlation(X_train, 0.7)
KLOC_data_clean_0_6_train = X_train.drop(corr_features,axis=1)
KLOC_data_clean_0_6_test = X_test.drop(corr_features,axis=1)
KLOC_data_clean_0_6_train

# In[160]:

corr_features = correlation(X_train, 0.8)
KLOC_data_clean_0_7_train = X_train.drop(corr_features,axis=1)
KLOC_data_clean_0_7_test = X_test.drop(corr_features,axis=1)
KLOC_data_clean_0_7_train

# # Normalization

# In[18]:

scaler = MinMaxScaler(feature_range=(0, 1))

x_train_scaled = scaler.fit_transform(KLOC_data_clean_0_3_train)
KLOC_data_clean_0_3_train_scaled = pd.DataFrame(x_train_scaled)
x_test_scaled = scaler.fit_transform(KLOC_data_clean_0_3_test)
KLOC_data_clean_0_3_test_scaled = pd.DataFrame(x_test_scaled)

x_train_scaled = scaler.fit_transform(KLOC_data_clean_0_4_train)
KLOC_data_clean_0_4_train_scaled = pd.DataFrame(x_train_scaled)
x_test_scaled = scaler.fit_transform(KLOC_data_clean_0_4_test)
KLOC_data_clean_0_4_test_scaled = pd.DataFrame(x_test_scaled)

x_train_scaled = scaler.fit_transform(KLOC_data_clean_0_5_train)
KLOC_data_clean_0_5_train_scaled = pd.DataFrame(x_train_scaled)
x_test_scaled = scaler.fit_transform(KLOC_data_clean_0_5_test)
KLOC_data_clean_0_5_test_scaled = pd.DataFrame(x_test_scaled)

x_train_scaled = scaler.fit_transform(KLOC_data_clean_0_6_train)
KLOC_data_clean_0_6_train_scaled = pd.DataFrame(x_train_scaled)
x_test_scaled = scaler.fit_transform(KLOC_data_clean_0_6_test)
KLOC_data_clean_0_6_test_scaled = pd.DataFrame(x_test_scaled)

x_train_scaled = scaler.fit_transform(KLOC_data_clean_0_7_train)
KLOC_data_clean_0_7_train_scaled = pd.DataFrame(x_train_scaled)
x_test_scaled = scaler.fit_transform(KLOC_data_clean_0_7_test)
KLOC_data_clean_0_7_test_scaled = pd.DataFrame(x_test_scaled)
KLOC_data_clean_0_3_train_scaled

# # LinearRegression

# In[161]:

reg=LinearRegression()

# In[162]:

reg.fit(KLOC_data_clean_0_3_train,y_train)
y_pred=reg.predict(KLOC_data_clean_0_3_test)
plt.figure(figsize=(15,10))
plt.scatter(y_test,y_pred)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.title('corr < 0.3')
r2_score(y_test,y_pred)

# In[163]:

reg.fit(KLOC_data_clean_0_4_train,y_train)
y_pred=reg.predict(KLOC_data_clean_0_4_test)
plt.figure(figsize=(15,10))
plt.scatter(y_test,y_pred)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.title('corr < 0.5')
r2_score(y_test,y_pred)

# In[164]:

reg.fit(KLOC_data_clean_0_5_train,y_train)
y_pred=reg.predict(KLOC_data_clean_0_5_test)
plt.figure(figsize=(15,10))
plt.scatter(y_test,y_pred)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.title('corr < 0.7')
r2_score(y_test,y_pred)

# In[165]:

reg.fit(KLOC_data_clean_0_6_train,y_train)
y_pred=reg.predict(KLOC_data_clean_0_6_test)
plt.figure(figsize=(15,10))
plt.scatter(y_test,y_pred)
plt.xlabel('actual')
plt.ylabel('predicted')
plt.title('corr < 0.9')
r2_score(y_test,y_pred)

# In[166]:

reg.fit(KLOC_data_clean_0_7_train,y_train)
y_pred=reg.predict(KLOC_data_clean_0_7_test)
plt.figure(figsize=(15,10))
plt.scatter(y_test,y_pred)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.title('corr < 0.95')
r2_score(y_test,y_pred)

# In[172]:

reg.coef_
pd.DataFrame(reg.coef_,
             KLOC_data_clean_0_7_train.columns,
             columns=['coef'])\
            .sort_values(by='coef', ascending=False)


import time

from tensorflow.python.eager import monitoring
from tensorflow.python.eager import test
from tensorflow.python.framework import test_util

class MonitoringTest(test_util.TensorFlowTestCase):

  def test_counter(self):
    counter = monitoring.Counter('test/counter', 'test counter')
    counter.get_cell().increase_by(1)
    self.assertEqual(counter.get_cell().value(), 1)
    counter.get_cell().increase_by(5)
    self.assertEqual(counter.get_cell().value(), 6)

  def test_multiple_counters(self):
    counter1 = monitoring.Counter('test/counter1', 'test counter', 'label1')
    counter1.get_cell('foo').increase_by(1)
    self.assertEqual(counter1.get_cell('foo').value(), 1)
    counter2 = monitoring.Counter('test/counter2', 'test counter', 'label1',
                                  'label2')
    counter2.get_cell('foo', 'bar').increase_by(5)
    self.assertEqual(counter2.get_cell('foo', 'bar').value(), 5)

  def test_same_counter(self):
    counter1 = monitoring.Counter('test/same_counter', 'test counter')  # pylint: disable=unused-variable
    counter2 = monitoring.Counter('test/same_counter', 'test counter')  # pylint: disable=unused-variable

  def test_int_gauge(self):
    gauge = monitoring.IntGauge('test/gauge', 'test gauge')
    gauge.get_cell().set(1)
    self.assertEqual(gauge.get_cell().value(), 1)
    gauge.get_cell().set(5)
    self.assertEqual(gauge.get_cell().value(), 5)

    gauge1 = monitoring.IntGauge('test/gauge1', 'test gauge1', 'label1')
    gauge1.get_cell('foo').set(2)
    self.assertEqual(gauge1.get_cell('foo').value(), 2)

  def test_string_gauge(self):
    gauge = monitoring.StringGauge('test/gauge', 'test gauge')
    gauge.get_cell().set('left')
    self.assertEqual(gauge.get_cell().value(), 'left')
    gauge.get_cell().set('right')
    self.assertEqual(gauge.get_cell().value(), 'right')

    gauge1 = monitoring.StringGauge('test/gauge1', 'test gauge1', 'label1')
    gauge1.get_cell('foo').set('start')
    self.assertEqual(gauge1.get_cell('foo').value(), 'start')

  def test_bool_gauge(self):
    gauge = monitoring.BoolGauge('test/gauge', 'test gauge')
    gauge.get_cell().set(True)
    self.assertTrue(gauge.get_cell().value())
    gauge.get_cell().set(False)
    self.assertFalse(gauge.get_cell().value())

    gauge1 = monitoring.BoolGauge('test/gauge1', 'test gauge1', 'label1')
    gauge1.get_cell('foo').set(True)
    self.assertTrue(gauge1.get_cell('foo').value())

  def test_sampler(self):
    buckets = monitoring.ExponentialBuckets(1.0, 2.0, 2)
    sampler = monitoring.Sampler('test/sampler', buckets, 'test sampler')
    sampler.get_cell().add(1.0)
    sampler.get_cell().add(5.0)
    histogram_proto = sampler.get_cell().value()
    self.assertEqual(histogram_proto.min, 1.0)
    self.assertEqual(histogram_proto.num, 2.0)
    self.assertEqual(histogram_proto.sum, 6.0)

    sampler1 = monitoring.Sampler('test/sampler1', buckets, 'test sampler',
                                  'label1')
    sampler1.get_cell('foo').add(2.0)
    sampler1.get_cell('foo').add(4.0)
    sampler1.get_cell('bar').add(8.0)
    histogram_proto1 = sampler1.get_cell('foo').value()
    self.assertEqual(histogram_proto1.max, 4.0)
    self.assertEqual(histogram_proto1.num, 2.0)
    self.assertEqual(histogram_proto1.sum, 6.0)

  def test_context_manager(self):
    counter = monitoring.Counter('test/ctxmgr', 'test context manager', 'slot')
    with monitoring.MonitoredTimer(counter.get_cell('long')):
      time.sleep(0.01)
      with monitoring.MonitoredTimer(counter.get_cell('short')):
        time.sleep(0.01)
    self.assertGreater(
        counter.get_cell('long').value(), counter.get_cell('short').value()
    )

  def test_monitored_timer_tracker(self):
    counter = monitoring.Counter('test/ctxmgr', 'test context manager', 'slot')
    counter2 = monitoring.Counter('test/ctxmgr2', 'slot')
    with monitoring.MonitoredTimer(counter.get_cell('long'), 'counter'):
      time.sleep(0.01)
      self.assertIn('counter', monitoring.MonitoredTimerSections)
      with monitoring.MonitoredTimer(counter2.get_cell(), 'counter2'):
        time.sleep(0.01)
        self.assertIn('counter', monitoring.MonitoredTimerSections)
        self.assertIn('counter2', monitoring.MonitoredTimerSections)
        with monitoring.MonitoredTimer(counter.get_cell('long'), 'counter'):
          time.sleep(0.01)
      self.assertNotIn('counter2', monitoring.MonitoredTimerSections)
    self.assertGreater(
        counter.get_cell('long').value(), counter.get_cell('short').value()
    )
    self.assertGreater(counter2.get_cell().value(), 0)

  def test_repetitive_monitored_timer(self):
    counter = monitoring.Counter('test/ctxmgr', 'test context manager')
    with monitoring.MonitoredTimer(
        counter.get_cell(),
        monitored_section_name='action1',
        avoid_repetitive_counting=True,
    ):
      time.sleep(1)
      with monitoring.MonitoredTimer(
          counter.get_cell(),
          monitored_section_name='action1',
          avoid_repetitive_counting=True,
      ):
        time.sleep(1)

      # The inner section is not timed.
      self.assertEqual(counter.get_cell().value(), 0)

    self.assertGreater(counter.get_cell().value(), 0)

  def test_function_decorator(self):
    counter = monitoring.Counter('test/funcdecorator', 'test func decorator')

    @monitoring.monitored_timer(counter.get_cell())
    def timed_function(seconds):
      time.sleep(seconds)

    timed_function(0.001)
    self.assertGreater(counter.get_cell().value(), 1000)

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


import requests
import bs4

class RecentEarthquake:
    def __init__(self, url):
        self.description = 'To get the recent earthquake in Indonesia from BMKG.go.id'
        self.result = None
        self.url = url

    def ekstraksi_data(self):

        try:
            content = requests.get(self.url)
        except Exception:
            return None
        if content.status_code == 200:
            soup = bs4.BeautifulSoup(content.text, 'html.parser') #INSTANTIATION = INSTANTIASI = PENCIPTAAN OBJECT DARI CLASS

            result = soup.find('span', {'class': 'waktu'})
            result = result.text.split(', ')
            tanggal = result[0]
            waktu = result[1]

            result = soup.find('div', {'class': 'col-md-6 col-xs-6 gempabumi-detail no-padding'})
            result = result.findChildren('li')
            i = 0
            magnitudo = None
            kedalaman = None
            ls = None
            bt = None
            lokasi = None
            dirasakan = None

            for res in result:
                if i == 1:
                    magnitudo =  res.text
                elif i == 2:
                    kedalaman = res.text
                elif i == 3:
                    koordinat = res.text.split(' - ')
                    ls = koordinat[0]
                    bt = koordinat[1]
                elif i == 4:
                    lokasi = res.text
                elif i == 5:
                    dirasakan = res.text
                i = i + 1

            hasil = dict()
            hasil['tanggal'] = tanggal
            hasil['waktu'] = waktu
            hasil['magnitudo'] = magnitudo
            hasil['kedalaman'] = kedalaman
            hasil['koordinat'] = {'ls': ls, 'bt': bt}
            hasil['lokasi'] = lokasi
            hasil['dirasakan'] = dirasakan
            self.result = hasil
        else:
            return None

    def tampilkan_data(self):
        if self.result is None:
            print('Tidak bisa menemukan data gempa terkini')
            return

        print('The last earthquake based on BMKG')
        print(f"Date {self.result['tanggal']}")
        print(f"Time {self.result['waktu']}")
        print(f"Magnitude {self.result['magnitudo']}")
        print(f"Depth {self.result['kedalaman']}")
        print(f"Coordinate: {self.result['koordinat']['ls']}, {self.result['koordinat']['bt']}")
        print(f"Location {self.result['lokasi']}")
        print(f"{self.result['dirasakan']}")

    def run(self):
        self.ekstraksi_data()
        self.tampilkan_data()

if __name__ == '__main__':
    earthquake_in_indonesia = RecentEarthquake('https://bmkg.go.id')
    print('Package description', earthquake_in_indonesia.description)
    earthquake_in_indonesia.run()
    # earthquake_in_indonesia.ekstraksi_data()
    # earthquake_in_indonesia.tampilkan_data()


import numpy as np
import pandas as pd
import cryocat
from cryocat import cryomotl
from scipy.spatial.transform import Rotation as srot
from cryocat import geom
import seaborn as sns
from scipy.spatial import KDTree
import sklearn.neighbors as sn
import matplotlib.pyplot as plt

def add_occupancy(
    motl,
    output_motl=None,
    occupancy_id="geom1",
    object_id="object_id",
    feature="tomo_id",
    order_id="geom2",
):
    if isinstance(motl, str):
        motl = cryomotl.Motl(motl_path=motl)

    motl.df[occupancy_id] = motl.df.groupby([feature, object_id])[order_id].transform(
        "max"
    )

    if output_motl is not None:
        motl.write_to_emfile(output_motl)

    return motl

def get_feature_nn_indices(fm_entry, fm_exit):
    coord_entry = fm_entry.get_coordinates()
    coord_exit = fm_exit.get_coordinates()

    if coord_entry.size <= 3:
        return [], [], []

    kdt_entry = sn.KDTree(coord_entry)

    # return 2 NN for each point
    dist, idx = kdt_entry.query(coord_exit, k=2)

    # create id array to check where the NN was the same particle
    ordered_idx = np.arange(0, idx.shape[0], 1)

    # if the first NN was the same particle, return the second one; same for distances
    nn_indices = np.where(ordered_idx == idx[:, 0], idx[:, 1], idx[:, 0])
    nn_distances = np.where(ordered_idx == idx[:, 0], dist[:, 1], dist[:, 0])

    # remove duplicates: first sort in each row, then find the unique idx
    sorted_idx = np.sort(
        np.hstack(
            (ordered_idx.reshape(idx.shape[0], 1), nn_indices.reshape(idx.shape[0], 1))
        ),
        axis=1,
    )
    unique_idx = np.sort(np.unique(sorted_idx, return_index=True, axis=0)[1])

    return ordered_idx[unique_idx], nn_indices[unique_idx], nn_distances[unique_idx]

def get_rotations(df):
    angles = -df[["psi", "theta", "phi"]].values
    angles_nn = df[["phi", "theta", "psi"]].values
    angles = angles[0:-1, :]
    angles_nn = angles_nn[1:, :]

    rot_nn = srot.from_euler("zxz", angles=angles_nn, degrees=True)
    rot_to_zero = srot.from_euler("zxz", angles=angles, degrees=True)
    final_rot = rot_to_zero * rot_nn
    points_on_sphere = geom.visualize_rotations(final_rot, plot_rotations=False)

    zero_angles = np.tile([0.0, 0.0, 0.0], (angles_nn.shape[0], 1))
    zero_rot = srot.from_euler("zxz", angles=zero_angles, degrees=True)
    ang_dist = geom.angular_distance(final_rot, zero_rot)[0]

    rotated_angles = final_rot.as_euler("zxz", degrees=True)

    rot_stats = np.hstack(
        (ang_dist.reshape(ang_dist.shape[0], 1), points_on_sphere, rotated_angles)
    )

    return rot_stats

def get_chain_distances(df, pixel_size, feature):
    entry_coord = (
        df[["x", "y", "z"]].values + df[["shift_x", "shift_y", "shift_z"]].values
    ) * pixel_size
    exit_coord = df[["exit_x", "exit_y", "exit_z"]].values * pixel_size
    entry_coord = entry_coord[1:, :]
    exit_coord = exit_coord[0:-1, :]

    chain_dist = np.linalg.norm(entry_coord - exit_coord, axis=1).reshape(
        entry_coord.shape[0], 1
    )
    centered_coord = entry_coord - exit_coord

    angles = -df[["psi", "theta", "phi"]].values
    angles = angles[0:-1, :]
    rot = srot.from_euler("zxz", angles=angles, degrees=True)
    rotated_points = rot.apply(centered_coord)

    dist_stats = np.hstack(
        (
            df[feature].values[:-1].reshape(chain_dist.shape[0], 1),
            chain_dist,
            centered_coord,
            rotated_points,
        )
    )

    return dist_stats

def get_polysome_stats(motl_entry, motl_exit, pixel_size=1.0, feature="geom1"):
    if isinstance(motl_entry, str):
        motl_entry = cryomotl.Motl(motl_path=motl_entry)

    if isinstance(motl_exit, str):
        motl_exit = cryomotl.Motl(motl_path=motl_exit)

    poly_entry_df = motl_entry.df[motl_entry.df[feature] > 1].copy()
    poly_exit_df = motl_exit.df[motl_exit.df[feature] > 1].copy()

    poly_entry_df.sort_values(["tomo_id", "object_id", "geom2"], inplace=True)
    poly_exit_df.sort_values(["tomo_id", "object_id", "geom2"], inplace=True)

    poly_entry_df[["exit_x", "exit_y", "exit_z"]] = (
        poly_exit_df[["x", "y", "z"]].values
        + poly_exit_df[["shift_x", "shift_y", "shift_z"]].values
    )

    chain_dist_stats = poly_entry_df.groupby(["tomo_id", "object_id"]).apply(
        get_chain_distances, pixel_size, feature
    )
    chain_rot_stats = poly_entry_df.groupby(["tomo_id", "object_id"]).apply(
        get_rotations
    )

    chain_dist_stats = np.vstack(chain_dist_stats.values)
    chain_rot_stats = np.vstack(chain_rot_stats.values)

    stats_df = pd.DataFrame(
        np.hstack((chain_dist_stats, chain_rot_stats)),
        columns=[
            "polysome_length",
            "distance",
            "coord_x",
            "coord_y",
            "coord_z",
            "coord_rx",
            "coord_ry",
            "coord_rz",
            "angular_distance",
            "rot_x",
            "rot_y",
            "rot_z",
            "phi",
            "theta",
            "psi",
        ],
    )

    stats_df["type"] = "polysome"

    return stats_df

def get_monosome_stats(motl_entry, motl_exit, pixel_size=1.0, feature="geom1"):
    centered_coord, rotated_coord, nn_dist, ang_dst = get_nn_distances(
        motl_entry, motl_exit, pixel_size=pixel_size, monosomes_only=True
    )
    coord_rot, angles = get_nn_rotations(motl_entry, motl_exit, monosomes_only=True)

    monosome_stats = pd.DataFrame(
        np.hstack(
            (
                nn_dist.reshape((nn_dist.shape[0], 1)),
                centered_coord,
                rotated_coord,
                ang_dst.reshape((nn_dist.shape[0], 1)),
                coord_rot,
                angles,
            )
        ),
        columns=[
            "distance",
            "coord_x",
            "coord_y",
            "coord_z",
            "coord_rx",
            "coord_ry",
            "coord_rz",
            "angular_distance",
            "rot_x",
            "rot_y",
            "rot_z",
            "phi",
            "theta",
            "psi",
        ],
    )

    monosome_stats["type"] = "monosome"

    return monosome_stats

def get_nn_stats(motl_entry, motl_exit, pixel_size=1.0, feature_id="tomo_id"):
    (
        centered_coord,
        rotated_coord,
        nn_dist,
        ang_dst,
        subtomo_idx,
        subtomo_idx_nn,
    ) = get_nn_distances(
        motl_entry,
        motl_exit,
        pixel_size=pixel_size,
        feature=feature_id,
        monosomes_only=False,
    )
    coord_rot, angles = get_nn_rotations(
        motl_entry, motl_exit, feature=feature_id, monosomes_only=False
    )

    nn_stats = pd.DataFrame(
        np.hstack(
            (
                nn_dist.reshape((nn_dist.shape[0], 1)),
                centered_coord,
                rotated_coord,
                ang_dst.reshape((nn_dist.shape[0], 1)),
                coord_rot,
                angles,
                subtomo_idx.reshape((nn_dist.shape[0], 1)),
                subtomo_idx_nn.reshape((nn_dist.shape[0], 1)),
            )
        ),
        columns=[
            "distance",
            "coord_x",
            "coord_y",
            "coord_z",
            "coord_rx",
            "coord_ry",
            "coord_rz",
            "angular_distance",
            "rot_x",
            "rot_y",
            "rot_z",
            "phi",
            "theta",
            "psi",
            "subtomo_idx",
            "subtomo_nn_idx",
        ],
    )

    nn_stats["type"] = "nn"

    return nn_stats

def get_nn_distances(
    motl_entry,
    motl_exit,
    pixel_size=1.0,
    feature="tomo_id",
    monosomes_only=False,
    type_id="geom1",
):
    if isinstance(motl_entry, str):
        motl_entry = cryomotl.Motl(motl_path=motl_entry)

    if isinstance(motl_exit, str):
        motl_exit = cryomotl.Motl(motl_path=motl_exit)

    features = np.unique(motl_entry.df.loc[:, feature].values)
    centered_coord = []
    nn_dist = []
    angular_distances = []
    rotated_coord = []
    subtomo_idx = []
    subtomo_idx_nn = []

    for f in features:
        fm_entry = motl_entry.get_feature_subset(f, feature_id=feature)
        fm_exit = motl_exit.get_feature_subset(f, feature_id=feature)

        if monosomes_only:
            fm_entry = fm_entry.get_feature_subset(1, type_id)
            fm_exit = fm_exit.get_feature_subset(1, type_id)

        idx, nn_idx, dist = get_feature_nn_indices(fm_entry, fm_exit)

        if len(idx) == 0:
            continue

        # ordered_idx = np.arange(0, idx.shape[0], 1)

        coord_entry = fm_entry.get_coordinates() * pixel_size
        coord_exit = fm_exit.get_coordinates() * pixel_size

        c_coord = coord_entry[nn_idx, :] - coord_exit[idx, :]
        centered_coord.append(c_coord)
        nn_dist.append(dist * pixel_size)

        # rotations = fm_entry.get_rotations()
        all_angles = fm_entry.get_angles()
        angles = all_angles[idx, :]
        angles_nn = all_angles[nn_idx, :]
        rotations = srot.from_euler("zxz", angles=angles, degrees=True)
        rotations_nn = srot.from_euler("zxz", angles=angles_nn, degrees=True)
        angular_distances.append(geom.angular_distance(rotations, rotations_nn)[0])

        angles = -fm_entry.df[["psi", "theta", "phi"]].values
        angles = angles[idx, :]
        rot = srot.from_euler("zxz", angles=angles, degrees=True)
        rotated_coord.append(rot.apply(c_coord))
        subtomos_all = fm_entry.df["subtomo_id"].to_numpy()
        subtomo_idx_nn.append(subtomos_all[nn_idx])
        subtomo_idx.append(subtomos_all[idx])

    return (
        np.vstack(centered_coord),
        np.vstack(rotated_coord),
        np.concatenate(nn_dist),
        np.concatenate(angular_distances),
        np.concatenate(subtomo_idx),
        np.concatenate(subtomo_idx_nn),
    )

def get_nn_rotations(
    motl_entry, motl_exit, feature="tomo_id", monosomes_only=False, type_id="geom1"
):
    if isinstance(motl_entry, str):
        motl_entry = cryomotl.Motl(motl_path=motl_entry)

    if isinstance(motl_exit, str):
        motl_exit = cryomotl.Motl(motl_path=motl_exit)

    features = np.unique(motl_entry.df.loc[:, feature].values)

    nn_rotations = []

    for f in features:
        fm_entry = motl_entry.get_feature_subset(f, feature_id=feature)
        fm_exit = motl_exit.get_feature_subset(f, feature_id=feature)

        if monosomes_only:
            fm_entry = fm_entry.get_feature_subset(1, type_id)
            fm_exit = fm_exit.get_feature_subset(1, type_id)

        idx, idx_nn, _ = get_feature_nn_indices(fm_entry, fm_exit)

        if len(idx) == 0:
            continue

        angles_nn = fm_entry.get_angles()
        rot_nn = srot.from_euler("zxz", angles=angles_nn[idx_nn, :], degrees=True)

        angles_ref_to_zero = -fm_entry.get_features(["psi", "theta", "phi"])
        rot_to_zero = srot.from_euler(
            "zxz", angles=angles_ref_to_zero[idx, :], degrees=True
        )

        nn_rotations.append(rot_to_zero * rot_nn)

    nn_rotations = srot.concatenate(nn_rotations)
    points_on_sphere = geom.visualize_rotations(nn_rotations, plot_rotations=False)
    angles = nn_rotations.as_euler("zxz", degrees=True)

    return points_on_sphere, angles

def plot_nn_coord_df(
    df,
    circle_radius,
    output_name=None,
    displ_threshold=None,
    title=None,
    marker_size=20,
):
    fig, axs = plt.subplots(1, 3, figsize=(15, 5))
    axs[0].set_title("XY distribution")
    sns.scatterplot(ax=axs[0], data=df, x="coord_x", y="coord_y", s=marker_size)
    axs[1].set_title("XZ distribution")
    sns.scatterplot(ax=axs[1], data=df, x="coord_x", y="coord_z", s=marker_size)
    axs[2].set_title("YZ distribution")
    sns.scatterplot(ax=axs[2], data=df, x="coord_y", y="coord_z", s=marker_size)

    # sns.move_legend(axs[0], "upper right")
    # sns.move_legend(axs[1], "upper right")
    # sns.move_legend(axs[2], "upper right")

    circle1 = plt.Circle((0, 0), circle_radius, color="gold", alpha=0.4, fill=True)
    circle2 = plt.Circle((0, 0), circle_radius, color="gold", alpha=0.4, fill=True)
    circle3 = plt.Circle((0, 0), circle_radius, color="gold", alpha=0.4, fill=True)

    axs[0].set_aspect("equal", "box")
    axs[1].set_aspect("equal", "box")
    axs[2].set_aspect("equal", "box")

    if displ_threshold is not None:
        limits = [-displ_threshold, displ_threshold]
        axs[0].set(xlim=limits, ylim=limits)
        axs[1].set(xlim=limits, ylim=limits)
        axs[2].set(xlim=limits, ylim=limits)

    if title is not None:
        fig.suptitle(title)

    axs[0].add_patch(circle1)
    axs[1].add_patch(circle2)
    axs[2].add_patch(circle3)

    if output_name is not None:
        plt.savefig(output_name, transparent=True)

def plot_nn_rot_coord_df(
    df, output_name=None, displ_threshold=None, title=None, marker_size=20
):
    fig, axs = plt.subplots(1, 3, figsize=(15, 5))
    axs[0].set_title("XY distribution")
    sns.scatterplot(
        ax=axs[0], data=df, x="coord_rx", y="coord_ry", hue="type", s=marker_size
    )
    axs[1].set_title("XZ distribution")
    sns.scatterplot(
        ax=axs[1], data=df, x="coord_rx", y="coord_rz", hue="type", s=marker_size
    )
    axs[2].set_title("YZ distribution")
    sns.scatterplot(
        ax=axs[2], data=df, x="coord_ry", y="coord_rz", hue="type", s=marker_size
    )

    sns.move_legend(axs[0], "upper right")
    sns.move_legend(axs[1], "upper right")
    sns.move_legend(axs[2], "upper right")

    axs[0].set_aspect("equal", "box")
    axs[1].set_aspect("equal", "box")
    axs[2].set_aspect("equal", "box")

    if displ_threshold is not None:
        limits = [-displ_threshold, displ_threshold]
        axs[0].set(xlim=limits, ylim=limits)
        axs[1].set(xlim=limits, ylim=limits)
        axs[2].set(xlim=limits, ylim=limits)

    if title is not None:
        fig.suptitle(title)

    plt.tight_layout()
    if output_name is not None:
        plt.savefig(output_name, transparent=True)

def plot_nn_coord(coord, displ_threshold=None, marker_size=20):
    # if displ_threshold is not None:
    #   coord[:,0] = coord[:, (coord#[:,0] >= -displ_threshold) & (coord[:,0] <= displ_threshold) ]

    fig, axs = plt.subplots(1, 3, figsize=(15, 5))
    axs[0].set_title("XY distribution")
    axs[0].scatter(coord[:, 0], coord[:, 1], s=marker_size)
    axs[1].set_title("XZ distribution")
    axs[1].scatter(coord[:, 0], coord[:, 2], s=marker_size)
    axs[2].set_title("YZ distribution")
    axs[2].scatter(coord[:, 1], coord[:, 2], s=marker_size)

    axs[0].set_aspect("equal", "box")
    axs[1].set_aspect("equal", "box")
    axs[2].set_aspect("equal", "box")

    if displ_threshold is not None:
        limits = [-displ_threshold, displ_threshold]
        axs[0].set(xlim=limits, ylim=limits)
        axs[1].set(xlim=limits, ylim=limits)
        axs[2].set(xlim=limits, ylim=limits)

def get_class_polysome_occupancies_mdp(motl, occupancy_id="geom1"):
    u_classes = np.unique(motl.df.loc[:, "class"].values)

    class_df = pd.DataFrame(columns=["class", "ribosome_number", "chain_type"])

    for c in u_classes:
        monosomes = motl.df[
            (motl.df["class"] == c) & (motl.df[occupancy_id] == 1)
        ].shape[0]
        disomes = motl.df[(motl.df["class"] == c) & (motl.df[occupancy_id] == 2)].shape[
            0
        ]
        polysomes = motl.df[
            (motl.df["class"] == c) & (motl.df[occupancy_id] > 2)
        ].shape[0]
        new_entry = [c, monosomes, "monosomes"]
        class_df.loc[len(class_df)] = new_entry
        new_entry = [c, disomes, "disomes"]
        class_df.loc[len(class_df)] = new_entry
        new_entry = [c, polysomes, "polysomes"]
        class_df.loc[len(class_df)] = new_entry

    return class_df

def get_class_polysome_occupancies_mp(motl, occupancy_id="geom1"):
    u_classes = np.unique(motl.df.loc[:, "class"].values)

    number_of_particles = motl.df.shape[0]

    class_df = pd.DataFrame(
        columns=["class", "ribosome_number", "chain_type", "percentage"]
    )

    for c in u_classes:
        monosomes = motl.df[
            (motl.df["class"] == c) & (motl.df[occupancy_id] == 1)
        ].shape[0]
        polysomes = motl.df[
            (motl.df["class"] == c) & (motl.df[occupancy_id] > 1)
        ].shape[0]
        new_entry = [c, monosomes, "monosomes", (monosomes / number_of_particles * 100)]
        class_df.loc[len(class_df)] = new_entry
        new_entry = [c, polysomes, "polysomes", (polysomes / number_of_particles * 100)]
        class_df.loc[len(class_df)] = new_entry

    return class_df

def assign_class(
    motl_unassigned,
    motl_list,
    starting_class=1,
    dist_threshold=20,
    output_motl=None,
    unassigned_class=0,
    update_coord=False,
):
    motl = cryomotl.Motl(motl_path=motl_unassigned)

    motl.df["class"] = unassigned_class

    classified_particles = 0
    overlaps = 0
    cl = starting_class

    for m in motl_list:
        cm = cryomotl.Motl(motl_path=m)
        classified_particles += cm.df.shape[0]
        tomos = np.unique(cm.df.loc[:, "tomo_id"].values)

        for t in tomos:
            tm_coord = cm.get_coordinates(t)
            all_coord = motl.get_coordinates(t)
            tm = cm.get_feature_subset(t, return_df=True)
            tm_all = motl.get_feature_subset(t, return_df=True)

            tm_idx = np.arange(0, tm.shape[0], 1)

            kdt = KDTree(all_coord)
            dist, idx = kdt.query(tm_coord)

            th = dist < dist_threshold  # kick out particles too far away
            idx = idx[th]
            tm_idx = tm_idx[th]

            unique_idx, unique_idx_counts = np.unique(idx, return_counts=True)
            duplicates = unique_idx[unique_idx_counts > 1]

            if duplicates.size > 0:
                identical_idx = []
                for d in duplicates:
                    identical_idx.append(np.where(idx == d))
                identical_idx = np.concatenate(identical_idx).flatten()
                subtomo_idx = tm.loc[
                    tm.index[identical_idx], ["subtomo_id"]
                ].values.flatten()
                print(f"Following particles in motl {m} are identical: {subtomo_idx}")
                overlaps += np.sum(unique_idx_counts) - unique_idx_counts.size

            tm_all.loc[tm_all.index[idx], ["geom1"]] += 1
            tm_all.loc[tm_all["geom1"] > 1, ["geom2"]] = tm_all.loc[
                tm_all["geom1"] > 1, ["class"]
            ]  # store previous class in the case of overlap
            tm_all.loc[tm_all.index[idx], ["class"]] = cl

            if update_coord:
                tm_all.loc[tm_all.index[idx], ["phi", "psi", "theta"]] = tm.loc[
                    tm.index[tm_idx], ["phi", "psi", "theta"]
                ].values
                tm_all.loc[tm_all.index[idx], ["geom4", "geom5", "geom6"]] = (
                    tm.loc[tm.index[tm_idx], ["x", "y", "z"]].values
                    + tm.loc[tm.index[tm_idx], ["shift_x", "shift_y", "shift_z"]].values
                )

            motl.df.loc[motl.df["tomo_id"] == t] = tm_all

        cl += 1

    assigned_aprticles = motl.df.loc[motl.df["geom1"] > 0].shape[0]
    print(
        f"Particles in classified motls: {classified_particles}, number of assigned particles: {assigned_aprticles}, number of overlaps: {overlaps}"
    )

    if update_coord:
        motl.df.loc[
            motl.df["class"] != unassigned_class, ["x", "y", "z"]
        ] = motl.df.loc[
            motl.df["class"] != unassigned_class, ["geom4", "geom5", "geom6"]
        ].values
        motl.df.loc[
            motl.df["class"] != unassigned_class, ["shift_x", "shift_y", "shift_z"]
        ] = 0.0
        motl.df["geom4"] = 0.0

    motl.df["geom5"] = motl.df["geom2"].values
    motl.df["geom6"] = motl.df["geom1"].values
    motl.df[["geom1", "geom2"]] = 0.0

    motl.update_coordinates()

    if output_motl is not None:
        motl.write_to_emfile(output_motl)

    return motl

# def get_nn_dist(kdt,query_point,query_size,active_points,test_value):
# search the nearest points
# first get all points sorted by distance
# then find the first one that is still unused
#    entry_dist, np_idx = kdt.query(query_point,query_size)
#    rp_idx = np.argmax(active_points[np_idx]==test_value)
#    entry_dist = entry_dist[rp_idx]
#    np_idx = np_idx[rp_idx]
#
#    return entry_dist, np_idx

# def get_nn_dist2(kdt,query_point,dist_max,dist_min,active_points,test_value):

#     id_max = kdt.query_ball_point(query_point, dist_max, p=2.0, eps=0, return_sorted=False)
#     entry_dist, np_idx = kdt.query(query_point,2)

#     if len(id_max) == 0:
#         return -1

#     if dist_min > 0:
#         id_min = kdt.query_ball_point(query_point, dist_min, p=2.0, eps=0, return_sorted=False)
#         id_max = np.setdiff1d(id_max,id_min)
#     else:
#         id_max = np.array(id_max)

#     ia=id_max[active_points[id_max]==test_value]

#     if ia.size != 0:
#         nn_id=ia[0]
#     else:
#         nn_id=-1

#     return nn_id

def add_traced_info(
    traced_motl, input_motl, output_motl_path=None, sort_by_subtomo=True
):
    if isinstance(traced_motl, str):
        traced_motl = cryomotl.Motl(motl_path=traced_motl)

    if isinstance(input_motl, str):
        input_motl = cryomotl.Motl(motl_path=input_motl)

    if sort_by_subtomo:
        traced_motl.df.sort_values(["subtomo_id"], inplace=True)
        input_motl.df.sort_values(["subtomo_id"], inplace=True)

    if not np.array_equal(
        traced_motl.df["subtomo_id"].values, traced_motl.df["subtomo_id"].values
    ):
        raise ValueError(
            "The input motl has different subtomograms as the traced motl."
        )

    input_motl.df[["geom1", "geom2", "geom5", "object_id"]] = traced_motl.df[
        ["geom1", "geom2", "geom5", "object_id"]
    ].values
    input_motl.df.sort_values(["tomo_id", "object_id", "geom2"], inplace=True)

    if output_motl_path is not None:
        input_motl.write_to_emfile(output_motl_path)

    return input_motl

def get_nn_dist(kdt, query_point, dist_max, dist_min, active_points, test_value):
    id_max, dist = kdt.query_radius(
        query_point, dist_max, return_distance=True, sort_results=True
    )
    # id_max, dist = [a[0] for a in kdt.query_radius(query_point, dist_max, return_distance=True, sort_results=True)]
    id_max = id_max[0]
    dist = dist[0]
    if id_max.size == 0:
        return -1, []

    rp_idx = id_max[active_points[id_max] == test_value]
    rp_dist = dist[active_points[id_max] == test_value]

    if rp_idx.size == 0:
        return -1, []
    elif dist_min > 0:
        rp_idx = rp_idx[rp_dist > dist_min]
        rp_dist = rp_dist[rp_dist > dist_min]

    if rp_idx.size == 0:
        return -1, []
    else:
        return rp_idx[0], rp_dist[0]

def add_chain_suffix(
    chain_df,
    motl,
    traced_df,
    subtomo_id,
    current_dist,
    store_idx1="object_id",
    store_idx2="geom2",
    store_dist="geom5",
):
    particle_id = motl.df.loc[motl.df.index[subtomo_id], "subtomo_id"]

    temp_cl_id, order_id, previous_dist = traced_df.loc[
        traced_df["subtomo_id"] == particle_id, [store_idx1, store_idx2, store_dist]
    ].values[0]
    chain_max_order = np.max(
        traced_df.loc[traced_df[store_idx1] == temp_cl_id, [store_idx2]].values
    )

    if chain_max_order != order_id:  # the closest particle is not the last one
        if previous_dist <= current_dist:  # the original chain holds, do nothing
            return
        else:  # the new chain is better, cut of the tail of the existing one
            current_class = chain_df[store_idx1].values[0]
            traced_df.loc[
                (traced_df[store_idx1] == temp_cl_id)
                & (traced_df[store_idx2] > order_id),
                store_idx1,
            ] = current_class
            new_chain_size = traced_df.loc[
                (traced_df[store_idx1] == current_class), store_idx2
            ].shape[0]
            traced_df.loc[
                (traced_df[store_idx1] == current_class), store_idx2
            ] = np.arange(1, new_chain_size + 1)
            chain_max_order = np.max(
                traced_df.loc[traced_df[store_idx1] == temp_cl_id, [store_idx2]].values
            )  # max changed in the meantime so has to be fetched again

    traced_df.loc[
        traced_df["subtomo_id"] == particle_id, store_dist
    ] = current_dist  # add distance to the last traced element from the chain (should be 0 before)
    chain_df[store_idx1] = temp_cl_id
    chain_df[store_idx2] += chain_max_order

    return temp_cl_id

def add_chain_prefix(
    chain_df,
    motl,
    traced_df,
    subtomo_id,
    current_dist,
    store_idx1="object_id",
    store_idx2="geom2",
    store_dist="geom5",
    class_max=None,
):
    # finding out class of the chain that should be appended to the current chain
    particle_id = motl.df.loc[motl.df.index[subtomo_id], "subtomo_id"]
    class_to_change = traced_df.loc[
        traced_df["subtomo_id"] == particle_id, store_idx1
    ].values[0]

    order_id = traced_df.loc[traced_df["subtomo_id"] == particle_id, store_idx2].values[
        0
    ]

    current_class = chain_df[store_idx1].values[0]
    cut_off_size = 0

    if order_id != 1:  # the closest particle is NOT the first one in the chain!
        # take the previous particle distance
        previous_dist = traced_df.loc[
            (traced_df[store_idx1] == class_to_change)
            & (traced_df[store_idx2] == order_id - 1),
            store_dist,
        ].values[0]

        if previous_dist <= current_dist:  # original particle closer -> do not append
            return
        else:  # the new particle is closer - change the class/object_id to the one from the current particle
            cut_off_size = traced_df.loc[
                (traced_df[store_idx1] == class_to_change)
                & (traced_df[store_idx2] < order_id)
            ].shape[0]
            if (
                class_max is None
            ):  # Only appending, the chain object_id value is not used and can be assing to the cut chain
                traced_df.loc[
                    (traced_df[store_idx1] == class_to_change)
                    & (traced_df[store_idx2] < order_id),
                    store_idx1,
                ] = current_class
            else:  # Connectiong from both sides, the chain object_id was changed in the previoius append and cannot be used -> the input from current is used
                traced_df.loc[
                    (traced_df[store_idx1] == class_to_change)
                    & (traced_df[store_idx2] < order_id),
                    store_idx1,
                ] = class_max[1]

    if class_max is None:
        chain_df[store_idx1] = class_to_change
        class_max = np.max(chain_df[store_idx2].values)
        traced_df.loc[traced_df[store_idx1] == class_to_change, [store_idx2]] += (
            class_max - cut_off_size
        )
    else:
        temp_cl_id = chain_df[store_idx1][0]
        traced_df.loc[traced_df[store_idx1] == class_to_change, [store_idx2]] += (
            class_max[0] - cut_off_size
        )
        traced_df.loc[
            traced_df[store_idx1] == class_to_change, [store_idx1]
        ] = temp_cl_id

    chain_df.loc[chain_df.index[-1], store_dist] = current_dist

def trace_chains(
    motl_entry,
    motl_exit,
    max_distance,
    min_distance=0,
    feature="tomo_id",
    output_motl=None,
    store_idx1="object_id",
    store_idx2="geom2",
    store_dist="geom5",
):
    motl_entry = cryomotl.Motl(motl_path=motl_entry)
    motl_exit = cryomotl.Motl(motl_path=motl_exit)

    features1 = np.unique(motl_entry.df.loc[:, feature])
    features2 = np.unique(motl_exit.df.loc[:, feature])

    if ~np.all(np.equal(features1, features2)):
        ValueError("Provided motls have different features sets!!!")

    traced_motl = cryomotl.Motl.create_empty_motl()

    for f in features1:
        # for f in np.array([2,274,405,423]):
        # for f in np.array([423]):
        # print(f)
        fm_entry = motl_entry.get_feature_subset(f, feature)
        fm_exit = motl_exit.get_feature_subset(f, feature)

        nfm_df = cryomotl.Motl.create_empty_motl()

        fm_size = fm_entry.df.shape[0]
        remain_entry = np.full((fm_size,), True)
        remain_exit = np.full((fm_size,), True)

        class_c = 1

        coord_entry = fm_entry.get_coordinates()
        coord_exit = fm_exit.get_coordinates()

        kdt_entry = sn.KDTree(coord_entry)
        kdt_exit = sn.KDTree(coord_exit)

        for i, current_point in enumerate(coord_exit):
            if ~remain_exit[i]:
                continue
            else:
                ch_m = cryomotl.Motl.create_empty_motl()  # create new chain motl df
                chain_id = 1  # assign chain id
                trace_chain = True
                p_idx = i
                used_idx = []
                while trace_chain:
                    # take the particle from the exit list
                    # part_process = fm_exit.df.iloc[p_idx]

                    # add the same processed particle from entry list to the chain
                    ch_m = pd.concat(
                        [ch_m, fm_entry.df.iloc[[p_idx]]], ignore_index=True
                    )

                    ch_m.loc[ch_m.index[-1], [store_idx2]] = chain_id
                    chain_id += 1

                    # remove currently processed point from both entry and exit
                    remain_entry[p_idx] = False
                    remain_exit[p_idx] = False
                    used_idx.append(p_idx)

                    # prepare coordinates
                    p_coord = coord_exit[p_idx, None, :]

                    if np.all(
                        remain_entry == False
                    ):  # no remaining particles, end the chain
                        # np_idx = p_idx
                        np_idx = -1
                    else:
                        # search for the nearest active point
                        np_idx, np_dist = get_nn_dist(
                            kdt_entry,
                            p_coord,
                            max_distance,
                            min_distance,
                            remain_entry,
                            True,
                        )

                    if np_idx != -1:  # continue tracing
                        p_idx = np_idx
                        ch_m.loc[ch_m.index[-1], [store_dist]] = np_dist
                    else:  # end chain
                        ch_m.loc[:, store_idx1] = class_c
                        class_c += 1

                        if nfm_df.size != 0:  # check existing chains for connections
                            first_coord = (
                                ch_m.loc[ch_m.index[0], ["x", "y", "z"]].values
                                + ch_m.loc[
                                    ch_m.index[0], ["shift_x", "shift_y", "shift_z"]
                                ].values
                            )  # entry point
                            first_coord = first_coord.reshape(1, 3)
                            remain_entry[used_idx] = True
                            remain_exit[used_idx] = True
                            # check if this chain cannot be connected to already an existing one
                            # This can happen if the chain is started "in the middle"
                            nm_idx, nm_dist = get_nn_dist(
                                kdt_entry,
                                p_coord,
                                max_distance,
                                min_distance,
                                remain_entry,
                                False,
                            )
                            first_idx, first_dist = get_nn_dist(
                                kdt_exit,
                                first_coord,
                                max_distance,
                                min_distance,
                                remain_exit,
                                False,
                            )

                            remain_entry[used_idx] = False
                            remain_exit[used_idx] = False

                            if (
                                nm_idx != -1 and first_idx != -1
                            ):  # they connect from both sides
                                current_class = class_c - 1

                                # appending the chain after an existing one
                                add_chain_suffix(
                                    ch_m,
                                    fm_exit,
                                    nfm_df,
                                    first_idx,
                                    first_dist,
                                    store_idx1,
                                    store_idx2,
                                )

                                cl_max = np.max(ch_m[store_idx2].values)
                                if cl_max == 1:
                                    class_max = None
                                else:
                                    class_max = (cl_max, current_class)
                                add_chain_prefix(
                                    ch_m,
                                    fm_entry,
                                    nfm_df,
                                    nm_idx,
                                    nm_dist,
                                    store_idx1,
                                    store_idx2,
                                    class_max=class_max,
                                )

                            elif (
                                nm_idx != -1
                            ):  # connecting the chain before an existing one
                                add_chain_prefix(
                                    ch_m,
                                    fm_entry,
                                    nfm_df,
                                    nm_idx,
                                    nm_dist,
                                    store_idx1,
                                    store_idx2,
                                )

                            elif (
                                first_idx != -1
                            ):  # appneding the chain after an existing one
                                add_chain_suffix(
                                    ch_m,
                                    fm_exit,
                                    nfm_df,
                                    first_idx,
                                    first_dist,
                                    store_idx1,
                                    store_idx2,
                                )

                            # else: # no existing chain  ( nm_d > max_distance and first_d > max_distance) or ( nm_d <= min_distance and first_d <= min_distance):
                            #    ch_m.loc[:,store_idx1] = class_c
                            #    class_c += 1

                        nfm_df = pd.concat([nfm_df, ch_m])
                        trace_chain = False

        traced_motl = pd.concat([traced_motl, nfm_df])

    traced_motl = cryomotl.Motl(motl_df=traced_motl)

    if output_motl is not None:
        traced_motl.write_to_emfile(output_motl)

    return traced_motl


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

"""
@Author: xiezizhe
@Date: 16/6/2020 上午12:22
"""

class Solution:

    def myPow2(self, x: float, n: int) -> float:
        if n == 0:
            return 1.0
        if n == 1:
            return x
        if n == -1:
            return 1.0 / x

        flag = True
        if n < 0:
            flag = False
            n = -n

        res = self.myPow2(x, n // 2)
        if n % 2 == 0:
            res *= res
        else:
            res = res * res * x

        return res if flag else 1.0 / res

    def myPow3(self, x: float, n: int) -> float:
        if n == 0:
            return 1.0
        if n < 0:
            return 1.0 / self.myPow3(x, -n)

        return self.myPow3(x * x, n // 2) if n % 2 == 0 else x * self.myPow3(x * x, n // 2)

    def myPow(self, x: float, n: int) -> float:
        flag = True
        if n < 0:
            flag = False
            n = -n

        ans, odd = x, 1
        while n > 1:
            if n % 2 != 0:
                odd *= ans
            ans = ans * ans
            n = n // 2

        return ans * odd if flag else 1.0 / (ans * odd)

if __name__ == "__main__":
    s = Solution()
    print(pow(2, -1))
    print(s.myPow(2, -1))


# -*- coding: utf-8 -*-
import unittest, os
from base_test_case import BaseTestCase
from pages.main_page import MainPage
from pages.games_page import GamesPage
from pages.birth_date_page import BirthDatePage
from pages.sinlge_game_page import SingleGamePage
from pages.about_steam_page import AboutSteamPage

class SteamTest(BaseTestCase):

    def test_steam_with_selecting_game_with_max_discount_and_downloading_steam_file(self):
        # If you want to check steam_test on Russian version of Steam,
        # uncomment time.sleep(10), run test and change language to Russian on the main Steam page during sleep time
        # time.sleep(10)

        main_page = MainPage(self.driver, self.data_controller)
        language = main_page.check_language()
        main_page.browse_tab()
        self.driver.implicitly_wait(self.data_controller.config["wait"])
        main_page.select_item(language)
        self.driver.implicitly_wait(self.data_controller.config["wait"])

        games_page = GamesPage(self.driver, self.data_controller, language)
        title = self.driver.title
        self.assertEqual(self.data_controller.config["site"]["title"][language], title)

        games_page.navigate_to_specials()
        res = list(games_page.get_games_list_with_sales_and_click_target_game())
        self.driver.implicitly_wait(self.data_controller.config["wait"])

        if games_page.check_is_age_validation_required(language) == True:
            birth_page = BirthDatePage(self.driver, self.data_controller, language)
            birth_page.enter_birth_date()
        self.driver.implicitly_wait(self.data_controller.config["wait"])

        single_game_page = SingleGamePage(self.driver, self.data_controller, res[0])
        single_game_page._validate_page(self.driver, self.data_controller)
        single_game_page.check_discount_and_price_values(res[1], res[2], res[3])
        single_game_page.find_and_click_install_steam_button()
        self.driver.implicitly_wait(self.data_controller.config["wait"])

        about_steam_page = AboutSteamPage(self.driver, self.data_controller)
        about_steam_page.click_install_steam_to_download_steam_file()
        about_steam_page.check_file_downloading(os.path.dirname(__file__))

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


import sys

INTRINSIC_SPECIAL_ATTRIBUTES = frozenset((
    "__qualname__",
    "__module__",
    "__metaclass__",
    "__dict__",
    "__weakref__",
    "__class__",
    "__subclasshook__",
    "__name__",
    "__doc__",
))

def isAttributeSafeToTransfer(name, value):
    """Return True if an attribute is safe to monkeypatch-transfer to another
    class.
    This rejects special methods that are defined automatically for all
    classes, leaving only those explicitly defined in a class decorated by
    `continueClass` or registered with an instance of `TemplateMeta`.
    """
    if name.startswith("__") and (value is getattr(object, name, None) or
                                          name in INTRINSIC_SPECIAL_ATTRIBUTES):
        return False
    return True

def continueClass(cls):
    """Re-open the decorated class, adding any new definitions into the original.
    For example,
    ::
        class Foo:
            pass
        @continueClass
        class Foo:
            def run(self):
                return None
    is equivalent to
    ::
        class Foo:
            def run(self):
                return None
    """
    orig = getattr(sys.modules[cls.__module__], cls.__name__)
    for name in dir(cls):
        # Common descriptors like classmethod and staticmethod can only be
        # accessed without invoking their magic if we use __dict__; if we use
        # getattr on those we'll get e.g. a bound method instance on the dummy
        # class rather than a classmethod instance we can put on the target
        # class.
        attr = cls.__dict__.get(name, None) or getattr(cls, name)
        if isAttributeSafeToTransfer(name, attr):
            setattr(orig, name, attr)
    return orig

def inClass(cls, name=None):
    """Add the decorated function to the given class as a method.
    For example,
    ::
        class Foo:
            pass
        @inClass(Foo)
        def run(self):
            return None
    is equivalent to::
        class Foo:
            def run(self):
                return None
    Standard decorators like ``classmethod``, ``staticmethod``, and
    ``property`` may be used *after* this decorator.  Custom decorators
    may only be used if they return an object with a ``__name__`` attribute
    or the ``name`` optional argument is provided.
    """
    def decorate(func):
        # Using 'name' instead of 'name1' breaks the closure because
        # assignment signals a strictly local variable.
        name1 = name
        if name1 is None:
            if hasattr(func, "__name__"):
                name1 = func.__name__
            else:
                if hasattr(func, "__func__"):
                    # classmethod and staticmethod have __func__ but no __name__
                    name1 = func.__func__.__name__
                elif hasattr(func, "fget"):
                    # property has fget but no __name__
                    name1 = func.fget.__name__
                else:
                    raise ValueError(
                        "Could not guess attribute name for '{}'.".format(func)
                    )
        setattr(cls, name1, func)
        return func
    return decorate

class TemplateMeta(type):
    """A metaclass for abstract base classes that tie together wrapped C++
    template types.
    C++ template classes are most easily wrapped with a separate Python class
    for each template type, which results in an unnatural Python interface.
    TemplateMeta provides a thin layer that connects these Python classes by
    giving them a common base class and acting as a factory to construct them
    in a consistent way.
    To use, simply create a new class with the name of the template class, and
    use ``TemplateMeta`` as its metaclass, and then call ``register`` on each
    of its subclasses.  This registers the class with a "type key" - usually a
    Python representation of the C++ template types.  The type key must be a
    hashable object - strings, type objects, and tuples of these (for C++
    classes with multiple template parameters) are good choices.  Alternate
    type keys for existing classes can be added by calling ``alias``, but only
    after a subclass already been registered with a "primary" type key.  For
    example (using Python 3 metaclass syntax)::
        import numpy as np
        from ._image import ImageF, ImageD
        class Image(metaclass=TemplateMeta):
            pass
        Image.register(np.float32, ImageF)
        Image.register(np.float64, ImageD)
        Image.alias("F", ImageF)
        Image.alias("D", ImageD)
    We have intentionally used ``numpy`` types as the primary keys for these
    objects in this example, with strings as secondary aliases simply because
    the primary key is added as a ``dtype`` attribute on the the registered
    classes (so ``ImageF.dtype == numpy.float32`` in the above example).
    This allows user code to construct objects directly using ``Image``, as
    long as an extra ``dtype`` keyword argument is passed that matches one of
    the type keys::
        img = Image(52, 64, dtype=np.float32)
    This simply forwards additional positional and keyword arguments to the
    wrapped template class's constructor.
    The choice of "dtype" as the name of the template parameter is also
    configurable, and in fact multiple template parameters are also supported,
    by setting a ``TEMPLATE_PARAMS`` class attribute on the ABC to a tuple
    containing the names of the template parameters.  A ``TEMPLATE_DEFAULTS``
    attribute can also be defined to a tuple of the same length containing
    default values for the template parameters, allowing them to be omitted in
    constructor calls.  When the length of these attributes is more than one,
    the type keys passed to ``register`` and ``alias`` should be tuple of the
    same length; when the length of these attributes is one, type keys should
    generally not be tuples.
    As an aid for those writing the Python wrappers for C++ classes,
    ``TemplateMeta`` also provides a way to add pure-Python methods and other
    attributes to the wrapped template classes.  To add a ``sum`` method to
    all registered types, for example, we can just do::
        class Image(metaclass=TemplateMeta):
            def sum(self):
                return np.sum(self.getArray())
        Image.register(np.float32, ImageF)
        Image.register(np.float64, ImageD)
    .. note::
        ``TemplateMeta`` works by overriding the ``__instancecheck__`` and
        ``__subclasscheck__`` special methods, and hence does not appear in
        its registered subclasses' method resolution order or ``__bases__``
        attributes. That means its attributes are not inherited by registered
        subclasses. Instead, attributes added to an instance of
        ``TemplateMeta`` are *copied* into the types registered with it. These
        attributes will thus *replace* existing attributes in those classes
        with the same name, and subclasses cannot delegate to base class
        implementations of these methods.
    Finally, abstract base classes that use ``TemplateMeta`` define a dict-
    like interface for accessing their registered subclasses, providing
    something like the C++ syntax for templates::
        Image[np.float32] -> ImageF
        Image["D"] -> ImageD
    Both primary dtypes and aliases can be used as keys in this interface,
    which means types with aliases will be present multiple times in the dict.
    To obtain the sequence of unique subclasses, use the ``__subclasses__``
    method.
    """

    def __new__(cls, name, bases, attrs):
        # __new__ is invoked when the abstract base class is defined (via a
        # class statement).  We save a dict of class attributes (including
        # methods) that were defined in the class body so we can copy them
        # to registered subclasses later.
        # We also initialize an empty dict to store the registered subclasses.
        attrs["_inherited"] = {k: v for k, v in attrs.items()
                               if isAttributeSafeToTransfer(k, v)}
        # The special "TEMPLATE_PARAMS" class attribute, if defined, contains
        # names of the template parameters, which we use to set those
        # attributes on registered subclasses and intercept arguments to the
        # constructor.  This line removes it from the dict of things that
        # should be inherited while setting a default of 'dtype' if it's not
        # defined.
        attrs["TEMPLATE_PARAMS"] = \
            attrs["_inherited"].pop("TEMPLATE_PARAMS", ("dtype",))
        attrs["TEMPLATE_DEFAULTS"] = \
            attrs["_inherited"].pop("TEMPLATE_DEFAULTS",
                                    (None,)*len(attrs["TEMPLATE_PARAMS"]))
        attrs["_registry"] = dict()
        self = type.__new__(cls, name, bases, attrs)

        if len(self.TEMPLATE_PARAMS) == 0:
            raise ValueError(
                "TEMPLATE_PARAMS must be a tuple with at least one element."
            )
        if len(self.TEMPLATE_DEFAULTS) != len(self.TEMPLATE_PARAMS):
            raise ValueError(
                "TEMPLATE_PARAMS and TEMPLATE_DEFAULTS must have same length."
            )
        return self

    def __call__(self, *args, **kwds):
        # __call__ is invoked when someone tries to construct an instance of
        # the abstract base class.
        # If the ABC defines a "TEMPLATE_PARAMS" attribute, we use those strings
        # as the kwargs we should intercept to find the right type.
        key = tuple(kwds.pop(p, d) for p, d in zip(self.TEMPLATE_PARAMS,
                                                   self.TEMPLATE_DEFAULTS))
        # indices are only tuples if there are multiple elements
        cls = self._registry.get(key[0] if len(key) == 1 else key, None)
        if cls is None:
            d = {k: v for k, v in zip(self.TEMPLATE_PARAMS, key)}
            raise TypeError("No registered subclass for {}.".format(d))
        return cls(*args, **kwds)

    def __subclasscheck__(self, subclass):
        # Special method hook for the issubclass built-in: we return true for
        # any registered type or true subclass thereof.
        if subclass in self._registry:
            return True
        for v in self._registry.values():
            if issubclass(subclass, v):
                return True
        return False

    def __instancecheck__(self, instance):
        # Special method hook for the isinstance built-in: we return true for
        # an instance of any registered type or true subclass thereof.
        if type(instance) in self._registry:
            return True
        for v in self._registry.values():
            if isinstance(instance, v):
                return True
        return False

    def __subclasses__(self):
        """Return a tuple of all classes that inherit from this class.
        """
        # This special method isn't defined as part of the Python data model,
        # but it exists on builtins (including ABCMeta), and it provides useful
        # functionality.
        return tuple(set(self._registry.values()))

    def _add_class_documentation(cls, subclass):
        cls.__doc__ = subclass.__doc__

        for attr_name in dir(subclass):
            # Only new attributes and non-special/private
            if hasattr(cls, attr_name):
                continue
            if attr_name.startswith('__'):
                continue

            # Only callables
            sub_attr = getattr(subclass, attr_name)
            if not hasattr(sub_attr, '__call__'):
                continue

            from types import MethodType
            def fail_on_call(_self):
                raise NotImplementedError("This method should never be called since it lives only in the meta class")
            fail_on_call.__name__ = attr_name
            fail_on_call.__doc__ = sub_attr.__doc__
            #setattr(cls, attr_name, classmethod(fail_on_call))
            setattr(cls, attr_name, MethodType(fail_on_call, cls))

    def register(self, key, subclass):
        """Register a subclass of this ABC with the given key (a string,
        number, type, or other hashable).
        Register may only be called once for a given key or a given subclass.
        """
        if key is None:
            raise ValueError("None may not be used as a key.")
        if subclass in self._registry.values():
            raise ValueError(
                "This subclass has already registered with another key; "
                "use alias() instead."
            )
        if self._registry.setdefault(key, subclass) != subclass:
            if len(self.TEMPLATE_PARAMS) == 1:
                d = {self.TEMPLATE_PARAMS[0]: key}
            else:
                d = {k: v for k, v in zip(self.TEMPLATE_PARAMS, key)}
            raise KeyError(
                "Another subclass is already registered with {}".format(d)
            )
        self._add_class_documentation(subclass)

        def setattrSafe(name, value):
            try:
                currentValue = getattr(subclass, name)
                if currentValue != value:
                    msg = ("subclass already has a '{}' attribute with "
                           "value {} != {}.")
                    raise ValueError(
                        msg.format(name, currentValue, value)
                    )
            except AttributeError:
                setattr(subclass, name, value)

        if len(self.TEMPLATE_PARAMS) == 1:
            setattrSafe(self.TEMPLATE_PARAMS[0], key)
        elif len(self.TEMPLATE_PARAMS) == len(key):
            for p, k in zip(self.TEMPLATE_PARAMS, key):
                setattrSafe(p, k)
        else:
            raise ValueError(
                "key must have {} elements (one for each of {})".format(
                    len(self.TEMPLATE_PARAMS), self.TEMPLATE_PARAMS
                )
            )

        for name, attr in self._inherited.items():
            setattr(subclass, name, attr)

    def alias(self, key, subclass):
        """Add an alias that allows an existing subclass to be accessed with a
        different key.
        """
        if key is None:
            raise ValueError("None may not be used as a key.")
        if key in self._registry:
            raise KeyError("Cannot multiply-register key {}".format(key))
        primaryKey = tuple(getattr(subclass, p, None)
                           for p in self.TEMPLATE_PARAMS)
        if len(primaryKey) == 1:
            # indices are only tuples if there are multiple elements
            primaryKey = primaryKey[0]
        if self._registry.get(primaryKey, None) != subclass:
            raise ValueError("Subclass is not registered with this base class.")
        self._registry[key] = subclass

    # Immutable mapping interface defined below.  We don't use collections
    # mixins because we don't want their comparison operators.

    def __getitem__(self, key):
        return self._registry[key]

    def __iter__(self):
        return iter(self._registry)

    def __len__(self):
        return len(self._registry)

    def __contains__(self, key):
        return key in self._registry

    def keys(self):
        """Return an iterable containing all keys (including aliases).
        """
        return self._registry.keys()

    def values(self):
        """Return an iterable of registered subclasses, with duplicates
        corresponding to any aliases.
        """
        return self._registry.values()

    def items(self):
        """Return an iterable of (key, subclass) pairs.
        """
        return self._registry.items()

    def get(self, key, default=None):
        """Return the subclass associated with the given key (including
        aliases), or ``default`` if the key is not recognized.
        """
        return self._registry.get(key, default)


from sys import stdin, setrecursionlimit, maxsize
setrecursionlimit(10**7)

def getMaxPathSum(matrix):
    maxi = -maxsize
    m = len(matrix)
    n = len(matrix[0])
    dp = [[-1]*n for x in range(m)]

    for i in range(n):
        maxi = max(maxi, recur(matrix, 0, i, dp))
    return maxi

def recur(matrix, i, j, dp):
    if j < 0 or j > len(matrix[0])-1: return -maxsize
    val = matrix[i][j]

    if i == len(matrix)-1: return val
    if dp[i][j] == -1:
        down= val + recur(matrix, i+1, j, dp)
        downr = val + recur(matrix, i+1, j+1, dp)
        downl = val + recur(matrix, i+1, j-1, dp)
        dp[i][j] = max(down, downr, downl)
    return dp[i][j]

from sys import stdin, setrecursionlimit, maxsize
setrecursionlimit(10**7)

def getMaxPathSum(matrix):
    m = len(matrix)
    n = len(matrix[0])
    dp = [-1]*n
    for i in range(n):
        dp[i] = matrix[m-1][i]

    i = m-2
    while(i > -1):
        j = n-1
        temp = [-1] * n
        while(j > -1):
            val = matrix[i][j]
            downl, downr = -maxsize, -maxsize
            down = val + dp[j]
            if j+1 < n:
                downl = val + dp[j+1]
            if j-1 > -1:
                downr = val + dp[j-1]
            temp[j] = max(down, downr, downl)
            j-=1
        dp = temp[:]
        i-=1
    return max(dp)


import cv2
from cv2 import VideoCapture
ing = cv2.imread("walking.avi")

# Create our body classifier
body_classifier = cv2.CascadeClassifier("haarcascade_fullbody.xml")

# Initiate video capture for video file
cap = cv2.VideoCapture('walking.avi')

# Loop once video is successfully loaded
while True:
    cv2.cvtColor(VideoCapture, cv2.COLOR_BGR2GRAY),

    # Read first frame
    ret, frame = cap.read()
    cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY),

    #Convert Each Frame into Grayscale

    # Pass frame to our body classifier

    body_classifier = cv2.CascadeClassifier("haarcascade_fullbody.xml")

    # Extract bounding boxes for any bodies identified

    if cv2.waitKey(1) == 32: #32 is the Space Key
        break

cap.release()
cv2.destroyAllWindows()


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

import pytest
import logging

from friendface.communication import Server, Client

LOCALHOST = 'localhost'
FORMAT = '%(asctime)s [%(threadName)s] %(filename)s +%(levelno)s %(funcName)s %(levelname)s %(message)s'
logging.basicConfig(level=logging.DEBUG, format=FORMAT)

@pytest.fixture(scope="session")
def port():
    return 9998

def test_server_startup(port):
    def handler(socket):
        pass
    server = Server(LOCALHOST, port, handler)
    server.start()
    server.stop()

def test_echo(port):
    message = 'hello'.encode('utf8')

    def echo(socket):
        socket.send(socket.recv(1024))

    server = Server(LOCALHOST, port, echo)
    server.start()

    with Client(LOCALHOST, port) as client:
        client.send(message)
        echoed = client.recv(1024)

    server.stop()

    assert echoed == message

def test_connect_twice_in_sequence(port):
    message_1 = 'hello 1'.encode('utf8')
    message_2 = 'hello 2'.encode('utf8')

    def echo(socket):
        socket.send(socket.recv(1024))

    server = Server(LOCALHOST, port, echo)
    server.start()

    with Client(LOCALHOST, port) as client:
        client.send(message_1)
        echoed_1 = client.recv(1024)

    with Client(LOCALHOST, port) as client:
        client.send(message_2)
        echoed_2 = client.recv(1024)

    server.stop()

    assert echoed_1 == message_1
    assert echoed_2 == message_2

def test_connect_twice_in_parallel(port):
    message_1 = 'hello 1'.encode('utf8')
    message_2 = 'hello 2'.encode('utf8')

    def echo(socket):
        socket.send(socket.recv(1024))

    server = Server(LOCALHOST, port, echo)
    server.start()

    with Client(LOCALHOST, port) as client_1:
        client_1.send(message_1)
        echoed_1 = client_1.recv(1024)

        with Client(LOCALHOST, port) as client_2:
            client_2.send(message_2)
            echoed_2 = client_2.recv(1024)

    server.stop()

    assert echoed_1 == message_1
    assert echoed_2 == message_2


def fibonacci(n):
    """
    Returns a list of Fibonacci numbers up to the nth index.
    """
    fib = [1, 1]
    for i in range(2, n):
        fib.append(fib[i-1] + fib[i-2])
    return fib

def solve(N, Q):
    fib = fibonacci(N)
    zeros = [0 for _ in range(N)]

    for _ in range(Q):
        LR = list(map(int, input().split()))
        L = LR[0]
        R = LR[1]

        index = 0

        for i in range(L - 1, R):
            add = fib[index]
            zeros[i] += add
            index += 1

    for i in range(len(zeros)):
        zeros[i] %= 998244353

    return zeros

for _ in range(int(input())):
    NQ = list(map(int, input().split()))
    N = NQ[0]
    Q = NQ[1]

    print(" ".join(list(map(str, solve(N, Q)))))


from __future__ import annotations

from typing import IO, TYPE_CHECKING, Dict

from flask import current_app, g

from enums import Dep, LeafState, MangoType
from exts import storage
from exts.id_tools import generate_id
from exts.sqlalchemy_ import (BaseModel, Column, ForeignKey, UniqueConstraint,
                              relationship)
from exts.sqlalchemy_.types import (ARRAY, JSON, Boolean, DateTime, Enum,
                                    LargeBinary, String)

from .audio_tools import get_audio_info
from .errors import NotQualifiedToPick, StateLocked, UnallowedType, UnknowType
from .file_tools import EXTS, is_allowed_type, special_save

if TYPE_CHECKING:
    from proj.models import Proj
    from pink.models import Pink

class Leaf(BaseModel):
    __tablename__ = 'leaf'

    id = Column(String, primary_key=True)
    proj_id = Column(String, ForeignKey('proj.id', ondelete='CASCADE'))
    dep = Column(Enum(Dep))
    role = Column(String)
    pink_id = Column(String, ForeignKey('pink.id'))
    state = Column(Enum(LeafState), default=LeafState.waiting)
    track = Column(ARRAY(String), default=list())
    timestamp = Column(DateTime)

    pink = relationship('Pink', back_populates='leafs')
    proj = relationship('Proj', back_populates='leafs')
    mangos = relationship('Mango',
                          back_populates='leaf',
                          cascade='all, delete-orphan',
                          passive_deletes=True)
    schedule = relationship('Schedule',
                            back_populates='leaf',
                            uselist=False,
                            cascade='all, delete-orphan',
                            passive_deletes=True)
    __table_args__ = (UniqueConstraint('proj_id',
                                       'dep',
                                       'role',
                                       'pink_id',
                                       name='_leaf_uc'), )

    def __init__(self, freerole, pink):
        if freerole.dep not in pink.deps:
            raise NotQualifiedToPick()
        super().__init__(proj_id=freerole.progress_id,
                         dep=freerole.dep,
                         role=freerole.role,
                         pink=pink,
                         timestamp=g.now)
        self.id = generate_id(15)
        self.proj.call_elf(dep=None, mango=None, pos=None)
        freerole.take(leaf_id=self.id)

    def drop(self, force: bool = False) -> None:
        if self.state != LeafState.normal and not force:
            raise StateLocked(current=self.state)
        self.state = LeafState.droped_m if not force else LeafState.droped_f
        self.track.append(f'drop|{g.now}' if not force else f'f_drop|{g.now}')
        self.proj.progress.put_role(leaf_id=self.id)

    def f_drop(self) -> None:
        self.pink.cc += 1
        self.drop(force=True)

    def submit(self, f: IO) -> None:
        if self.state != LeafState.normal:
            raise StateLocked(current=self.state)
        mango = Mango(leaf=self, f=f)
        self.state = LeafState.paused_fin
        self.proj.run_elfs(dep=self.dep, mango=mango, pos=True)
        self.track.append(f'fin|{g.now}')
        return mango

    def download(self):
        if self.state != LeafState.paused_fin:
            raise StateLocked(current=self.state)
        mango = self.mangos[-1]
        mango.download()
        return mango.id, mango.name

    def redo(self) -> None:
        if self.state != LeafState.paused_fin:
            raise StateLocked(current=self.state)
        mango: Mango = self.mangos[-1]
        mango.delete()
        self.state = LeafState.normal
        self.proj.run_elfs(dep=self.dep, mango=mango, pos=False)
        self.track.append(f'redo|{g.now}')

    def to_dict(self, lv: int) -> Dict[str, str]:
        if lv == 0:
            return {
                'id': self.id,
                'proj_id': self.proj_id,
                'dep_': self.dep.name,
                'role': self.role,
                'pink_id': self.pink.id,
                'state': self.state.name
            }

class Mango(BaseModel):
    __tablename__ = 'mango'

    id = Column(String, primary_key=True)
    leaf_id = Column(String, ForeignKey('leaf.id', ondelete='CASCADE'))
    mtype = Column(Enum(MangoType))
    fp = Column(LargeBinary(32))
    deleted = Column(Boolean, default=False)
    timestamp = Column(DateTime)
    metainfo = Column(JSON)

    leaf = relationship('Leaf', back_populates='mangos')

    @property
    def name(self):
        leaf = self.leaf
        return f'{leaf.dep}-{leaf.role} [{leaf.pink.name}-{self.id[:6]}].{EXTS[self.mtype]}'

    def __init__(self, leaf: Leaf, f: IO):
        super().__init__(leaf=leaf)
        self.id = generate_id(18)
        self.timestamp = g.now
        path = f'{current_app.root_path}/{self.id}'
        self.fp, self.mtype = special_save(f=f, path=path)
        if self.mtype is MangoType.unknown:
            raise UnknowType()
        if not is_allowed_type(self.dep, self.mtype):
            raise UnallowedType(mtype=self.mtype)
        # fetch info
        if self.mtype // 10 == 5:
            self.metainfo = get_audio_info(path=path)
        else:
            self.metainfo = None

        storage.upload(mango=self, path=path)

    def download(self) -> None:
        storage.download(mango=self)

    def delete(self) -> None:
        self.deleted = True

class Schedule(BaseModel):
    __tablename__ = 'schedule'

    leaf_id = Column(String,
                     ForeignKey('leaf.id', ondelete='CASCADE'),
                     primary_key=True)
    begin = Column(DateTime)
    due = Column(DateTime)
    paused_at = Column(DateTime)

    leaf = relationship('Leaf', back_populates='schedule')


import numpy as np
import matplotlib.pyplot as plt

def kernel_function(x, x_p, s_f=1, l=1):
    # get || x - x_p || ^ 2
    squared_distance = np.sum(x ** 2, axis=1).reshape(-1, 1) + np.sum(x_p ** 2, axis=1) \
                       - 2 * np.matmul(x, np.transpose(x_p))
    # compute and return kernel function
    return (s_f ** 2) * np.exp((-1 / (2 * l ** 2)) * squared_distance)

def plot_gaussian_process(x, dist):
    # iterate through each distribution
    for i in range(dist.shape[1]):
        # plot each distribution
        plt.plot(x, dist[:, i])
    plt.show()

def prior_functions():
    # set up minimum and maximum intervals
    interval_min, interval_max = -4, 4
    # take arbitrary size of n = 50
    n = 50
    # generate X values
    x = np.linspace(interval_min, interval_max, n).reshape(-1, 1)
    # compute kernel function for given x
    kernel = kernel_function(x, x)

    # compute cholesky decomposition of kernel matrix to get L matrix
    l_mat = np.linalg.cholesky(kernel + 1e-6 * np.eye(n))
    # generate 10 prior distributions
    prior = np.dot(l_mat, np.random.normal(size=(n, 10)))
    return x, prior

def create_training_data():
    # assign x values
    x = np.array([-3.8, -3.2, -3, 1, 3])
    # assign y values
    # y = sin(0.5 * x)
    y = np.array([-0.9463, -0.9996, -0.9975, 0.4794, 0.9975])
    return x.reshape(-1, 1), y.reshape(-1, 1)

def plot_mean_cov_gt(mean, cov, x, y, x_star):
    # plot training samples
    plt.plot(x, y, 'rx', label='training samples')
    # plot ground truth curve
    plt.plot(x_star, np.sin(x_star / 2), label='ground truth')
    # plot estimated mean curve
    plt.plot(x_star, mean, label='predicted')
    # get standard deviation from diagonal elements of covariance matrix
    sigma = np.sqrt(np.diag(cov))
    region = 1.96 * sigma
    # fill error regions for estimated mean curve
    plt.fill_between(x_star.flatten(), mean.flatten() + region, mean.flatten() - region, alpha=0.2)
    plt.legend(loc='upper left')
    plt.show()

def non_linear_regression(train_X, train_y, x):
    # compute kernel function of train_X, train_X
    k = kernel_function(train_X, train_X)
    # compute kernel function of train_X, x
    k_star = kernel_function(train_X, x)
    # compute kernel function of x, x
    k_star_star = kernel_function(x, x)

    # compute cholesky decomposition of k to get l
    l = np.linalg.cholesky(k + 1e-6 * np.eye(len(train_X)))
    # solve for m using l and train_y
    m = np.linalg.solve(l, train_y)
    # solve for alpha using l.T and m
    alpha = np.linalg.solve(np.transpose(l), m)
    # estimate mean by multiplying k_star and alpha
    mean = np.matmul(np.transpose(k_star), alpha)

    # solve for v using l and k_star
    v = np.linalg.solve(l, k_star)
    # estimate covariance matrix from k_star_star and v
    cov = k_star_star - np.matmul(np.transpose(v), v)
    return mean, cov

def compute_posterior(mean, cov, n):
    # compute cholesky decomposition of covariance matrix to get L matrix
    l_mat = np.linalg.cholesky(cov + 1e-6 * np.eye(n))
    # generate 10 posterior distributions with estimated mean and covariance
    posterior = mean + np.dot(l_mat, np.random.normal(size=(n, 10)))
    return posterior

def main():
    # set up random seed for reproducibility
    np.random.seed(123)

    # a) prior functions
    # generate prior functions
    x, prior = prior_functions()
    # plot the gaussian process prior
    plot_gaussian_process(x, prior)

    # b) estimate mean and error
    # create training data set
    train_X, train_y = create_training_data()
    # compute mean and covariance
    mean, cov = non_linear_regression(train_X, train_y, x)
    # plot predicted mean, error curves and ground truth
    plot_mean_cov_gt(mean, cov, train_X, train_y, x)

    # c) posterior functions
    posterior = compute_posterior(mean, cov, x.shape[0])
    # plot gaussian process posterior
    plot_gaussian_process(x, posterior)

if __name__ == '__main__':
    main()


import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

class Fit_Gaussian():
    """
    A class used to fit a gaussian on a histogram

    ...

    Attributes
    ----------
    data : array like
        input data. The histogram is computed over the flattened array.

    normalized : bool
        fit a normalized histogram, the default is false.

    Methods
    -------
    hist_fitting(show = False)
        Get a gaussian fitting of a histogram.
    """

    def __init__(self, data, normalized = False):
        """
        Parameters
        ----------
        data : array like
            input data. The histogram is computed over the flattened array.

        normalized : bool
            fit a normalized histogram, the default is false.
        """

        self.data = data                     # The image to the Gaussian on.
        self.normalized = normalized       # Using normalized Gaussian.

    # Define a gaussian
    def Gauss(x, x0, sigma, y0, A):
        return y0 + A * np.exp(-(x - x0)**2 / (2 * sigma**2))

    # Define a normalized gaussian
    def Gauss_normalized(x, x0, sigma):
        return (1/np.sqrt(2 * np.pi * sigma**2)) * np.exp(-(x - x0)**2 / (2 * sigma**2))

    # Fit a gaussian on a histogram
    def hist_fitting(self, bins = 200, show = False):
        """Get a gaussian fitting of a histogram.

        Parameters
        ----------
        bins : int, optional
        It defines the number of equal-width bins in the given range (200, by default).

        show : bool, optional
        Show the graph of the histogram, the default is false.

        Returns
        -------
        popt: array
        Optimal values for the parameters so that the sum of the squared residuals of the Gaussian with data is minimized

        X0, sigma, Y0, A of the histogram gaussian
        X0, sigma of the normalized histogram gaussian if normalized = True

        Raises
        ------
        Value Error
            if either ydata or xdata contain NaNs, or if incompatible options are used.
        Runtime Error
            if the least-squares minimization fails.
        Optimize Warning
            if covariance of the parameters can not be estimated.
        """
        # Make a histogram
        if self.normalized == True:
            n, bins_ = np.histogram(self.data, bins=bins, density = True)
        else:
            n, bins_ = np.histogram(self.data, bins=bins)

        # Data
        x = np.linspace(bins_.min(),bins_.max(),bins_.shape[0]-1)
        y = n

        # Apply the fitting
        if self.normalized == True:
            popt,pcov = curve_fit(Fit_Gaussian.Gauss_normalized, x, y,
                                  p0 = (x.max()/2, x.max()/3),
                                  bounds = (0, [x.max(), x.max()/2]))
        else:
            popt,pcov = curve_fit(Fit_Gaussian.Gauss, x, y,
                                  p0 = (x.max()/2, x.max()/3, 0, 1/np.sqrt(2 * np.pi * (x.max()/3)**2)),
                                  bounds = (0, [x.max(), x.max()/2, np.inf, np.inf]))

        # Display the results
        if show == True:
            plt.figure(figsize=(8,5))

            if self.normalized == True:
                plt.plot(x, Fit_Gaussian.Gauss_normalized(x, *popt), 'r-',
                         label='Gauss: $x_0$ = {:.4f}, $\sigma$ = {:.4f}'.format(*popt))
            else:
                plt.plot(x, Fit_Gaussian.Gauss(x, *popt), 'r-',
                         label='Gauss: $x_0$ = {:.4f}, $\sigma$ = {:.4f}, $Y_0$ = {:.4f}, A = {:.4f}'.format(*popt))

            plt.plot(x, y, 'b+:', label='data')
            plt.legend()
            plt.title('Histogram Gaussian')
            plt.xlabel('value')
            plt.ylabel('frequency')
            plt.grid()

        return popt  #(X0, sigma, Y0, A) or just (X0, sigma) for normalized Gaussian