I am trying to write my report and I have this problem with natbib package.
I am using overleaf and I am getting the same error:
LaTeX Error: Can be used only in preamble.
See the LaTeX manual or LaTeX Companion for explanation. Type H
for immediate help. ...
l.168 \bibliography
{references}
What i am doing wrong?
This my code:
\documentclass[12pt,letterpaper]{article}
\usepackage[utf8]{inputenc}
\usepackage[spanish, es-tabla]{babel}
\usepackage[version=3]{mhchem}
\usepackage[journal=jacs]{chemstyle}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{makeidx}
\usepackage[usenames,dvipsnames,svgnames,table]{xcolor}
\usepackage[stable]{footmisc}
\usepackage[section]{placeins}
%Paquetes necesarios para tablas
\usepackage{longtable}
\usepackage{array}
\usepackage{xtab}
\usepackage{multirow}
\usepackage{colortab}
%Paquete para el manejo de las unidades
\usepackage{siunitx}
\sisetup{mode=text, output-decimal-marker = {,}, per-mode = symbol, qualifier-mode = phrase, qualifier-phrase = { de }, list-units = brackets, range-units = brackets, range-phrase = --}
\DeclareSIUnit[number-unit-product = \;] \atmosphere{atm}
\DeclareSIUnit[number-unit-product = \;] \pound{lb}
\DeclareSIUnit[number-unit-product = \;] \inch{"}
\DeclareSIUnit[number-unit-product = \;] \foot{ft}
\DeclareSIUnit[number-unit-product = \;] \yard{yd}
\DeclareSIUnit[number-unit-product = \;] \mile{mi}
\DeclareSIUnit[number-unit-product = \;] \pint{pt}
\DeclareSIUnit[number-unit-product = \;] \quart{qt}
\DeclareSIUnit[number-unit-product = \;] \flounce{fl-oz}
\DeclareSIUnit[number-unit-product = \;] \ounce{oz}
\DeclareSIUnit[number-unit-product = \;] \degreeFahrenheit{\SIUnitSymbolDegree F}
\DeclareSIUnit[number-unit-product = \;] \degreeRankine{\SIUnitSymbolDegree R}
\DeclareSIUnit[number-unit-product = \;] \usgallon{galón}
\DeclareSIUnit[number-unit-product = \;] \uma{uma}
\DeclareSIUnit[number-unit-product = \;] \ppm{ppm}
\DeclareSIUnit[number-unit-product = \;] \eqg{eq-g}
\DeclareSIUnit[number-unit-product = \;] \normal{\eqg\per\liter\of{solución}}
\DeclareSIUnit[number-unit-product = \;] \molal{\mole\per\kilo\gram\of{solvente}}
\usepackage{cancel}
%Paquetes necesarios para imágenes, pies de página, etc.
\usepackage{graphicx}
\usepackage{lmodern}
\usepackage{fancyhdr}
\usepackage[left=4cm,right=2cm,top=3cm,bottom=3cm]{geometry}
\usepackage{xcolor,soul,framed} %,caption
\colorlet{shadecolor}{yellow}
%Instrucción para evitar la indentación
%\setlength\parindent{0pt}
%Paquete para incluir la bibliografía
\usepackage[backend=bibtex,style=chem-acs,biblabel=dot]{biblatex}
\addbibresource{references.bib}
%Formato del título de las secciones
\usepackage{titlesec}
\usepackage{enumitem}
\titleformat*{\section}{\bfseries\large}
\titleformat*{\subsection}{\bfseries\normalsize}
%Creación del ambiente anexos
\usepackage{float}
\floatstyle{plaintop}
\newfloat{anexo}{thp}{anx}
\floatname{anexo}{Anexo}
\restylefloat{anexo}
\restylefloat{figure}
%Modificación del formato de los captions
\usepackage[margin=10pt,labelfont=bf]{caption}
%Paquete para incluir comentarios
\usepackage{todonotes}
%Paquete para incluir hipervínculos
\usepackage[colorlinks=true,
linkcolor = blue,
urlcolor = blue,
citecolor = black,
anchorcolor = blue]{hyperref}
\definecolor{mygreen}{rgb}{0,0.6,0}
\definecolor{mygray}{rgb}{0.5,0.5,0.5}
\definecolor{mymauve}{rgb}{0.58,0,0.82}
\definecolor{darkWhite}{rgb}{0.94,0.94,0.94}
\usepackage{minted}
%%%%%%%%%%%%%%%%%%%%%%
%Inicio del documento%
%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
%TXT
\bibliography{references}
\end{document}
Thank you for your help!
I find the solution, the syntax should be:
\begin{document}
....
\printbibliography
\end{document}
Related
I do not understand why my program does not work, try everything and does not work, the program is to calculate the total amount to pay.
adultomayor = 2500
adulto = 6000
niños = 1500
infantes = 0
amayor int(input("Ingrese la cantidad de entradas de adulto mayor: "))
aadulto int(input("Ingrese la cantidad de entradas de adulto: "))
aniños int(input("Ingrese la cantidad de entradas de niños: "))
ainfantes int(input("Ingrese la cantidad de entradas de infantes: "))
total = amayor * adultomayor + aadulto * adulto + aniños * niños + ainfantes * infantes
print("El valor a pagar es: " total)
You Missed some equals,
adultomayor = 2500
adulto = 6000
niños = 1500
infantes = 0
amayor = input("Ingrese la cantidad de entradas de adulto mayor: ")
aadulto = input("Ingrese la cantidad de entradas de adulto: ")
aniños = input("Ingrese la cantidad de entradas de niños: ")
ainfantes = input("Ingrese la cantidad de entradas de infantes: ")
total = int(amayor) * adultomayor + int(aadulto) * adulto + int(aniños) * niños + int(ainfantes) * infantes
print("El valor a pagar es: " + str(total))
I am trying to load and delete images when loading an image I create a status bar to tell me the name of the file and if I delete it, the bar is cleaned, I get this error and I do not know what it may be, luckily they load me the images but in the console, it throws me that error and it does not show me the status bar (I leave part of the code), thanks...
Error
Traceback (most recent call last): File "lol.py", line 220, in
self.animacionMostar.finished.connect(lambda: (self.statusBar.showMessage(nombre))) AttributeError:
'VentanaVISUALIZAR' object has no attribute 'statusBar'
Code:
class VentanaVISUALIZAR(QDialog):
def __init__(self, parent=None):
super(VentanaVISUALIZAR, self).__init__()
self.setWindowIcon(QIcon("icono.png"))
self.setWindowTitle("Visualizador ")
self.setWindowFlags(Qt.MSWindowsFixedSizeDialogHint)
self.setFixedSize(1020, 680)
self.widget()
def widget(self):
# ===================== LLAMAR WIDGETS =======================
framePrincipal = QFrame(self)
framePrincipal.setFrameShape(QFrame.Box)
framePrincipal.setFrameShadow(QFrame.Sunken)
framePrincipal.setAutoFillBackground(True)
framePrincipal.setBackgroundRole(QPalette.Light)
framePrincipal.setFixedSize(1000, 560)
framePrincipal.move(10, 10)
frame = QFrame(framePrincipal)
frame.setFixedSize(980, 540)
frame.move(10, 10)
self.labelImagen = QLabel(frame)
self.labelImagen.setAlignment(Qt.AlignCenter)
self.labelImagen.setGeometry(0, 0, 980, 540)
self.labelImagenUno = QLabel(frame)
self.labelImagenUno.setAlignment(Qt.AlignCenter)
self.labelImagenUno.setGeometry(-970, 0, 980, 540)
# =================== BOTONES VISUALIZADOR ==================
botonVCargar = QPushButton("Cargar Imagen", self)
botonVCargar.setGeometry(QRect(10,590,325,30))
botonVCargar.setIcon(QtGui.QIcon("cargar.png"))
botonVCargar.setIconSize(QtCore.QSize(20,20))
botonVEliminar = QPushButton("Eliminar Imagen", self)
botonVEliminar.setGeometry(QRect(350,590,325,30))
botonVEliminar.setIcon(QtGui.QIcon("borrar.png"))
botonVEliminar.setIconSize(QtCore.QSize(20,20))
#================== ACCIONES BOTONES VISUALIZADOR ===================
botonVCargar.clicked.connect(self.Cargar)
botonVEliminar.clicked.connect(self.Eliminar)
posicion = int
carpetaActual = QDir()
imagenesCarpeta = []
def bloquearBotones(self, bool):
self.botonVCargar.setEnabled(bool)
self.botonVEliminar.setEnabled(bool)
def Mostrar (self, label, imagen, nombre, posicionX=970):
imagen = QPixmap.fromImage(imagen)
# Escalar imagen a 640x480 si el ancho es mayor a 640 o el alto mayor a 480
if imagen.width() > 980 or imagen.height() > 540:
imagen = imagen.scaled(980, 540, Qt.KeepAspectRatio, Qt.SmoothTransformation)
# Mostrar imagen
label.setPixmap(imagen)
# Animación (al finalizar la animación se muestra en la barra de estado el nombre y la extensión de la imagen
# y se desbloquean los botones).
self.animacionMostar = QPropertyAnimation(label, b"geometry")
self.animacionMostar.finished.connect(lambda: (self.statusBar.showMessage(nombre)))
self.animacionMostar.setDuration(200)
self.animacionMostar.setStartValue(QRect(posicionX, 0, 960, 540))
self.animacionMostar.setEndValue(QRect(0, 0, 960, 540))
self.animacionMostar.start(QAbstractAnimation.DeleteWhenStopped)
def Limpiar(self, labelConImagen, labelMostrarImagen, imagen, nombre,
posicionInternaX, posicionX=None):
def Continuar(estado):
if estado:
if posicionX:
self.Mostrar(labelMostrarImagen, imagen, nombre, posicionX)
else:
self.Mostrar(labelMostrarImagen, imagen, nombre)
self.animacionLimpiar = QPropertyAnimation(labelConImagen, b"geometry")
self.animacionLimpiar.finished.connect(lambda: labelConImagen.clear())
self.animacionLimpiar.setDuration(200)
# self.animacionLimpiar.valueChanged.connect(lambda x: print(x))
self.animacionLimpiar.stateChanged.connect(Continuar)
self.animacionLimpiar.setStartValue(QRect(0, 0, 980, 540))
self.animacionLimpiar.setEndValue(QRect(posicionInternaX, 0, 980, 540))
self.animacionLimpiar.start(QAbstractAnimation.DeleteWhenStopped)
def Cargar(self):
nombreImagen, _ = QFileDialog.getOpenFileName(self, "Seleccionar imagen",
QDir.currentPath(),
"Archivos de imagen (*.jpg *.png *.ico *.bmp)")
if nombreImagen:
# Verificar que QLabel tiene imagen
labelConImagen = ""
if self.labelImagen.pixmap():
labelConImagen = self.labelImagen
elif self.labelImagenUno.pixmap():
labelConImagen = self.labelImagenUno
imagen = QImage(nombreImagen)
if imagen.isNull():
if labelConImagen:
self.Eliminar()
QMessageBox.information(self, "Visor de imágenes",
"No se puede cargar %s." % nombreImagen)
return
# Obtener ruta de la carpeta que contiene la imagen seleccionada
self.carpetaActual = QDir(QFileInfo(nombreImagen).absoluteDir().path())
# Obtener la ruta y el nombre de las imagenes que se encuentren en la carpeta de
# la imagen seleccionada
imagenes = self.carpetaActual.entryInfoList(["*.jpg", "*.png", "*.ico", "*.bmp"],
QDir.Files, QDir.Name)
self.imagenesCarpeta = [imagen.absoluteFilePath() for imagen in imagenes]
self.posicion = self.imagenesCarpeta.index(nombreImagen)
# Función encargada de bloquear o desbloquear los botones
#self.bloquearBotones(False)
# Nombre y extensión de la imagen
nombre = QFileInfo(nombreImagen).fileName()
if labelConImagen:
posicionInternaX = -970
labelMostrarImagen = self.labelImagen if self.labelImagenUno.pixmap() else self.labelImagenUno
self.Limpiar(labelConImagen, labelMostrarImagen, imagen, nombre, posicionInternaX)
else:
self.Mostrar(self.labelImagen, imagen, nombre)
def Eliminar(self):
def establecerValores():
labelConImagen.clear()
labelConImagen.move(0, 0)
# Limpiar la barra de estado
self.statusBar.clearMessage()
# Establecer los valores predeterminados
self.posicion = int
self.estadoAnterior, self.estadoSiguiente = False, False
self.carpetaActual = QDir()
self.imagenesCarpeta.clear()
#self.bloquearBotones(True)
# Verificar que QLabel tiene imagen
labelConImagen = ""
if self.labelImagen.pixmap():
labelConImagen = self.labelImagen
elif self.labelImagenUno.pixmap():
labelConImagen = self.labelImagenUno
if labelConImagen:
#self.bloquearBotones(False)
self.animacionEliminar = QPropertyAnimation(labelConImagen, b"geometry")
self.animacionEliminar.finished.connect(establecerValores)
self.animacionEliminar.setDuration(200)
self.animacionEliminar.setStartValue(QRect(0, 0, 640, 480))
self.animacionEliminar.setEndValue(QRect(-650, 0, 640, 480))
self.animacionEliminar.start(QAbstractAnimation.DeleteWhenStopped)
VentanaVISUALIZAR is a subclass of QDialog which does not have a status bar by default. You can add one by adding something like this to VentanaVISUALIZAR.__init__:
self.statusBar = QStatusBar(self)
self.statusBar.setSizeGripEnabled(False)
self.statusBar.move(0,650)
self.statusBar.setFixedSize(1020,30)
Helloooo guys !
I've started a project to write an algorithm that can recognize constellations in the northern hemisphere. But it can only recognize constellations on very easy pictures.
My objective being this:
private fun rotate(
templateData: Array<Array<Array<String>>>,
brightest_index: Int,
second_brightest: Int
): Array<Array<DoubleArray>> {
val userStarData: Array<DoubleArray> = CameraActivity.starArray
val rotatedTemplates =
Array(
5
) {
Array(
89
) { arrayOfNulls<String>(31) }
}
val x0: Double
val y0: Double
val x1: Double
val y1: Double
val dx: Double
val dy: Double
var angle = 0.0
x0 = userStarData[brightest_index][0]
y0 = userStarData[brightest_index][1]
x1 = userStarData[second_brightest][0]
y1 = userStarData[second_brightest][1]
dx = x1 - x0
dy = y1 - y0
// Angle en Radians
angle = Math.atan(dx / dy)
Log.i(TAG, "Rotation angle: $angle")
return rotateTemplates(templateData, angle)
}
/**
* Cette fonction est appelée une fois que l'angle de rotation a été calculé, fait tourner les données du modèle.
* #param templateData template de constellation
* #param angle angle de rotation déterminé par rotateTemplate
* #return
*/
private fun rotateTemplates(
templateData: Array<Array<Array<String>>>,
angle: Double
): Array<Array<DoubleArray>> {
val rotatedTemplates =
Array(
5
) { Array(89) { DoubleArray(31) } }
var x: Double
var y: Double
var xprime: Double
var yprime: Double
// Pour chaque constellation :
for (i in 0..85) {
val numStars = templateData[0][i][1].toInt()
for (j in 0 until numStars) {
x = templateData[1][i][j].toDouble()
y = templateData[2][i][j].toDouble()
// Pour chaque x et y, analyser les valeurs, puis calculer les valeurs pivotées. Formules :
// x' = (x * cos(theta)) - (y * sin(theta))
// y' = (x * sin(theta)) + (y * cos(theta))
xprime = x * Math.cos(angle) - y * Math.sin(angle)
yprime = x * Math.sin(angle) + y * Math.cos(angle)
// Échange des coordonnées x et y pour inverser les modèles afin qu'ils correspondent à la façon dont la caméra représente les blobs
rotatedTemplates[1][i][j] = yprime
rotatedTemplates[2][i][j] = xprime
}
}
return rotatedTemplates
}
//cette fonction recherche dans les ensembles de données d'images et de modèles de l'utilisateur pour trouver une correspondance entre les données
//cette fonction recherche les correspondances en analysant chaque ensemble de triplets d'étoiles dans l'ensemble des données de l'image utilisateur
//regarder d'abord les deux premières étoiles du triplet pour déterminer l'échelle de leurs coordonnées et appliquer cette échelle au modèle considéré
//puis itérez sur l'ensemble de données de l'utilisateur pour chaque ensemble de triplets possibles, en vérifiant s'il y a une correspondance de distance
//dans une fenêtre de 10 % de la distance entre les étoiles correspondantes du modèle
//continuer d'itérer jusqu'à ce qu'un triplet soit trouvé
//puis itérez les données de l'utilisateur à partir de la troisième étoile du triplet pour trouver les autres étoiles de la constellation
private fun findConstellationMatch(templateData: Array<Array<Array<String>>>): Array<Array<String>> {
val userStarData: Array<DoubleArray> =
CameraActivity.starArray //saisir un ensemble de données à partir d'une image de l'utilisateur provenant de l'activité de la caméra
val match =
Array(
3
) { Array(31, {i -> ""}) }
// ) { arrayOfNulls<String>(31) } //ce tableau contiendra les coordonnées de toutes les étoiles de la constellation identifiée
var templateNumStars: Int
for (i in 0..85) //itérer à travers chacune des 89 constellations
{
templateNumStars = templateData[0][i][1].toInt()
//itérer sur le jeu de données de l'image utilisateur pour l'index de la première étoile du triplet
for (starOne in 0 until userStarData.size - 2) {
val starOne_x = userStarData[starOne][0]
//itérer sur le jeu de données de l'image utilisateur pour l'index de la seconde étoile du triplet
for (starTwo in starOne + 1 until userStarData.size - 1) {
val rotatedTemplates =
rotate(templateData, starOne, starTwo)
val starTwo_x = userStarData[starTwo][0]
//itérer sur le jeu de données de l'image utilisateur pour l'index de la troisieme étoile du triplet
for (starThree in starTwo + 1 until userStarData.size) { // Échelle utilisant la distance entre les deux étoiles les plus brillantes, calculer les rapports.
val templateXDelta =
(rotatedTemplates[1][i][2] - rotatedTemplates[1][i][1]) / (rotatedTemplates[1][i][1] - rotatedTemplates[1][i][0])
val templateYDelta =
(rotatedTemplates[2][i][2] - rotatedTemplates[2][i][1]) / (rotatedTemplates[2][i][1] - rotatedTemplates[2][i][0])
val xDelta =
(userStarData[starThree][0] - userStarData[starTwo][0]) / (userStarData[starTwo][0] - userStarData[starOne][0])
val yDelta =
(userStarData[starThree][1] - userStarData[starTwo][1]) / (userStarData[starTwo][1] - userStarData[starOne][1])
//vérifier si une correspondance a été trouvée avec le jeu de triplés
if (templateNumStars <= userStarData.size && xDelta > templateXDelta * 0.9 && xDelta < templateXDelta * 1.1 && yDelta > templateYDelta * 0.9 && yDelta < templateYDelta * 1.1) {
Log.i(
TAG,
"Match le premier triplet de " + templateData[0][i][0]
)
//si une correspondance a été trouvée, enregistrer leurs coordonnées dans le tableau de correspondance [][] ainsi que le nom de la constellation identifiée
match[0][0] = templateData[0][i][0]
match[1][0] =
java.lang.Double.toString(userStarData[starOne][0])
match[2][0] =
java.lang.Double.toString(userStarData[starOne][1])
match[1][1] =
java.lang.Double.toString(userStarData[starTwo][0])
match[2][1] =
java.lang.Double.toString(userStarData[starTwo][1])
match[1][2] =
java.lang.Double.toString(userStarData[starThree][0])
match[2][2] =
java.lang.Double.toString(userStarData[starThree][1])
return match
}
}
}
}
}
// Si aucune correspondance n'a été trouvée, retournez un tableau vide..
val res = Array(3) { Array(31, {i -> ""}) }
return res
// return Array(3) { arrayOfNulls<String>(31) }
}
}
The database look like that :
link to image of db
I don't know if the error comes from the image processing or from the algorithm itself.
My script:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import multiprocessing
import pickle
import socket
import ssl
import sys
import time
from Logs.cryptography import symmetric_crypto
from Logs import sign_up_log_in as log
class Servidor():
"""
Se creara un servidor en local (127.0.0.1), en el puerto 7000.
"""
def __init__(self,host = "192.168.0.16", port = 7000):
"""
En self.clientes se almacenaran todos los usuarios que se conecten al servidor
setblocking(False or True) -> si este es True (por defecto), sera un socket bloqueante,
lo que quiere decir que el servidor solo atendera a una sola peticion y las demas deberan
esperar, en cambio si es False, este atendera todas las peticiones que lleguen de manera simultanea con ayuda de los hilos.
threading.Thread(target = metodo())
* La clase Thread cuenta con un parametro llamado target, el cual ejecutara un metodo o funcionalidad de forma simultanea a
otros procesos, tareas (metodos - funcionalidades) que tambien deseen ejecutarse al tiempo, a esto se le conoce como hilos.
El parametro daemon sirve para darle fin a los hilos, una vez que el programa haya terminado, esto es util cuando no queremos que estos procesos
queden andando sin motivo alguno.
El metodo start(), da inicio al hilo hijo, el hilo principal es el de la ejecucion del propio programa en si.
Este metodo se coloca despues del parametro daemon, siempre y cuando hagamos uso de el.
El metodo join(), sirve para indicarle al programa que no debe ejecutar mas procesos (hilos), hasta que no termine con el actual(proceso-hilo),
este metodo se coloca despues del start() metodo.
"""
self.load_clients()
self.clientes_registrados = []
self.clientes_conectados = []
self.staging_area = []
self.nickname = None
self.transmitted_message = None
self.server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.server.bind((str(host),int(port)))
self.server.listen(10)
self.server.setblocking(False)
# se ejecutan de inmediato al iniciar el programa
recv_logging = multiprocessing.Process(target = self.recv_logging)
aceptar_conn = multiprocessing.Process(target = self.aceptar_conn)
recv_messages = multiprocessing.Process(target = self.recv_messages)
lista_send_conn = multiprocessing.Process(target = self.lista_send_conn)
# se anclan al hilo principal, los hilos hijos, para que estos no queden como procesos andantes aun despues de haberse cerrado el programa,
# seguido de esto se inicia la ejecucion de los metodos.
recv_logging.daemon = True
recv_logging.start()
aceptar_conn.daemon = True
aceptar_conn.start()
lista_send_conn.daemon = True
lista_send_conn.start()
recv_messages.daemon = True
recv_messages.start()
def lista_send_conn(self):
if bool( self.clientes_conectados ):
package = (self.clientes_conectados,"lista_conn")
self.conn_cliente.send( pickle.dumps(package) )
def save_clients(self):
"""
Metodo que guarda los cambios producidos en el archivo clientes.pckl
"""
with open("clientes.pckl","wb") as clients:
pickle.dump(self.clientes_registrados,clients)
def load_clients(self):
"""
Metodo que carga el archivo clientes.pckl en una variable para su posterior uso.
"""
with open("clientes.pckl","ab+") as clients:
clients.seek(0)
try:
self.clientes_registrados = pickle.load(clients)
except:
pass
def recv_logging(self):
# El error esta en este metodo, que no hace el recv de lo que le manda el cliente (obj_usuario -> (user/password) )
"""
Este metodo recibira una variable por parte del metodo login(), del modulo cliente.py, el cual tendra un dict que tiene en la clave la ip del usuario,
y en su valor, el objeto de la clase Usuario del cliente.
Se recorre la lista (con los diccionarios "self.clientes del modulo sign_up_log_in.py" dentro), para asi poder verificar la existencia de un usuario
que dice registrarse o logearse dentro del servidor.
A cada cliente de la lista de registrados, se le saca su valor a la variable obj_usuario, recordemos que la clave era la ip, y su valor el objeto de la clase Usuario del respectivo
usuario.
"""
while True:
# Desencripta el archivo .pckl para su posterior uso.
if self.transmitted_message != None:
self.decrypt_data_logging(self.transmitted_message)
# cliente[ip] devuelve un objeto Usuario (nickname, password del usuario), objeto que se almcanera en obj_usuario,
# para posteriormente comparar los nicknames de los clientes en base de datos, con los que se acaban de pronunciar (sign or log),
# y sus contraseñas.
# Este for lo uso para saber si esa ip entrante ya esta registrada, de modo que si se levanta un error, no esta registrada,
# en cambio si no se levanta un error, quiere decir que el usuario si esta, pero que si no ingreso es por un error de autenticacion
manager = log.Controller()
# recibir una tupla (obj_user, id, ip), el id puedes ser "log-in" o "sign-up"
if bool(self.staging_area):
for conexion in self.staging_area:
try:
received_data = conexion.recv(2048) # ERROR (pero aca se caga todoooo)
except Exception as e:
print(e)
else:
received_data = pickle.loads(received_data)
# desempaquetamos el paquete
#received_id = received_data[0][1]
received_id = received_data[1]
# el id sirve especificamente para redireccionar en este condicional, a sus respectivos metodos
if received_id == "sign_up":
#received_sign_up = received_data[0][0]
received_sign_up = received_data[0]
status_ok = manager.add_user(received_sign_up, self.clientes_registrados)
else:
#received_log_in = received_data[0][0]
received_log_in = received_data[0]
status_ok = manager.verify_user(received_log_in, self.clientes_registrados)
# de acuerdo a lo que se retorna en los metodos verify_user() y add_user(), se ejecutan ciertas tareas.
# Errores al momento de realizar el proceso de logueo
if status_ok == "user_exist_signup":
if bool(self.staging_area):
for conexion in self.staging_area:
conexion.send("user_exist_sign-up".encode("utf-8"))
elif status_ok == "invalid_nickname":
if bool(self.staging_area):
for conexion in self.staging_area:
conexion.send("invalid_nickname".encode("utf-8"))
elif status_ok == "user_exist_log-in":
if bool(self.staging_area):
for conexion in self.staging_area:
conexion.send("user_exist_log-in".encode("utf-8"))
elif status_ok == "not_found":
if bool(self.staging_area):
for conexion in self.staging_area:
conexion.send("not_found".encode("utf-8"))
else:
# si retorna una tupla (obj_usuario, id), entonces este se pasa por el else
data_decode = pickle.loads(status_ok)
# si el id es igual a sign-up, se redireccionara para que inicie sesion
if data_decode[1] == "sign_up":
# solo se agrega el obj_usuario
self.clientes_registrados.append((data_decode[0]))
if bool(self.staging_area):
for conexion in self.staging_area:
conexion.send("log-in_go".encode("utf-8"))
else:
# si el id es igual a log-in, se redireccionara para que inicie el chat
if bool(self.staging_area):
for conexion in self.staging_area:
conexion.send("chat".encode("utf-8"))
# devolver un objeto usuario, con la ip que manda el mismo
for client in self.clientes_registrados:
obj_usuario = client[received_data[2]]
self.nickname = obj_usuario.usuario
self.clientes_conectados.append( {self.nickname:[conexion for conexion in self.staging_area if bool(self.staging_area)]} )
return self.nickname
# Se encriptan los datos de los usuarios y se guarda (confirma) dicho cambio, posteriormente se le envia una señal al cliente,
# para avisarle de que dicho usuario ya esta registrado y que solo debera iniciar seison, no registrarse, de no ser por este aviso,
# el usuario podria volver accidentalmente a registrarse, y eso no es lo que queremos, verdad?
self.encrypt_data_logging()
self.save_clients()
def encrypt_data_logging(self):
"""
Este metodo cifrara el archivo.pckl
"""
manager = symmetric_crypto.Transmitter()
key = manager.random_key()
msg = manager.extract_message("clientes.pckl")
# self.transmitted_message, es un atributo que se usara para el decrypt_data_logging(self,transmitted_message) metodo.
# cipher_text, solo guarda la copia del mensaje cifrado, sin adjuntos. Util para encriptar el fichero .pckl
self.transmitted_message,cipher_text = manager.encrypt(key,msg.encode("utf-8"))
with open("clientes.pckl",'wb') as file:
file.write(cipher_text)
def decrypt_data_logging(self,transmitted_message):
"""
Este metodo descifrara el archivo.pckl
"""
manager = symmetric_crypto.Receiver()
cipher_text, tag_mac, salt, nonce = manager.unpacking(transmitted_message)
plain_text = manager.decrypt(cipher_text, tag_mac, salt, nonce)
with open("clientes.pckl",'wb') as file:
file.write(plain_text)
def main(self):
"""
Este metodo solo reaccionara ante el input "salir", lo cual causara el cierre del servidor, y de la terminal.
"""
self.aceptar_conn()
while True:
opcion = input("\n-> ").strip().lower()
if opcion == "salir":
self.server.close()
sys.exit()
else:
pass
def aceptar_conn(self):
"""
Aceptaremos todas las conexiones entrantes, (maximo 10 coneixones) y a cada usuario que se conecte, le aplicaremos el metodo
setblocking = False, para que estos puedan ejecutar multiples tareas.
"""
while True:
try:
conn_cliente, data_cliente = self.server.accept()
conn_cliente.setblocking(False)
except Exception as e:
print(e)
else:
self.staging_area.append(conn_cliente)
def recv_messages(self):
"""
Si self.clientes_conectados es mayor que 0, es decir, si aun hay usuarios conectados, y ademas, si han enviado algun mensaje,
se recibiran los mensajes de cada uno de ellos, y se enviaran al metodo msg_to_whoami().
"""
while True:
# mientras hayan clientes en linea
if bool(self.clientes_conectados):
# A cada cliente conectado se le recibiran sus dichas peticiones (mensajes)
for cliente in self.clientes_conectados:
# se captura el nombre del usuario (whoami), al cual se le quiere hacer llegar el mensaje, y el mensaje_anidado,
# digo anidado porque ademas del mensaje, este tiene otros adjuntos que ayudan al cifrado del mismo.
whoami, msg = cliente.recv(4096)
whoami,msg = pickle.loads(whoami), pickle.loads(msg)
# verificar que haya un msg y un usuario existente
if cliente[whoami]:
# # ip_user = obj_usuario[whoami]
if msg:
self.msg_to_whoami(cliente, msg)
def msg_to_whoami(self,cliente,msg):
"""
El mensaje se envia a todos los usuarios conectados, menos al que envio el mensaje propiamente.
En caso de que halla un error, ese usuario sera sacado de la red, ya que este estaba inactivo y le
esta quitando el espacio a un usuario activo que desee entrar en el chat.
"""
for client in self.clientes_conectados:
# generamos una lista con las claves de todos los usuarios (nicknames), y su valor es (conn_objeto_socket)
keys = client.keys()
for key in keys:
# para cada clave en la lista, si alguna es igual al nickname parametro, se obtiene su objeto para poder enviarle el
# mensaje solo a dicha persona.
if key == cliente:
conn_obj = client[key]
conn_obj.send(pickle.dumps(msg))
# Si hay algun tipo de error, se removera el usuario del servidor para darle lugar a otros, ya que dicho usuario esta inactivo.
self.clientes_conectados.remove(client)
if __name__ == '__main__':
init = Servidor()
init.main()
My code was fine, until suddenly I get this error.
Error code:
Traceback (most recent call last):
File ".\servidor.py", line 355, in <module>
init.main()
File ".\servidor.py", line 274, in main
self.aceptar_conn()
File ".\servidor.py", line 295, in aceptar_conn
conn_cliente, data_cliente = self.server.accept()
File "C:\Users\EQUIPO\AppData\Local\Programs\Python\Python37-32\lib\socket.py", line 212, in accept
fd, addr = self._accept()
BlockingIOError: [WinError 10035] A non-blocking socket operation could not be completed immediately
Anyone know why this happens, and how can I fix it?
I searched the internet, but I really can't understand much about this error. Basically what I do is put the connections in a list and going through the list (bone in order of arrival), I am performing certain tasks with each connection, because the connection is lost once it is established (because the method is always waiting for connection and configure 10 in the queue, in the self.server.listen (10))
PDTA: If this information is of any use, I am doing a small private chat room, so I need that conn_cliente.setblocking (False)
BlockingIOError: [WinError 10035] A non-blocking socket operation could not be completed immediately
accept usually waits until a client is connected and only then returns successful. But you've explicitly set the socket to non-blocking which means it will not wait. Instead it will return the error you see if no client connected during (the short time) accept was called.
... so I need that conn_cliente.setblocking (False)
None of your code deals specifically with non-blocking sockets so I doubt that you actually need it.
This question already has answers here:
Is it possible to implement gradual movement of an object to given coordinates in Pygame?
(1 answer)
How to make a circle move diagonally from corner to corner in pygame
(1 answer)
Pygame Enemys Wont Move Down - Tower Defense Game
(3 answers)
Closed 1 year ago.
I've been struggling with a code I found in the web and I tinkered with it. My goal was to make two ways of finding a path to a certain point to win against human user with an 'AI' in a tron game. But I've found you instantaneously die no matter what you do! After days of searching for clues with PyGame library or trying to see what happens, I still can't figure out what's wrong.
The algorithm is something like this:
pathTarget = new Queue();
fillPath(pathTarget);
// use pathTarget to move with `move()`
It either fills it up with A* search or BFS but I think it traverses all the nodes instantaneously, though I can't find the bug. I'd appreciate if you could point me in the right direction? The code is here in a friend's repo since I did not know what github is until today. Thanks in advance.
EDIT: As requested, the code is here too:
import pygame, time, collections, random, heapq
pygame.init()
BLACK = (0, 0, 0) # colores para usar en la ventana
P1_COLOUR = (0, 255, 255) # color de traza del jugador 1
P2_COLOUR = (255, 0, 255) # color de traza del jugador 2
moves = {'up':(0, -2), 'down':(0, 2), 'left':(0, -2), 'right':(0, 2)} # diccionario utilitario
# distancia manhattan entre dos nodos
def manhattan(nodeL, nodeR):
return abs(nodeL[0] - nodeR[0]) + abs(nodeL[1] - nodeR[1])
class Queue: # Clase para acceder facilmente a collections.deque
def __init__(self):
self.elements = collections.deque() # nuevo deque (double ended queue)
def empty(self):
return len(self.elements) == 0 # checar si está vacío
def push(self, x): # encolar elemento x
self.elements.append(x)
def pop(self): # remover y devolver el elemento en el frente
return self.elements.popleft()
def last(self): # ver el último nodo en la fila
node = self.elements.pop() # lo sacamos
self.elements.append(node) # lo metemos de vuelta
return node # lo devolvemos
# Clase Cola de Prioridad (usa heap de Python)
class PriorityQueue:
# Constructor
def __init__(self):
self.elements = []
# Checa si esta vacía
def empty(self):
return len(self.elements) == 0
# Inserta elemento item con prioridad priority
def push(self, item, priority):
heapq.heappush(self.elements, (priority, item))
# regresa el elemento prioritario
def pop(self):
return heapq.heappop(self.elements)[1]
# Clase jugador
class Player:
# Constructor
def __init__(self, direction, isHuman=False):
self.direction = direction # direccion como una tupla
self.isHuman = isHuman # si es humano o AI
if self.isHuman: # Si es humano lo construimos diferente
self.x = 50 # con cierta posición
self.y = height // 2
self.colour = P1_COLOUR # Y cierto color
else: # de otro modo es IA y va en otro lado
self.x = width - 50
self.y = height // 2
self.colour = P2_COLOUR # Con otro color
self.xTarget = 50 # además de valores especiales para seguir su objetivo y crear un camino
self.yTarget = height // 2
self.pathTarget = Queue() # como el camino a seguir para derrotar al humano
self.difficulty = 2 # random.randint(1, 2) # dificultad a usar
self.speed = 1 # velocidad del jugador
self.boost = False # si tiene nitro
self.start_boost = time.time() # para controlar la medida del nitro
self.boosts = 3 # cantidad de nitros
self.rect = pygame.Rect(self.x - 1, self.y - 1, 2, 2) # rectangulo del jugador
# metodo para dibujar
def __draw__(self):
self.rect = pygame.Rect(self.x - 1, self.y - 1, 2, 2) # redefine el rectangulo
pygame.draw.rect(screen, self.colour, self.rect, 0) # dibuja al jugador en la pantalla
# actualizar objetivo y camino, IA nada mas
def updateTarget(self):
self.xTarget, self.yTarget = p2.x, p2.y # actualiza los objetivos
# Este punto se supone que es un buen punto para "matar" al enemigo
if p2.direction == moves['left']:
self.yTarget -= 2
elif p2.direction == moves['right']:
self.yTarget += 2
elif p2.direction == moves['up']:
self.xTarget += 2
elif p2.direction == moves['down']:
self.xTarget -= 2
# Uso de la IA buscando caminos
if not self.pathTarget.empty():
self.pathTarget.push((self.xTarget, self.yTarget))
else:
if self.difficulty == 1:
self.bfs()
else:
self.aSearch()
# metodo para revisar la direccion de un nodo respecto a otro
def checkDir(self, target):
if self.x < target[0]:
return moves['right']
if self.x > target[0]:
return moves['left']
if self.y < target[1]:
return moves['down']
if self.y > target[1]:
return moves['up']
# metodo mover para evitar el privado '__move__', como una 'API' para la IA
def move(self):
if self.isHuman: # Si es humano que siga normal
past = (self.x, self.y)
self.__move__() # nos movemos normal
usedBoard[past[0]][past[1]] = True
else: # si es IA
if not self.pathTarget.empty(): # mientras haya direcciones a seguir en el camino
self.direction = self.checkDir(self.pathTarget.pop()) # sigamoslas
self.updateTarget() # actualiza las direcciones y la cola
# importante! primero calculamos la direccion y luego marcamos el nodo como usado
past = (self.x, self.y)
self.__move__() # nos movemos normal
usedBoard[past[0]][past[1]] = True
# Movimiento
def __move__(self):
if not self.boost: # Si no hay nitro
self.x += self.direction[0]
self.y += self.direction[1]
else: # si lo hay
self.x += self.direction[0] * 2
self.y += self.direction[1] * 2
# Nitro
def __boost__(self):
if self.boosts > 0: # si tenemos nitro
self.boosts -= 1 # quitamos
self.boost = True # activamos
self.start_boost = time.time() # y a correr! (0.5s)
# calcular los vecinos de un nodo dado un tablero prueba
def computeNeighbors(self, coords, testBoard):
neighbors = [] # vacía por las dudas
# Si x > 0 y está vacío el tablero, vamos a la izquierda
if coords[0] > 1:
if not usedBoard[coords[0] - 2][coords[1]] and not testBoard[coords[0] - 2][coords[1]]:
neighbors.append( (coords[0] - 2, coords[1]) )
# Si y > 62 y está vacío el tablero, vamos arriba
if coords[1] > 1:
if not usedBoard[coords[0]][coords[1] - 2] and not testBoard[coords[0]][coords[1] - 2]:
neighbors.append( (coords[0], coords[1] - 2) )
# Si x < width y está vacío el tablero, vamos a la derecha
if coords[0] < width - 4:
if not usedBoard[coords[0] + 2][coords[1]] and not testBoard[coords[0] + 2][coords[1]]:
neighbors.append( (coords[0] + 2, coords[1]) )
# Si y < height y está vacío el tablero, vamos abajo
if coords[1] < height - 4 - offset:
if not usedBoard[coords[0]][coords[1] + 2] and not testBoard[coords[0]][coords[1] + 2]:
neighbors.append( (coords[0], coords[1] + 2) )
return neighbors
# Busqueda de camino con A*
def aSearch(self):
testBoard = usedBoard # tablero de prueba para inundar
neighbors = PriorityQueue() # Creamos un heap o cola de prioridad
neighbors.push((self.x, self.y), 0) # metemos nuestro nodo inicial
pathGenerated = {} # Camino creado
costUpTo = {} # Costo generado
pathGenerated[(self.x, self.y)] = None # Inicializamos el camino
costUpTo[(self.x, self.y)] = 0 # y los costos
while not neighbors.empty(): # Mientras haya vecinos
current = neighbors.pop() # obtenemos el mejor vecino
testBoard[current[0]][current[1]] = True # lo marcamos usado
if current == (self.xTarget, self.yTarget): # si es el objetivo nos salimos
break
frontier = self.computeNeighbors(current, testBoard) # Si no, le sacamos los vecinos
if frontier: # si no está vacía
for node in frontier: # Y para cada uno
newCost = costUpTo[current] + 1 # Costo de viajar al siguiente es 1
if node not in costUpTo or newCost < costUpTo[node]: # si el nodo no ha sido visitado o el costo es menor
costUpTo[node] = newCost # vamos a recorrerlo y añadirlo
priority = newCost + manhattan(node, (self.xTarget, self.yTarget)) # creamos su prioridad
neighbors.push(node, priority) # lo metemos en el heap
pathGenerated[node] = current # y en el camino
for key in pathGenerated: # metemos el camino
self.pathTarget.push(key) # para que lo visitemos
# Busqueda de camino con BFS
def bfs(self): # calcula el camino a seguir
testBoard = usedBoard # creamos el tablero de prueba para inundar
neighbors = Queue() # cola de nodos a visitar
neighbors.push((self.x, self.y)) # metemos el nodo actual
while not neighbors.empty(): # mientras haya nodos por inundar
current = neighbors.pop() # obtenemos el nodo de la cola
self.pathTarget.push(current)
# Si llegamos al objetivo, terminar y salir
if current[0] == self.xTarget and current[1] == self.yTarget:
break
testBoard[current[0]][current[1]] = True # Marcar como usado
frontier = self.computeNeighbors(current, testBoard) # Obtener vecinos del nodo actual
if frontier: # actualizar la cola
for node in frontier:
neighbors.push(node)
# para crear un nuevo juego
def new_game():
new_p1 = Player((-2, 0)) # IA de dificultad aleatoria
new_p2 = Player((2, 0), True) # Jugador
return new_p1, new_p2
width, height = 600, 660 # dimensiones de la ventana
offset = height - width # espacio vertical extra
usedBoard = [[False] * width for _ in range(height-offset)] # para uso con la BFS y la A*
screen = pygame.display.set_mode((width, height)) # crea la ventana
pygame.display.set_caption("Tron") # coloca el titulo del juego
font = pygame.font.Font(None, 72) # cambiamos el tamaño de la fuente
clock = pygame.time.Clock() # para regular los FPS
check_time = time.time() # para revisar colisiones en tiempo y forma
objects = list() # lista de todosl os jugadores
path = list() # lista de todos los caminos ya recorridos
p1 = Player((-2, 0)) # crea IA
p2 = Player((2, 0), True) # crea al jugador
objects.append(p1) # metemos la IA
path.append((p1.rect, '1')) # metemos su objeto en el camino
objects.append(p2) # ahora ocn el jugador
path.append((p2.rect, '2'))
player_score = [0, 0] # puntuaciones
wall_rects = [pygame.Rect([0, offset, 15, height]) , pygame.Rect([0, offset, width, 15]),\
pygame.Rect([width - 15, offset, 15, height]),\
pygame.Rect([0, height - 15, width, 15])] # los muros de fuera de la ventana
# variables de uso
done = False
new = False
while not done:
for event in pygame.event.get(): # obtener todos los eventos ocurridos
if event.type == pygame.QUIT: # cerrar el juego
done = True
elif event.type == pygame.KEYDOWN: # tecla presionada
# Movimientos del jugador
# >Flechas para moverse
# >Nitro con shift derecho
# Esta parte se puede activar para 2 jugadores, solo se descomenta y juega con WASD y TAB
# if event.key == pygame.K_w and objects[0].direction != (0, 2):
# objects[0].direction = (0, -2)
# elif event.key == pygame.K_s and objects[0].direction != (0, -2):
# objects[0].direction = (0, 2)
# elif event.key == pygame.K_a and objects[0].direction != (2, 0):
# objects[0].direction = (-2, 0)
# elif event.key == pygame.K_d and objects[0].direction != (-2, 0):
# objects[0].direction = (2, 0)
# elif event.key == pygame.K_TAB:
# objects[0].__boost__()
# Aquí comienzan los movimientos del jugador
if event.key == pygame.K_UP and objects[1].direction != (0, 2):
objects[1].direction = (0, -2)
elif event.key == pygame.K_DOWN and objects[1].direction != (0, -2):
objects[1].direction = (0, 2)
elif event.key == pygame.K_LEFT and objects[1].direction != (2, 0):
objects[1].direction = (-2, 0)
elif event.key == pygame.K_RIGHT and objects[1].direction != (-2, 0):
objects[1].direction = (2, 0)
elif event.key == pygame.K_RSHIFT:
objects[1].__boost__()
screen.fill(BLACK) # limpia la pantalla
for r in wall_rects: # para cada rectangulo
pygame.draw.rect(screen, (42, 42, 42), r, 0) # dibuja los muros
for obj in objects:
if time.time() - obj.start_boost >= 0.5: # limita el nitro a 0.5s
obj.boost = False
# Revisar colisiones
if (obj.rect, '1') in path or (obj.rect, '2') in path or obj.rect.collidelist(wall_rects) > -1: # choco con el camino o muro
# previene chocar consigo mismo
if (time.time() - check_time) >= 0.1:
check_time = time.time()
#puntuaciones
if obj.colour == P1_COLOUR:
player_score[1] += 1
else:
player_score[0] += 1
usedBoard = [[False] * width for _ in range(height-offset)] # para uso con la BFS y la A*
new = True
new_p1, new_p2 = new_game()
objects = [new_p1, new_p2]
path = [(p1.rect, '1'), (p2.rect, '2')]
break
else: # sin atravesar
path.append((obj.rect, '1')) if obj.colour == P1_COLOUR else path.append((obj.rect, '2'))
obj.__draw__()
obj.move()
for r in path:
if new is True: # vacía el camino, evita glitches
path = []
new = False
break
if r[1] == '1':
pygame.draw.rect(screen, P1_COLOUR, r[0], 0)
else:
pygame.draw.rect(screen, P2_COLOUR, r[0], 0)
# muestra las puntuaciones
score_text = font.render('{0} : {1}'.format(player_score[0], player_score[1]), 1, (255, 153, 51))
score_text_pos = score_text.get_rect()
score_text_pos.centerx = width // 2
score_text_pos.centery = offset // 2
screen.blit(score_text, score_text_pos)
pygame.display.flip() # voltea el display
clock.tick(60) # regula los FPS
pygame.quit()