"""
General Numerical Solver for the 1D Time-Dependent Schrodinger Equation.

Authors:
- Jake Vanderplas <vanderplas@astro.washington.edu>
- Andre Xuereb (imaginary time propagation, normalized wavefunction

For a theoretical description of the algorithm, please see
http://jakevdp.github.com/blog/2012/09/05/quantum-python/

License: BSD style
Please feel free to use and modify this, but keep the above information.
"""
import numpy as np
from scipy import fftpack
import matplotlib.pyplot as plt
from matplotlib import animation
import seaborn as sns
sns.set()

class Schrodinger(object):
    """
    Class which implements a numerical solution of the time-dependent
    Schrodinger equation for an arbitrary potential
    """
    def __init__(self, x, psi_x0, V_x, k0=None, hbar=1, m=1, t0=0.0):
        """
        Parameters
        ----------
        x : array_like, float
            Length-N array of evenly spaced spatial coordinates
        psi_x0 : array_like, complex
            Length-N array of the initial wave function at time t0
        V_x : array_like, float
            Length-N array giving the potential at each x
        k0 : float
            The minimum value of k.  Note that, because of the workings of the
            Fast Fourier Transform, the momentum wave-number will be defined
            in the range
              k0 < k < 2*pi / dx ,
            where dx = x[1]-x[0].  If you expect nonzero momentum outside this
            range, you must modify the inputs accordingly.  If not specified,
            k0 will be calculated such that the range is [-k0,k0]
        hbar : float
            Value of Planck's constant (default = 1)
        m : float
            Particle mass (default = 1)
        t0 : float
            Initial time (default = 0)
        """
        # Validation of array inputs
        self.x, psi_x0, self.V_x = map(np.asarray, (x, psi_x0, V_x))
        N = self.x.size
        assert self.x.shape == (N,)
        assert psi_x0.shape == (N,)
        assert self.V_x.shape == (N,)

        # Validate and set internal parameters
        assert hbar > 0
        assert m > 0
        self.hbar = hbar
        self.m = m
        self.t = t0
        self.dt_ = None
        self.N = len(x)
        self.dx = self.x[1] - self.x[0]
        self.dk = 2 * np.pi / (self.N * self.dx)

        # Set momentum scale
        if k0 == None:
            self.k0 = -0.5 * self.N * self.dk
        else:
            assert k0 < 0
            self.k0 = k0
        self.k = self.k0 + self.dk * np.arange(self.N)

        self.psi_x = psi_x0
        self.compute_k_from_x()

        # Variables which hold steps in evolution
        self.x_evolve_half = None
        self.x_evolve = None
        self.k_evolve = None

    def _set_psi_x(self, psi_x):
        assert psi_x.shape == self.x.shape
        self.psi_mod_x = (psi_x * np.exp(-1j * self.k[0] * self.x)
                          * self.dx / np.sqrt(2 * np.pi))
        self.psi_mod_x /= self.norm
        self.compute_k_from_x()

    def _get_psi_x(self):
        return (self.psi_mod_x * np.exp(1j * self.k[0] * self.x)
                * np.sqrt(2 * np.pi) / self.dx)

    def _set_psi_k(self, psi_k):
        assert psi_k.shape == self.x.shape
        self.psi_mod_k = psi_k * np.exp(1j * self.x[0] * self.dk
                                        * np.arange(self.N))
        self.compute_x_from_k()
        self.compute_k_from_x()

    def _get_psi_k(self):
        return self.psi_mod_k * np.exp(-1j * self.x[0] * self.dk
                                        * np.arange(self.N))

    def _get_dt(self):
        return self.dt_

    def _set_dt(self, dt):
        assert dt != 0
        if dt != self.dt_:
            self.dt_ = dt
            self.x_evolve_half = np.exp(-0.5 * 1j * self.V_x
                                         / self.hbar * self.dt)
            self.x_evolve = self.x_evolve_half * self.x_evolve_half
            self.k_evolve = np.exp(-0.5 * 1j * self.hbar / self.m
                                    * (self.k * self.k) * self.dt)

    def _get_norm(self):
        return self.wf_norm(self.psi_mod_x)

    psi_x = property(_get_psi_x, _set_psi_x)
    psi_k = property(_get_psi_k, _set_psi_k)
    norm = property(_get_norm)
    dt = property(_get_dt, _set_dt)

    def compute_k_from_x(self):
        self.psi_mod_k = fftpack.fft(self.psi_mod_x)

    def compute_x_from_k(self):
        self.psi_mod_x = fftpack.ifft(self.psi_mod_k)

    def wf_norm(self, wave_fn):
        """
        Returns the norm of a wave function.

        Parameters
        ----------
        wave_fn : array
            Length-N array of the wavefunction in the position representation
        """
        assert wave_fn.shape == self.x.shape
        return np.sqrt((abs(wave_fn) ** 2).sum() * 2 * np.pi / self.dx)

    def solve(self, dt, Nsteps=1, eps=1e-3, max_iter=1000):
        """
        Propagate the Schrodinger equation forward in imaginary
        time to find the ground state.

        Parameters
        ----------
        dt : float
            The small time interval over which to integrate
        Nsteps : float, optional
            The number of intervals to compute (default = 1)
        eps : float
            The criterion for convergence applied to the norm (default = 1e-3)
        max_iter : float
            Maximum number of iterations (default = 1000)
        """
        eps = abs(eps)
        assert eps > 0
        t0 = self.t
        old_psi = self.psi_x
        d_psi = 2 * eps
        num_iter = 0
        while (d_psi > eps) and (num_iter <= max_iter):
            num_iter += 1
            self.time_step(-1j * dt, Nsteps)
            d_psi = self.wf_norm(self.psi_x - old_psi)
            old_psi = 1. * self.psi_x
        self.t = t0

    def time_step(self, dt, Nsteps=1):
        """
        Perform a series of time-steps via the time-dependent Schrodinger
        Equation.

        Parameters
        ----------
        dt : float
            The small time interval over which to integrate
        Nsteps : float, optional
            The number of intervals to compute.  The total change in time at
            the end of this method will be dt * Nsteps (default = 1)
        """
        assert Nsteps >= 0
        self.dt = dt
        if Nsteps > 0:
            self.psi_mod_x *= self.x_evolve_half
            for num_iter in range(Nsteps - 1):
                self.compute_k_from_x()
                self.psi_mod_k *= self.k_evolve
                self.compute_x_from_k()
                self.psi_mod_x *= self.x_evolve
            self.compute_k_from_x()
            self.psi_mod_k *= self.k_evolve
            self.compute_x_from_k()
            self.psi_mod_x *= self.x_evolve_half
            self.compute_k_from_x()
            self.psi_mod_x /= self.norm
            self.compute_k_from_x()
            self.t += dt * Nsteps

######################################################################
# Helper functions for gaussian wave-packets
def gauss_x(x, a, x0, k0):
    """
    a gaussian wave packet of width a, centered at x0, with momentum k0
    """
    return ((a * np.sqrt(np.pi)) ** (-0.5)
            * np.exp(-0.5 * ((x - x0) * 1. / a) ** 2 + 1j * x * k0))

def gauss_k(k, a, x0, k0):
    """
    analytical fourier transform of gauss_x(x), above
    """
    return ((a / np.sqrt(np.pi)) ** 0.5
            * np.exp(-0.5 * (a * (k - k0)) ** 2 - 1j * (k - k0) * x0))

######################################################################
# Utility functions for running the animation
def theta(x):
    """
    theta function :
      returns 0 if x<=0, and 1 if x>0
    """
    x = np.asarray(x)
    y = np.zeros(x.shape)
    y[x > 0] = 1.0
    return y

def square_barrier(x, width, height):
    return height * (theta(x) - theta(x - width))

######################################################################
# Create the animation

# specify time steps and duration
dt = 0.01
N_steps = 50
t_max = 120
frames = int(t_max / float(N_steps * dt))

# specify constants
hbar = 1.0   # planck's constant
m = 1.9      # particle mass

# specify range in x coordinate
N = 2 ** 11
dx = 0.1
x = dx * (np.arange(N) - 0.5 * N)

# specify potential
V0 = 1.5
L = hbar / np.sqrt(2 * m * V0)
a = 3 * L
x0 = -60 * L
V_x = square_barrier(x, a, V0)
V_x[x < -98] = 1E6
V_x[x > 98] = 1E6

# specify initial momentum and quantities derived from it
p0 = np.sqrt(2 * m * 0.2 * V0)
dp2 = p0 * p0 * 1. / 80
d = hbar / np.sqrt(2 * dp2)

k0 = p0 / hbar
v0 = p0 / m
psi_x0 = gauss_x(x, d, x0, k0)

# define the Schrodinger object which performs the calculations
S = Schrodinger(x=x,
                psi_x0=psi_x0,
                V_x=V_x,
                hbar=hbar,
                m=m,
                k0=-28)

######################################################################
# Set up plot
fig = plt.figure('Quantum Tunneling')

# plotting limits
xlim = (-100, 100)
klim = (-5, 5)

# top axes show the x-space data
ymin = 0
ymax = V0
ax1 = fig.add_subplot(211, xlim=xlim,
                      ylim=(ymin - 0.2 * (ymax - ymin),
                            ymax + 0.2 * (ymax - ymin)))
psi_x_line, = ax1.plot([], [], c='r', label=r'$|\psi(x)|$')
V_x_line, = ax1.plot([], [], c='k', label=r'$V(x)$')
center_line = ax1.axvline(0, c='k', ls=':', label=r"$x_0 + v_0t$")

title = ax1.set_title("")
ax1.legend(prop=dict(size=12))
ax1.set_xlabel('$x$')
ax1.set_ylabel(r'$|\psi(x)|$')

# bottom axes show the k-space data
ymin = abs(S.psi_k).min()
ymax = abs(S.psi_k).max()
ax2 = fig.add_subplot(212, xlim=klim,
                      ylim=(ymin - 0.2 * (ymax - ymin),
                            ymax + 0.2 * (ymax - ymin)))
psi_k_line, = ax2.plot([], [], c='r', label=r'$|\psi(k)|$')

p0_line1 = ax2.axvline(-p0 / hbar, c='k', ls=':', label=r'$\pm p_0$')
p0_line2 = ax2.axvline(p0 / hbar, c='k', ls=':')
mV_line = ax2.axvline(np.sqrt(2 * V0) / hbar, c='k', ls='--',
                      label=r'$\sqrt{2mV_0}$')
ax2.legend(prop=dict(size=12))
ax2.set_xlabel('$k$')
ax2.set_ylabel(r'$|\psi(k)|$')

V_x_line.set_data(S.x, S.V_x)

######################################################################
# Functions to Animate the plot
def init():
    psi_x_line.set_data([], [])
    V_x_line.set_data([], [])
    center_line.set_data([], [])

    psi_k_line.set_data([], [])
    title.set_text("")
    return (psi_x_line, V_x_line, center_line, psi_k_line, title)

def animate(i):
    S.time_step(dt, N_steps)
    psi_x_line.set_data(S.x, 4 * abs(S.psi_x))
    V_x_line.set_data(S.x, S.V_x)
    center_line.set_data(2 * [x0 + S.t * p0 / m], [0, 1])

    psi_k_line.set_data(S.k, abs(S.psi_k))
    return (psi_x_line, V_x_line, center_line, psi_k_line, title)

# call the animator.
# blit=True means only re-draw the parts that have changed.
anim = animation.FuncAnimation(fig, animate, init_func=init,
                               frames=frames, interval=30, blit=True)

# uncomment the following line to save the video in mp4 format.  This
# requires either mencoder or ffmpeg to be installed on your system
# anim.save('schrodinger_barrier.mp4', fps=15,
#          extra_args=['-vcodec', 'libx264'])
plt.tight_layout()
plt.show()


from collections import OrderedDict
import fnmatch
import re

IMAGENET_DEFAULT_MEAN = (0.485, 0.456, 0.406)
IMAGENET_DEFAULT_STD = (0.229, 0.224, 0.225)

DEFAULT_CONFIGS = OrderedDict({
    'ckdn': {
        'metric_opts': {
            'type': 'CKDN',
        },
        'metric_mode': 'FR',
    },
    'lpips': {
        'metric_opts': {
            'type': 'LPIPS',
            'net': 'alex',
            'version': '0.1',
        },
        'metric_mode': 'FR',
        'lower_better': True,
    },
    'lpips-vgg': {
        'metric_opts': {
            'type': 'LPIPS',
            'net': 'vgg',
            'version': '0.1',
        },
        'metric_mode': 'FR',
        'lower_better': True,
    },
    'dists': {
        'metric_opts': {
            'type': 'DISTS',
        },
        'metric_mode': 'FR',
        'lower_better': True,
    },
    'ssim': {
        'metric_opts': {
            'type': 'SSIM',
            'downsample': False,
            'test_y_channel': True,
        },
        'metric_mode': 'FR',
    },
    'psnr': {
        'metric_opts': {
            'type': 'PSNR',
            'test_y_channel': False,
        },
        'metric_mode': 'FR',
    },
    'fsim': {
        'metric_opts': {
            'type': 'FSIM',
            'chromatic': True,
        },
        'metric_mode': 'FR',
    },
    'ms_ssim': {
        'metric_opts': {
            'type': 'MS_SSIM',
            'downsample': False,
            'test_y_channel': True,
            'is_prod': True,
        },
        'metric_mode': 'FR',
    },
    'vif': {
        'metric_opts': {
            'type': 'VIF',
        },
        'metric_mode': 'FR',
    },
    'gmsd': {
        'metric_opts': {
            'type': 'GMSD',
            'test_y_channel': True,
        },
        'metric_mode': 'FR',
        'lower_better': True,
    },
    'nlpd': {
        'metric_opts': {
            'type': 'NLPD',
            'channels': 1,
            'test_y_channel': True,
        },
        'metric_mode': 'FR',
        'lower_better': True,
    },
    'vsi': {
        'metric_opts': {
            'type': 'VSI',
        },
        'metric_mode': 'FR',
    },
    'cw_ssim': {
        'metric_opts': {
            'type': 'CW_SSIM',
            'channels': 1,
            'level': 4,
            'ori': 8,
            'test_y_channel': True,
        },
        'metric_mode': 'FR',
    },
    'mad': {
        'metric_opts': {
            'type': 'MAD',
            'test_y_channel': True,
        },
        'metric_mode': 'FR',
        'lower_better': True,
    },
    'niqe': {
        'metric_opts': {
            'type': 'NIQE',
            'test_y_channel': True,
        },
        'metric_mode': 'NR',
        'lower_better': True,
    },
    'ilniqe': {
        'metric_opts': {
            'type': 'ILNIQE',
        },
        'metric_mode': 'NR',
        'lower_better': True,
    },
    'brisque': {
        'metric_opts': {
            'type': 'BRISQUE',
            'test_y_channel': True,
        },
        'metric_mode': 'NR',
        'lower_better': True,
    },
    'nrqm': {
        'metric_opts': {
            'type': 'NRQM',
        },
        'metric_mode': 'NR',
    },
    'pi': {
        'metric_opts': {
            'type': 'PI',
        },
        'metric_mode': 'NR',
        'lower_better': True,
    },
    'musiq': {
        'metric_opts': {
            'type': 'MUSIQ',
            'pretrained': 'koniq10k'
        },
        'metric_mode': 'NR',
    },
    'musiq-ava': {
        'metric_opts': {
            'type': 'MUSIQ',
            'pretrained': 'ava'
        },
        'metric_mode': 'NR',
    },
    'musiq-koniq': {
        'metric_opts': {
            'type': 'MUSIQ',
            'pretrained': 'koniq10k'
        },
        'metric_mode': 'NR',
    },
    'musiq-paq2piq': {
        'metric_opts': {
            'type': 'MUSIQ',
            'pretrained': 'paq2piq'
        },
        'metric_mode': 'NR',
    },
    'musiq-spaq': {
        'metric_opts': {
            'type': 'MUSIQ',
            'pretrained': 'spaq'
        },
        'metric_mode': 'NR',
    },
    'nima': {
        'metric_opts': {
            'type': 'NIMA',
            'pretrained': 'ava'
        },
        'metric_mode': 'NR',
    },
    'pieapp': {
        'metric_opts': {
            'type': 'PieAPP',
        },
        'metric_mode': 'FR',
        'lower_better': True,
    },
    'paq2piq': {
        'metric_opts': {
            'type': 'PAQ2PIQ',
        },
        'metric_mode': 'NR',
    },
    'dbcnn': {
        'metric_opts': {
            'type': 'DBCNN',
            'pretrained': 'koniq'
        },
        'metric_mode': 'NR',
    },
})

def _natural_key(string_):
    return [int(s) if s.isdigit() else s for s in re.split(r'(\d+)', string_.lower())]

def list_models(filter='', exclude_filters=''):
    """ Return list of available model names, sorted alphabetically
    Args:
        filter (str) - Wildcard filter string that works with fnmatch
        exclude_filters (str or list[str]) - Wildcard filters to exclude models after including them with filter
    Example:
        model_list('*ssim*') -- returns all models including 'ssim'
    """
    all_models = DEFAULT_CONFIGS.keys()
    if filter:
        models = []
        include_filters = filter if isinstance(filter, (tuple, list)) else [filter]
        for f in include_filters:
            include_models = fnmatch.filter(all_models, f)  # include these models
            if len(include_models):
                models = set(models).union(include_models)
    else:
        models = all_models
    if exclude_filters:
        if not isinstance(exclude_filters, (tuple, list)):
            exclude_filters = [exclude_filters]
        for xf in exclude_filters:
            exclude_models = fnmatch.filter(models, xf)  # exclude these models
            if len(exclude_models):
                models = set(models).difference(exclude_models)
    return list(sorted(models, key=_natural_key))


# -*- coding: utf-8 -*-
from django.template.loader import render_to_string
from django.contrib.admin.utils import quote

def get_mptt_admin_node_template(instance):
    '''
    Get MPTT admin node template name by model instance
    :param instance: instance of mptt model
    :return: template name
    '''
    return 'edw/admin/mptt/_%s_node.html' % instance.__class__.__name__.lower()

def mptt_admin_node_info_update_with_template(admin_instance, template, instance, node_info, context={}):
    '''
    Update MPTT admin node with rendered by html template node label.
    :param admin_instance: mptt admin instance
    :param template: template name for renfer
    :param instance: instance of mptt model
    :param node_info: jstree node info
    :param context: additional context for render
    :return: none
    '''

    pk_attname = admin_instance.model._meta.pk.attname
    pk = quote(getattr(instance, pk_attname))

    context.update({
        'instance': instance,
        'node_info': node_info,
        'app_label': instance._meta.app_label.lower()
    })

    label = render_to_string(template, context)

    node_info.update(
        url=admin_instance.get_admin_url('change', (quote(pk),)),
        move_url=admin_instance.get_admin_url('move', (quote(pk),)),
        label=label,
    )


import pandas as pd
from pulp import *
import itertools

df = pd.read_excel('beers.xlsx')

costs = df.\
    assign(Warehouse_to_Bar = lambda x: x.Warehouse_to_Bar.astype(str)).\
        set_index('Warehouse_to_Bar').\
            to_dict()

warehouses = ['A','B']
bars = [str(x) for x in range(1,6)]

supply_ = [1000,4000]
demand_ = [500,900,1800,200,700]

supply = dict(zip(warehouses,supply_))
demand = dict(zip(bars, demand_))

routes = list(itertools.product(warehouses,bars))

'''
dv : how many beers for every warehouse - bar pair
obj : minimize dv * cost
1) supply : sum of beers leaving a warehouse <= supply
2) demand : sum of beers reaching a bar == demand
'''

# instantiate minimization problem
prob = LpProblem('Beer_Transportation', LpMinimize)

# define decision variables
decision_vars = LpVariable.dicts('routes',(warehouses,bars),0,None,LpInteger)

# define objective function
prob += lpSum([decision_vars[w][b] * costs[w][b] for w,b in routes])

# define supply constrains
for w in warehouses:
    prob += lpSum([decision_vars[w][b] for b in bars]) <= supply[w]

# define demand constrains
for b in bars:
    prob += lpSum([decision_vars[w][b] for w in warehouses]) >= demand[b]

# solve problem
prob.solve()

# The status of the solution is printed to the screen
print("Status:", LpStatus[prob.status])

# print out solution
for w in warehouses:
    for b in bars:
        if value(decision_vars[w][b]):
            print(f'from {w} to {b} - {value(decision_vars[w][b])}')


#######################################################################
# Necessaria a instalacao do biopython (pip install biopython)
from Bio import pairwise2
from Bio.pairwise2 import format_alignment
from Bio.Seq import Seq

def alinhamento(seqt, numseq):
    nome1 = "guilherme"
    nome2 = "costa"
    nome3 = "oliveira"

    dicionario = {"q":1, "w":2, "e":3, "r":4, "t":5, "y":6, "u":7, "i":8, "o":9, "p":10, "á":11, "ã":12,
                "a":11, "s":9, "d":7, "f":5, "g":3, "h":1, "j":11, "k":9, "l":7, "ç":5, "é":3, "í":1,
                "z":2,  "x":4, "c":6, "v":8, "b":10, "n":12, "m":2, "ó":4, "õ":6, "ô":8, "ẫ":10, "ê":12}

    #Funcao para transformar o primeiro nome em numeros
    def converte(x):
        for l in dicionario:
            x = x.replace(l, str(dicionario[l]))
        return x

    nome1 = converte(nome1)     #O primeiro nome
    nome1 = int(nome1)
    resto1 = nome1 % 3

    if resto1 == 0:
        alpha = 1
        beta = 0
        delta = -1

    elif resto1 == 1:
        alpha = 2
        beta = 0
        delta = -1

    elif resto1 == 2:
        alpha = 1
        beta = 0
        delta = -2

    nome2 = converte(nome2)
    nome2 = int(nome2)              #O último nome
    pref_gap = nome2 % 3

    nome3 = converte(nome3)
    nome3 = int(nome3)             #O nome do meio
    gap_js = nome3 % 2

    score = 0
    scoreaux = 0
    count1 = 0
    count2 = 0

    n = numseq     # numero de sequencias
    k = 0
    scoretotal = 0

    while n > 0:
        if n == numseq:# eh reduzido 0.5 do score a cada gap consecutivo, ou seja, as sequencias com gaps separados podem ter maior score, assim cumprindo a condicao de que os gaps sejam separados
            alignments = pairwise2.align.globalms(seqt[k], seqt[k + 1], alpha, beta, delta, -0.5)
            for alignment in alignments:
                if count1 == 0:
                    seqt[k] = alignment.seqA
                    seqt[k + 1] = alignment.seqB
                    score = alignment.score
                    count1 = count1 + 1
                else:
                    if alignment.score >= score:
                        seqt[k] = alignment.seqA
                        seqt[k + 1] = alignment.seqB
                        score = alignment.score
            n = n - 2
            k = k + 1
            scoretotal = scoretotal + alignment.score
        else:
            alignments = pairwise2.align.globalms(seqt[k], seqt[k + 1], alpha, beta, delta, -0.5)
            for alignment in alignments:
                if count2 == 0:
                    seqt[k] = alignment.seqA
                    seqt[k + 1] = alignment.seqB
                    scoreaux = alignment.score
                    count2 = count2 + 1
                else:
                    if alignment.score >= scoreaux:
                        seqt[k] = alignment.seqA
                        seqt[k + 1] = alignment.seqB
                        scoreaux = alignment.score
            n = n - 2
            k = k + 1
            scoretotal = scoretotal + alignment.score
    scoretotal = "Score Total: " + str(scoretotal)
    seqt.append(scoretotal)
    return seqt


import socket
import struct
import subprocess
import logging
from datetime import datetime

# Configuração do cliente
MULTICAST_IP = '224.0.0.1'
MULTICAST_PORT = 5004
CHUNK_SIZE = 1472  # Tamanho do pacote incluindo 4 bytes para o contador
CLIENT_INTERFACE_IP = '0.0.0.0'  # Use o IP de interface apropriado se necessário
PACKETS_RECEIVED = 0

# Configuração do logging
log_filename = datetime.now().strftime("cliente_%H%M%S.txt")
logging.basicConfig(filename=log_filename,
                    filemode='w',
                    level=logging.DEBUG,
                    format='CLIENTE - %(asctime)s - %(levelname)s - %(message)s')

# Criar um socket UDP
client_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
logging.info("Socket criado.")

# Permitir múltiplos clientes na mesma máquina (para fins de teste)
client_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
logging.info("Socket configurado para permitir múltiplos clientes.")

# Vincular ao endereço do servidor
client_sock.bind((CLIENT_INTERFACE_IP, MULTICAST_PORT))
logging.info(f"Socket vinculado a {CLIENT_INTERFACE_IP}:{MULTICAST_PORT}.")

# Dizer ao sistema operacional para adicionar o socket ao grupo multicast
group = socket.inet_aton(MULTICAST_IP) + socket.inet_aton(CLIENT_INTERFACE_IP)
client_sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, group)
logging.info(f"Socket adicionado ao grupo multicast {MULTICAST_IP}.")

# Inicializar contadores
expected_packet_counter = None
lost_packets = 0
out_of_order_packets = 0

# Preparar comando subprocess para VLC
vlc_command = "vlc -"  # O traço '-' diz ao VLC para aceitar entrada do stdin

# Iniciar VLC como um subprocesso
vlc_process = subprocess.Popen(["vlc", "fd://0"], stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
logging.info("Processo VLC iniciado.")
logging.info("Iniciando loop de recebimento de pacotes.")

try:
    while True:
        # Receber pacote
        data, address = client_sock.recvfrom(CHUNK_SIZE)

        # Verificar pacote "fim-de-stream"
        if data[4:] == b'END_OF_STREAM':
            PACKETS_RECEIVED += 1
            logging.info("Fim do stream detectado, redefinindo contador.")
            expected_packet_counter = None
            continue

        # Extrair contador de pacotes
        packet_counter, = struct.unpack('>I', data[:4])
        video_data = data[4:]

        # Se for o primeiro pacote ou se for o pacote esperado
        if expected_packet_counter is None or packet_counter == expected_packet_counter:
            PACKETS_RECEIVED += 1
            # Atualiza o contador esperado para o próximo pacote
            if expected_packet_counter is None:
                logging.info(f"Primeiro pacote recebido com contador {packet_counter}")
            expected_packet_counter = (packet_counter + 1) % (2 ** 32)
        else:
            if packet_counter < expected_packet_counter:
                PACKETS_RECEIVED += 1
                # Pacote fora de ordem
                out_of_order_packets += 1
                logging.warning(f"Pacote fora de ordem. Esperado: {expected_packet_counter}, Recebido: {packet_counter}")
            else:
                # Pacotes perdidos
                lost_packets += packet_counter - expected_packet_counter
                expected_packet_counter = (packet_counter + 1) % (2 ** 32)
                if lost_packets > 0:  # Registra apenas se houver pacotes perdidos
                    logging.warning(f"Pacotes perdidos. Esperado: {expected_packet_counter-1}, Recebido: {packet_counter}")

            # Definir o próximo contador de pacote esperado
            expected_packet_counter = (packet_counter + 1) % (2 ** 32)

        # Escrever os dados do vídeo no stdin do VLC
        vlc_process.stdin.write(video_data)

except KeyboardInterrupt:
    logging.info("Cliente encerrando por KeyboardInterrupt.")
    logging.info(f"Pacotes recebidos: {PACKETS_RECEIVED}")

finally:
    # Fechar processo VLC
    if vlc_process:
        vlc_process.terminate()
        logging.info("Processo VLC terminado.")

    # Fechar o socket
    client_sock.close()
    logging.info("Socket fechado.")

    # Logar estatísticas finais
    logging.info(f"Total de pacotes perdidos: {lost_packets}. Total de pacotes fora de ordem: {out_of_order_packets}.")


import cv2
import numpy as np
import glob
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph.opengl as gl
import numpy as np
from time import sleep

dis_test_label = np.load("D:/PythonFile/NestProject/Nest_Model/pos_process/test_data/dis_test_data_complex_exp_shuffle_3.npy")
dis_test_predict = np.load('D:/PythonFile/NestProject/Nest_Model/pos_process/prediction_data/predict_data_complex_exp_shuffle_3.npy')

dis_train_label = np.load("D:/NestData/3tx-32chirp-jaco-55times_all/data_usage/radar_pos_label_deleted.npy")
dis_train_predict = np.load('D:/PythonFile/NestProject/Nest_Model/pos_process/prediction_data/predict_data_complex_exp_shuffle_4(train).npy')

# dis_label = np.concatenate((label1, label2))
print(dis_train_label.shape, dis_test_predict.shape)

app = QtGui.QApplication([])
w = gl.GLViewWidget()
w.show()
g = gl.GLGridItem()
w.addItem(g)

colors_1 = [1.0,0,0,0.5]
colors_2 = [0,1.0,0,0.5]

# dis_test_predict = dis_test_predict[:,0,:]

dis_test_label = dis_test_label/100
dis_test_predict = dis_test_predict/100
dis_train_label = dis_train_label/100
dis_train_predict = dis_train_predict/100
dis_train_label = dis_train_label[:500]

# dis_test_label = dis_test_label[:,1:3]
# dis_predict = dis_predict[:,1:3]
# print(dis_test_label.shape)

# sp0 = gl.GLScatterPlotItem(pos=dis_test_label[:], color=colors_1)
# w.addItem(sp0)

# sp1 = gl.GLScatterPlotItem(pos=dis_test_predict[:])
# w.addItem(sp1)

sp2 = gl.GLScatterPlotItem(pos=dis_train_label[:], color=colors_2)
w.addItem(sp2)

# sp3 = gl.GLScatterPlotItem(pos=dis_train_predict[:])
# w.addItem(sp3)

# i = 0
# def update():

#     global i

#     sp2 = gl.GLScatterPlotItem(pos=dis_train_label[i], color=colors_1)
#     w.addItem(sp2)

#     # sp3 = gl.GLScatterPlotItem(pos=dis_test_predict[i])
#     # w.addItem(sp3)
#     print(i)
#     i += 1

# time = QtCore.QTimer()
# time.timeout.connect(update)
# time.start(5)

if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()


from transformers import BertForTokenClassification, BertJapaneseTokenizer, get_linear_schedule_with_warmup
from flask import Flask, render_template, request
import argparse
import json
from predict import predict
import torch
import sys
from pathlib import Path
base_dir = Path(__file__).resolve().parents[1]
sys.path.append(str(base_dir))

from utils import iob2json

device = 'cuda' if torch.cuda.is_available() else 'cpu'

app = Flask(__name__)

@app.route("/", methods=['POST'])
def index():
    word = request.form["text"]
    input_json = json.loads(word)
    input_x = [input_json[str(i)] for i in range(len(input_json))]
    input_x = [tokenizer.tokenize(t) for t in input_x]
    input_x = [tokenizer.convert_tokens_to_ids(['[CLS]'] + x) for x in input_x]
    tags = predict(model, input_x,  device)

    labels = [[id2label[t] for t in tag] for tag in tags]
    input_x = [tokenizer.convert_ids_to_tokens(t)[1:] for t in input_x]

    output = [zip(x, l) for x, l in zip(input_x, labels)]
    output = [iob2json.decode_iob(i) for i in output]

    return iob2json.create_json(output)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Train BERT')
    parser.add_argument('--model_dir', type=str, help='data path')
    args = parser.parse_args()

    tokenizer = BertJapaneseTokenizer.from_pretrained("bert-base-japanese-char")

    with open(args.model_dir + '/label_vocab.json', 'r') as f:
        label_vocab = json.load(f)
    id2label = {v:k for k, v in label_vocab.items()}

    model = BertForTokenClassification.from_pretrained('bert-base-japanese-char', num_labels=len(label_vocab))

    model_path = args.model_dir + '/final.model'
    model.load_state_dict(torch.load(model_path))

    app.run(port='8000', host='0.0.0.0', debug=True)


# Debugging script to see how much GPS signal bounced around
import csv
import math
import numpy as np
from matplotlib import pyplot as plt

'''
# distance between points
dx_between_pts = []

prev_lat, prev_long = 0, 0
with open('2_2_23_gps.csv', mode ='r') as f:
  csv_f = csv.reader(f)
  for i, line in enumerate(csv_f):
    # column/header line (e.g. "time, lat, long, alt")
    if i == 0:
      continue
    lat, long = float(line[1]), float(line[2])
    if prev_lat != 0:
      dlat = lat - prev_lat
      dlong = long - prev_long
      dx = (dlat**2 + dlong**2) ** .5
      if not math.isnan(dx):
        dx_between_pts.append(dx)
    prev_lat = lat
    prev_long = long

dx_min = min(dx_between_pts)
dx_max = max(dx_between_pts)
print("max: ", dx_max, " min: ", dx_min)
dx_sorted = np.sort(dx_between_pts)
plt.plot(dx_sorted)
assert dx_sorted[0] == dx_min, f"{dx_sorted[0]} != {dx_min}"
assert dx_sorted[-1] == dx_max, f"{dx_sorted[-1]} != {dx_max}"
plt.show()
'''

#################
### Phone GPS ###
#################
import gpxpy
import gpxpy.gpx

gpx_file = open('phone_gps.gpx', 'r')
gpx = gpxpy.parse(gpx_file)

prev_lat, prev_long = 0, 0

dx_between_pts = []
for track in gpx.tracks:
  for segment in track.segments:
    for point in segment.points:
      lat, long = point.latitude, point.longitude
      if prev_lat != 0:
        dlat = lat - prev_lat
        dlong = long - prev_long
        dx = (dlat**2 + dlong**2) ** .5
        if not math.isnan(dx):
          dx_between_pts.append(dx)
      prev_lat = lat
      prev_long = long

dx_min = min(dx_between_pts)
dx_max = max(dx_between_pts)
print("max: ", dx_max, " min: ", dx_min)
dx_sorted = np.sort(dx_between_pts)
plt.plot(dx_sorted)
assert dx_sorted[0] == dx_min, f"{dx_sorted[0]} != {dx_min}"
assert dx_sorted[-1] == dx_max, f"{dx_sorted[-1]} != {dx_max}"
plt.show()

'''
# Creating histogram
fig, ax = plt.subplots(figsize = (10, 7))
min_dx = min(dx_between_pts)
max_dx = max(dx_between_pts)
bin_width = (max_dx - min_dx) / 5
ax.hist(dx_between_pts, bins = np.arange(min_dx, max_dx, bin_width))
# Show plot
plt.show()
'''


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Mar 16 19:35:10 2020

@author: isaacparker
"""

#Load libraries
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import pandas as pd
from scipy.stats import lognorm, gaussian_kde

# Specify font used in plots
font = 'Adobe Myungjo Std'
math_font = 'cm'

import matplotlib as mpl
mpl.style.use('seaborn-white')
mpl.rcParams['font.family'] = font
mpl.rcParams['font.size'] = 18
mpl.rcParams['mathtext.fontset'] = 'cm'

#LOAD DATA
JV_exp = np.loadtxt('perov_JV_exp.txt',delimiter=',')
JV_exp = JV_exp

v_sweep = np.linspace (0,1.2,100)
power_exp= JV_exp[:,100*2:100*3]*v_sweep
eff_exp = np.max(power_exp, axis=1)/0.98

exp_condition = pd.read_excel('prcess_label.xlsx',index_col=0)
exp_condition = exp_condition.values

#Stack data and order
X_data = np.concatenate([eff_exp.reshape(-1,1), exp_condition],axis= 1)

p_index = []
X_data_re=[]
for i in [70,90,110,130]:
    for j in [2,4,8]:
        idx = np.intersect1d(np.where(X_data[:,1]==i) ,np.where(X_data[:,2]==j))
        X_data_re.append(X_data[idx,:])

X_data_re = np.vstack(X_data_re)

#Remove data to have same # of samples:
X_data_re = np.delete(X_data_re, [0,15,21,13,14,10,12,17,12,9,7,4], 0)
X_data_re = np.insert(X_data_re, 36, [3.88, 90, 2], axis=0)
X_data_re = np.delete(X_data_re, [106,107,108,96,110,112], 0)
X_data_re = np.insert(X_data_re, 143, [5.77, 130, 8], axis=0)

# Compute efficiency and normalize
df_X1 = pd.DataFrame(X_data_re, columns=['Efficiency','Temperature','Ratio'])

df_X = df_X1.copy()

max_eff = df_X['Efficiency'].max()

# Normalize
df_X['Efficiency'] = df_X['Efficiency'] / max_eff

# Get mean and variance for empirical distribution
X_mean = df_X['Efficiency'].mean()
eff_data = df_X['Efficiency']

log_norm_var = eff_data.std()

# Lognormal distribution histogram
np.random.seed(6)
logn = lognorm(s=1*log_norm_var, scale = 0.7*(1-X_mean))
sample = logn.rvs (size=500)
sample[sample>1]= 1
plt.figure()
plt.hist((1-sample)*20,50,
         density=True,
         edgecolor='white',
         linewidth=1.2,
         # color='mediumseagreen',
         # alpha=0.5)
         # color=(60/255, 110/255, 135/255, 0.8))
         color='k',
         alpha=0.5)
plt.xlabel(r'Solar Cell Efficiency $\eta$ [%]', size=18, fontname=font)
plt.ylabel(r'Probability $p(\eta)$', size=18, fontname=font)
plt.xlim(left=0, right=20)
plt.yticks(np.arange(0, 0.25, step=0.1))

density = gaussian_kde((1-sample)*20)
xs = np.linspace(0,20,50)
density.covariance_factor = lambda : 1*log_norm_var
density._compute_covariance()
plt.plot(xs,density(xs),
         # color=(60/255, 110/255, 135/255))
         # color='mediumseagreen')
         color='k')
plt.tight_layout()
plt.savefig('Fig1.png',dpi=300)
plt.show()


from matplotlib import pyplot as plt

# 题目：某月气温变化表

# 知识点总结：
# 1.x,y的输入
# 2.绘制  plt.plot()
# 3.设置图片大小 plt.figure()
# 4，保存到本地 plt.savefig()
# 5.描述信息 xlabel() ylable() title()
# 6.调整x，y的间距 xticks(),yticks()
# 7.线条的样式 linestyle=
# 8.标记出特殊的点
# 9.添加水印

# 设置图片大小
plt.figure(figsize=(16, 8), dpi=80)

# 左闭右开
x = range(2, 26, 2)
y = [15, 13, 14.5, 17, 20, 25, 26, 26, 24, 22, 18, 15]

# 传入x，y通过plot绘制出折线图
plt.plot(x, y)

# 设置x，y轴的刻度
# plt.xticks(x)
# plt.xticks(range(2, 25))
num = []
for i in range(2, 25):
    num.append(i)
    num.append(i + 0.5)
# plt.xticks(num[::3])

num = [i / 2 for i in range(4, 50)]
plt.xticks(num)
plt.yticks(range(min(y), max(y) + 1))

# 保存
# plt.savefig("./SaveDate/p1.png")

# 输出
plt.show()

# 关于range：
# 在 Python 3 中，range() 函数返回的对象并不是列表，而是一个类型为 range 的可迭代对象（iterable），
# 它按需生成指定范围内的整数。这种方式称为“惰性求值”（lazy evaluation），它可以节省空间和时间。

# 因为 range 对象并不是列表，所以它并不占用与列表相同的内存空间。
# 相反，它只需要存储 start、stop 和 step 这三个参数，以及根据这些参数生成整数序列的算法。

# 当使用 range 对象时，Python 会根据需要逐个生成序列中的元素，而不是一次性生成所有元素并存储在内存中。

# 如果您需要将 range 对象转换为列表，可以使用 list() 函数将其转换为列表


import numpy as np
import pytest

from gym.spaces import Box, Discrete
from gym.wrappers import AtariPreprocessing, StepAPICompatibility
from tests.testing_env import GenericTestEnv, old_step_fn

class AleTesting:
    """A testing implementation for the ALE object in atari games."""

    grayscale_obs_space = Box(low=0, high=255, shape=(210, 160), dtype=np.uint8, seed=1)
    rgb_obs_space = Box(low=0, high=255, shape=(210, 160, 3), dtype=np.uint8, seed=1)

    def lives(self) -> int:
        """Returns the number of lives in the atari game."""
        return 1

    def getScreenGrayscale(self, buffer: np.ndarray):
        """Updates the buffer with a random grayscale observation."""
        buffer[...] = self.grayscale_obs_space.sample()

    def getScreenRGB(self, buffer: np.ndarray):
        """Updates the buffer with a random rgb observation."""
        buffer[...] = self.rgb_obs_space.sample()

class AtariTestingEnv(GenericTestEnv):
    """A testing environment to replicate the atari (ale-py) environments."""

    def __init__(self):
        super().__init__(
            observation_space=Box(
                low=0, high=255, shape=(210, 160, 3), dtype=np.uint8, seed=1
            ),
            action_space=Discrete(3, seed=1),
            step_fn=old_step_fn,
        )
        self.ale = AleTesting()

    def get_action_meanings(self):
        """Returns the meanings of each of the actions available to the agent. First index must be 'NOOP'."""
        return ["NOOP", "UP", "DOWN"]

@pytest.mark.parametrize(
    "env, obs_shape",
    [
        (AtariTestingEnv(), (210, 160, 3)),
        (
            AtariPreprocessing(
                StepAPICompatibility(AtariTestingEnv(), output_truncation_bool=True),
                screen_size=84,
                grayscale_obs=True,
                frame_skip=1,
                noop_max=0,
            ),
            (84, 84),
        ),
        (
            AtariPreprocessing(
                StepAPICompatibility(AtariTestingEnv(), output_truncation_bool=True),
                screen_size=84,
                grayscale_obs=False,
                frame_skip=1,
                noop_max=0,
            ),
            (84, 84, 3),
        ),
        (
            AtariPreprocessing(
                StepAPICompatibility(AtariTestingEnv(), output_truncation_bool=True),
                screen_size=84,
                grayscale_obs=True,
                frame_skip=1,
                noop_max=0,
                grayscale_newaxis=True,
            ),
            (84, 84, 1),
        ),
    ],
)
def test_atari_preprocessing_grayscale(env, obs_shape):
    assert env.observation_space.shape == obs_shape

    # It is not possible to test the outputs as we are not using actual observations.
    # todo: update when ale-py is compatible with the ci

    env = StepAPICompatibility(
        env, output_truncation_bool=True
    )  # using compatibility wrapper since ale-py uses old step API

    obs, _ = env.reset(seed=0)
    assert obs in env.observation_space

    obs, _, _, _, _ = env.step(env.action_space.sample())
    assert obs in env.observation_space

    env.close()

@pytest.mark.parametrize("grayscale", [True, False])
@pytest.mark.parametrize("scaled", [True, False])
def test_atari_preprocessing_scale(grayscale, scaled, max_test_steps=10):
    # arbitrarily chosen number for stepping into env. and ensuring all observations are in the required range
    env = AtariPreprocessing(
        StepAPICompatibility(AtariTestingEnv(), output_truncation_bool=True),
        screen_size=84,
        grayscale_obs=grayscale,
        scale_obs=scaled,
        frame_skip=1,
        noop_max=0,
    )

    obs, _ = env.reset()

    max_obs = 1 if scaled else 255
    assert np.all(0 <= obs) and np.all(obs <= max_obs)

    terminated, truncated, step_i = False, False, 0
    while not (terminated or truncated) and step_i <= max_test_steps:
        obs, _, terminated, truncated, _ = env.step(env.action_space.sample())
        assert np.all(0 <= obs) and np.all(obs <= max_obs)

        step_i += 1
    env.close()


from fbchat import *
from fbchat.models import *
from Credentials import *
import json
import requests
import re
import os
import time
from threading import Thread
import socket

def finalVerification(url):
    if re.search("homework-help", url):
        return True
    return False

def question_id(url):
    try:
        ID = ""
        i = len(url) - 1
        while i > 0:
            if url[i] != "q":
                ID = url[i] + ID
            else:
                return "q" + ID
            i -= 1
    except Exception:
        return "QUESTION ID ERROR"

def verifyURL(url):
    try:
        response = requests.head(url)
        print(response.status_code)
        if response.status_code == 404:
            print("Bad website.")
            return False
        return True
    except Exception:
        print("Bad website")
        return False

def isAnswered(url):
    id = question_id(url)
    for root, dirs, files in os.walk("./screenshots"):
        for name in files:
            if name == id + ".png":
                return True
        return False

class CustomClient(Client):

    def onMessage(self, mid, author_id, message, message_object, thread_id, thread_type, ts, metadata, msg):
        global daily_limit, start_time

        def respond(text, msgType=None):
            if thread_type == thread_type.GROUP:
                if msgType is None:
                    self.send(Message(text=text), thread_id=thread_id, thread_type=thread_type)
                elif msgType == "IMAGE":
                    self.sendLocalImage(text, thread_id=thread_id, thread_type=thread_type)
            elif thread_type == thread_type.USER:
                if msgType is None:
                    self.send(Message(text=text), thread_id=author_id, thread_type=thread_type)
                elif msgType == "IMAGE":
                    self.sendLocalImage(text, thread_id=author_id, thread_type=thread_type)

        def collectPNG():
            global que_position, socket, recent_call
            que_position += 1
            print("Started a thread to collect {}".format(question_id(message)))
            respond("You have {} new questions left. Approximate retrieval time: {:.0F} seconds".format(daily_limit[author_id], que_position*10 + 1*max(0, 25-(time.time()-recent_call)) + (que_position-1)*25))

            while que_position-1 != 0 or time.time() - recent_call < 25:
                time.sleep(0.1)

            socket.sendto(message.encode(), ("127.0.0.1", 5000))
            recent_call = time.time()
            print("Request sent to AnswerMe")
            started = time.time()
            while time.time() - started < 15:
                if os.path.exists("./screenshots/" + question_id(message) + ".png"):
                    respond("./screenshots/" + question_id(message) + ".png", "IMAGE")
                    que_position -= 1
                    return
            respond("Error: Timed out.")

        if time.time() - start_time > 86400:
            start_time = time.time()
            daily_limit = {}
        print(message_object)
        if author_id != self.uid:
            if re.search("CHEGG", message):
                message = message.replace("CHEGG", "").strip()
                if verifyURL(message) and finalVerification(message):
                    respond("Your question {} is being processed.".format(question_id(message)))
                    if isAnswered(message):
                        respond("The question has been identified in Steve's data base.")
                        respond("./screenshots/" + question_id(message) + ".png", "IMAGE")
                    elif author_id in daily_limit and daily_limit[author_id] > 0 or author_id not in daily_limit:
                        if author_id not in daily_limit:
                            daily_limit[author_id] = 4
                        daily_limit[author_id] -= 1
                        Thread(target=collectPNG).start()
                    else:
                        respond(
                            "You have asked too many questions today. Please wait {:.2f} minute(s) to ask more questions!".format(
                                (86400 - (time.time() - start_time)) / 60))
                else:
                    respond("Invalid URL. Please type in a correct link.")

class MessengerBot:
    def __init__(self):
        self.client = None

    def login(self, username, password):
        if self.client is None:
            cookies = None
            try:
                with open("session.json") as file:
                    cookies = json.load(file)
                    print("Loading session cookies...")

            except FileNotFoundError:
                print("First time logging in...")

            self.client = CustomClient(username, password, session_cookies=cookies)
            print("Is logged in? {}".format(self.client.isLoggedIn()))

            if cookies is None:
                with open("session.json", "w") as file:
                    json.dump(self.client.getSession(), file)

    def listen(self):
        print("Listening")
        self.client.listen()

if __name__ == "__main__":
    while True:
        try:
            socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            que_position = 0
            start_time = time.time()
            recent_call = 0
            daily_limit = {}
            bot = MessengerBot()
            bot.login(username, passwd)
            bot.listen()
        except Exception:
            continue


import os
import json
import psycopg2
import psycopg2.extras
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity

model = SentenceTransformer('distilbert-base-nli-mean-tokens')

alpha = 0.9

#Function that will take a list of goals and goal ids and output the similar goals
def my_calc_similarity(list_of_goals, list_of_ids):
    sentence_embeddings = model.encode(list_of_goals)
    #I want to turn this into a matrix of cosine similarity scores
    sim_scores = cosine_similarity(sentence_embeddings)
    #Set up a list to hold the potential matches goal ids
    match_goal_ids = [[] for x in range(len(list_of_goals))]
    for j in range(len(list_of_goals)):
        #ignore the diagnol entry
        cur_sim_scores = sim_scores[j]
        cur_sim_scores[j] = 0
        #index where greater than alpha
        cur_potential_idx = [i for i,v in enumerate(cur_sim_scores) if v > alpha]
        for k in range(len(cur_potential_idx)):
            #Need to append the goal ID to the list
            match_goal_ids[j].append(list_of_ids[cur_potential_idx[k]])
            if j > cur_potential_idx[k]:
                continue
            #Print the current goals as potential matches
            print("Potential Match: Goals ", j," and ", cur_potential_idx[k])
            print("Potential Match: Goal ", j, ": ", list_of_goals[j],". and Goal ", cur_potential_idx[k],": ", list_of_goals[cur_potential_idx[k]])
    return(match_goal_ids)

conn = connect_to_db()
cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
cur.execute("SELECT * FROM public.goals;")
rows = cur.fetchall()

cur_goals_list = [row['goal'] for row in rows]
cur_goal_ids = [row['id'] for row in rows]

match_ids = my_calc_similarity(cur_goals_list,cur_goal_ids)