Two clients do not communicate on python with ssl - ssl

El servidor tiene problemas para funcionar, he sacado el código de openai.com, pero parece que sus respuestas estan sacadas del código de personas que han posteado dudas y problemas en lugar de ejemplos funcionales.
El servidor.
import socketserver
import ssl
class Server:
def __init__(self, host, port, context):
self.host = host
self.port = port
self.context = context
self.context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
self.context.load_cert_chain(certfile='./cer.pem', keyfile='./clave.key')
self.server = socketserver.TCPServer((host, port), ServerHandler, context)
self.server.clients = []
def start(self):
self.server.serve_forever()
def stop(self):
self.server.shutdown()
self.server.server_close()
def send_message_to_all_clients(self, message):
for client in self.server.clients:
client.sendall(message)
class ServerHandler(socketserver.BaseRequestHandler):
def __init__(self, request, client_address, server):
self.context = context
super().__init__(request, client_address, server)
def handle(self):
self.server.clients.append(self.request)
self.request = self.context.wrap_socket(self.request, server_side=True)
while True:
data = self.request.recv(1024)
if not data:
break
self.send_message_to_all_clients(data)
def send_message_to_all_clients(self, message, context):
for client in self.server.clients:
client = context.wrap_socket(client, server_side=True)
client.sendall(message)
if __name__ == "__main__":
host = "127.0.0.1"
port = 8080
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(certfile='./cer.pem', keyfile='./clave.key')
server = Server(host, port, context)
server.start()

#!/usr/bin/python
from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA
from cifrar import CIFRAR
from descifrar import DESCIFRAR
from comprobar import *
import sys, os
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QIcon, QFont, QImage, QPixmap
from PyQt5.QtCore import pyqtSlot, Qt, pyqtSignal
class Ventana(QMainWindow, QWidget):
def __init__(self):
super().__init__()
#Icono
self.setWindowIcon(QIcon('v.png'))
#Variables de estado
self.conectado=False
#Fuente tipo negrita
fetiqueta=QFont()
fetiqueta.setBold(True)
#Avatar
self.archivoAvatar = "avatar.png"
self.avatar = QLabel(self)
self.avatar.setPixmap(QPixmap(self.archivoAvatar).scaled(120, 120, Qt.KeepAspectRatio))
self.avatar.move(720,130)
self.avatar.resize(120,120)
self.avatar.show()
#Texto de entrada
self.lineEntry = QPlainTextEdit(self)
self.lineEntry.move(10,10)
self.lineEntry.resize(700,200)
self.lineEntry.setReadOnly(True)
#Texto a enviar
self.linaEnvio = QLineEdit(self)
self.linaEnvio.move(10,500)
self.linaEnvio.resize(700,40)
self.linaEnvio.setReadOnly(False)
#Texto estado y avisos
self.linestado = QLineEdit(self)
self.linestado.move(10,210)
self.linestado.resize(700,40)
self.linestado.setReadOnly(True)
#Etiqueta bajo boton conectar -> IP
self.etiquetaIPS = QLabel(self)
self.etiquetaIPS.move(720,60)
self.etiquetaIPS.setText("IP:192.168.1.100 ")
self.etiquetaIPS.setStyleSheet("font-weight: 300")
#Etiqueta bajo boton conectar -> Puerto
self.etiquetaPS = QLabel(self)
self.etiquetaPS.move(720,80)
self.etiquetaPS.setText("Puerto: 8080 ")
self.etiquetaPS.setStyleSheet("font-weight: 300")
#Etiqueta bajo boton conectar -> Certificados
self.etiquetaCer = QLabel(self)
self.etiquetaCer.move(720,100)
self.etiquetaCer.setText("Puerto: 8080 ")
self.etiquetaCer.setStyleSheet("font-weight: 300")
#Boton conectar
self.boton1 = QPushButton(self)
self.boton1.move(720,10)
self.boton1.resize(130,40)
self.boton1.setText("Conectar")
self.boton1.setFont(fetiqueta)
self.boton1.setStyleSheet("background-color: red")
#Boton cerrar
self.boton2 = QPushButton(self)
self.boton2.move(720,550)
self.boton2.resize(130,40)
self.boton2.setFont(fetiqueta)
self.boton2.setText("Cerrar")
#Boton Enviar
self.boton3 = QPushButton(self)
self.boton3.move(10,550)
self.boton3.resize(700,40)
self.boton3.setText("Enviar")
self.boton3.setFont(fetiqueta)
#Señales
self.boton1.clicked.connect(self.conectar)
self.boton2.clicked.connect(self.cerrar)
self.boton3.clicked.connect(self.enviar)
# self.avatar.clicked.connect(self.seleccionarAvatar)
#Ventana principal
self.setGeometry(50,50,860,600)
self.setWindowTitle("Chat")
self.show()
#Funciones
def alinicio(self):
#Comprobamos estado de conexión, coloreamos boton de conexión y desactivamos boton y linea de envio
self.conecado = True
if self.conectado == False:
self.linestado.setText("Pulsa en el botón Desconectado para empezar.")
self.linaEnvio.setEnabled(False)
self.boton3.setEnabled(False)
self.boton1.setText("Desconectado")
self.boton1.setStyleSheet("background-color: red")
else:
self.linestado.setText("Conexión establecida!")
self.linaEnvio.setEnabled(True)
self.boton3.setEnabled(True)
self.conectado == True
self.boton1.setText("Conectado")
self.boton1.setStyleSheet("background-color: green")
#Comprobamos existencia de certificados
if os.path.isfile('./public0.pem') and os.path.isfile('./privad0.pem'):
self.etiquetaCer.setText("Certificados OK")
elif not os.path.isfile('./public0.pem') and not os.path.isfile('./privad0.pem'):
self.etiquetaCer.setText("¿Certificados?")
self.linestado.setStyleSheet("background-color: red")
self.linestado.setText("Faltan los certificados de cifrado!")
def seleccionarAvatar(self):
self.avatar = QFileDialog.getOpenFileName(self, 'Selecciona una imagen',".","Imagenes (*.png *.jpg *.bmp *.gif)")
if self.avatar:
self.image = QImage(self.avatar)
if self.image.isNull():
popup = QMessageBox(QMessageBox.Critical, "Image load error", "Could not load image file!", QMessageBox.Ok, self)
popup.show()
else:
cursor = self.text.textCursor()
cursor.insertImage(self.image, self.avatar)
def conectar(self):
self.conectado=True
self.alinicio()
def enviar(self, texto):
texto = self.linaEnvio.text()
tes = b''
resultado = tes + texto.encode('utf-8')
if self.linaEnvio.text():
key = RSA.import_key(open('public0.pem').read())
cipher = PKCS1_OAEP.new(key)
textoCifrado = cipher.encrypt(resultado)
self.lineEntry.appendPlainText(str(textoCifrado))
else:
self.linestado.setText("Escribe algo en el campo de texto encima del botón enviar...")
def cerrar(self):
self.seleccionarAvatar()
# sys.exit(app.exec_())
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Ventana()
ex.alinicio()
sys.exit(app.exec_())
# des= DESCIFRAR(cif)
# print(des)
# Aquí esta una solución.
# key = RSA.import_key(open('privad0.pem').read())
# cipher = PKCS1_OAEP.new(key)
# textoDesCifrado = cipher.decrypt(mensaje)
# return textoDesCifrado.decode("utf-8")

Related

PYQT5 imported MDI Subwindow Scaled Up

I'm working on a gui tool-- I'm building it with Pyqt5. I'm speifically NOT using QT designer. I'm using an MDI widget to keep everyhing a bit tidier.
Furthermore, so that my code is more crisp and less redundant, I'm building out each child window in a separate window in the same directory and then just importing the appropriate class from the individual files.
The problem is, whenver I import the subwindows, the are scaled up in the MDI subwindow. I am at a loss as to how I can address this. Has anyone expierenced something similar? I've added simplied code for my MDI subwindow below, followed by the code for one of the subwindows thta I'm importing. Any assistance would be greatly appreciated.
Import sys
from PyQt5 import QtCore
from PyQt5.QtGui import *
from PyQt5.QtGui import QWindow
from PyQt5.QtWidgets import *
from PyQt5.QtWidgets import QMdiArea, QAction, QMdiSubWindow, QTextEdit
from Admission_Tool import *
from COPD_tool import *
from Discharge_Template import DischargeWindow
from Note_Template import *
class MDIWindow(QMainWindow):
count = 0
htntoolcount = 0
copdcount = 0
def __init__(self):
super().__init__()
self.mdi = QMdiArea()
self.setCentralWidget(self.mdi)
self.setStyleSheet('font-size: 10pt; font-family: Times;')
self.setStyleSheet("QPushButton{font-size: 10pt;}")
self.setStyleSheet("QLabel{font-size: 10pt;}")
self.mdi.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.mdi.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
#####Setting up main Menu Labels and Buttons#####
self.mainMenuWidget = QWidget(self)
self.mmWidgetLayout = QVBoxLayout()
self.mainMenuWidget.setLayout(self.mmWidgetLayout)
self.mainMenuWidget.setWindowTitle("Main Menu")
self.mmButton1 = QPushButton("Note Setup Tool", self)
self.mmButton2 = QPushButton("Lab Entry Tool", self)
self.mmButton3 = QPushButton("Follow Up Tools", self)
self.mmButton4 = QPushButton("ROS Generator", self)
self.mmButton5 = QPushButton("Physical Exam Generator", self)
self.mmButton6 = QPushButton("Cardon Matrix", self)
self.mmButton7 = QPushButton("Trilogy Matrix", self)
self.mmButton8 = QPushButton("ASC Matrix", self)
self.mmButton9 = QPushButton("Proactive Email", self)
self.mmWidgetLayout.addWidget(self.mmButton1)
self.mmWidgetLayout.addWidget(self.mmButton2)
self.mmWidgetLayout.addWidget(self.mmButton3)
self.mmWidgetLayout.addWidget(self.mmButton4)
self.mmWidgetLayout.addWidget(self.mmButton5)
self.mmWidgetLayout.addWidget(self.mmButton6)
self.mmWidgetLayout.addWidget(self.mmButton7)
self.mmWidgetLayout.addWidget(self.mmButton8)
self.mmWidgetLayout.addWidget(self.mmButton9)
self.mdi.addSubWindow(self.mainMenuWidget)
self.mainMenuWidget.show()
##adding actions to main menu buttons##
self.mmButton1.clicked.connect(self.noteSetupFunc)
self.mmButton2.clicked.connect(self.admissionTool)
self.mmButton3.clicked.connect(self.COPDToolFunc)
self.setWindowTitle("Proactive Charting Tool")
def noteSetupFunc(self):
self.noteSUButtFuncWidget = NOTEWindow()
self.mdi.addSubWindow(self.noteSUButtFuncWidget)
self.noteSUButtFuncWidget.show()
# Setting MAin Menu Widget for NOtes#
# self.NOTEmainMenuWidget = QWidget(self)
# self.noteMMWidgetLayout = QVBoxLayout()
# self.NOTEmainMenuWidget.setLayout(self.noteMMWidgetLayout)
# self.NOTEmainMenuWidget.setWindowTitle("Note Menu")
#
# self.NotemmButton1 = QPushButton("Admission", self)
# self.NotemmButton2 = QPushButton("Discharge", self)
# self.NotemmButton3 = QPushButton("Diag Testing", self)
# self.NotemmButton4 = QPushButton("Acute Visit", self)
# self.NotemmButton5 = QPushButton("Fall", self)
# self.NotemmButton6 = QPushButton("Med Review / Comp", self)
# self.NotemmButton7 = QPushButton("Coumadin", self)
# self.NotemmButton8 = QPushButton("Noncompliance", self)
# self.NotemmButton9 = QPushButton("Simple Note", self)
# self.noteMMWidgetLayout.addWidget(self.NotemmButton1)
# self.noteMMWidgetLayout.addWidget(self.NotemmButton2)
# self.noteMMWidgetLayout.addWidget(self.NotemmButton3)
# self.noteMMWidgetLayout.addWidget(self.NotemmButton4)
# self.noteMMWidgetLayout.addWidget(self.NotemmButton5)
# self.noteMMWidgetLayout.addWidget(self.NotemmButton6)
# self.noteMMWidgetLayout.addWidget(self.NotemmButton7)
# self.noteMMWidgetLayout.addWidget(self.NotemmButton8)
# self.noteMMWidgetLayout.addWidget(self.NotemmButton9)
# self.mdi.addSubWindow(self.NOTEmainMenuWidget)
# self.NOTEmainMenuWidget.show()
# self.NOTEMMButton2.clicked.connect(self.dcwindowFunc)
def admissionTool(self):
self.admitToolWidget = admitWindow()
self.mdi.addSubWindow(self.admitToolWidget)
self.admitToolWidget.show()
def COPDToolFunc(self):
self.copdToolWidget = COPDWindow()
self.mdi.addSubWindow(self.copdToolWidget)
self.copdToolWidget.show()
MDIWindow.copdcount = MDIWindow.copdcount + 1
def dcwindowFunc(self):
self.dcwindowWidget = DischargeWindow()
self.mdi.addSubWindow(self.dcwindowWidget)
self.dcwindowWidget.show()
def htnButton(self):
self.htnsubwidgets = QWidget(self)
self.htnMAinLayout = QHBoxLayout()
self.htnLeftLayout = QVBoxLayout()
self.htnRightLayout = QVBoxLayout()
##Adding secondary layours to main layouts##
self.htnMAinLayout.addLayout(self.htnLeftLayout)
self.htnMAinLayout.addLayout(self.htnRightLayout)
##Adding htnRightLayout widgets##
self.htnLabel1 = QLabel("Date of last HTN Med change", self)
self.htnDateEdit = QDateEdit(self)
self.htnDateEdit.setGeometry(QtCore.QRect(10, 30, 120, 45))
self.htnDateEdit.setObjectName("Med_change_dateEdit")
self.htnDateEdit.setDate(QtCore.QDate.currentDate())
self.htnDateEdit.setCalendarPopup(True)
self.htnQ2Label = QLabel("Med most recently changed?", self)
self.htnQ2LineEdit = QLineEdit()
self.htnQ3Label = QLabel("Most Recent bP Measurement", self)
self.htnQ3LineEdit = QLineEdit()
self.htnQ4Label = QLabel("Overall Bp Control?", self)
self.htnQ4Combobox = QComboBox()
self.htnQ4ComboboxList = ["Hypotension", "BP Well Controlled", "Some Hypertensive Episodes",
"Regular Hypertension"]
self.htnQ4Combobox.addItems(self.htnQ4ComboboxList)
self.htnq5Label = QLabel("Resident's current meds?", self)
self.htnq5LineEdit = QLineEdit()
self.htnCompleteButton = QPushButton("Complete", self)
self.htnCompleteButton.setMaximumWidth(75)
##Adding Widgets to Left Layout##
self.htnLeftLayout.addWidget(self.htnLabel1)
self.htnLeftLayout.addWidget(self.htnDateEdit)
self.htnLeftLayout.addWidget(self.htnQ2Label)
self.htnLeftLayout.addWidget(self.htnQ2LineEdit)
self.htnLeftLayout.addWidget(self.htnQ3Label)
self.htnLeftLayout.addWidget(self.htnQ3LineEdit)
self.htnLeftLayout.addWidget(self.htnQ4Label)
self.htnLeftLayout.addWidget(self.htnQ4Combobox)
self.htnLeftLayout.addWidget(self.htnq5Label)
self.htnLeftLayout.addWidget(self.htnq5LineEdit)
self.htnLeftLayout.addWidget(self.htnCompleteButton)
## Adding right widgets##
self.htntextedit = QTextEdit()
self.htntextedit.setMinimumWidth(200)
##Adding right widgets##
self.htnRightLayout.addWidget(self.htntextedit)
self.htnCompleteButton.clicked.connect(self.htnCompleteFunc)
self.htnsubwidgets.setLayout(self.htnMAinLayout)
self.mdi.addSubWindow(self.htnsubwidgets)
self.htnsubwidgets.show()
def htnCompleteFunc(self):
self.htnTotalList = [self.htnDateEdit.text(),self.htnQ2LineEdit.text(),self.htnQ3LineEdit.text(),self.htnQ4Combobox.currentText(),self.htnq5LineEdit.text()]
self.htntextedit.setText(f"The resient's most recent blood pressure med change ({self.htnTotalList[0]}) change was {self.htnTotalList[1]}. The residnet's most recent BP is {self.htnTotalList[2]}. The resdient is currently receiving {self.htnTotalList[4]}. Overall hypertension status: {self.htnTotalList[3]}")
def main():
app = QApplication(sys.argv)
font = QFont('Times', 10)
app.setFont(font)
mdiwindow = MDIWindow()
mdiwindow.show()
app.exec_()
if __name__ == '__main__':
main()ere
An example of one of my subwindowss is as follows:
from PyQt5 import QtCore
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtWidgets import QMdiArea, QAction, QMdiSubWindow, QTextEdit
from Admission_Tool import *
from COPD_tool import *
class NOTEWindow(QWidget):
def __init__(self):
super().__init__()
self.notemdi = QWidget()
self.setStyleSheet('font-size: 10pt; font-family: Times;')
self.setStyleSheet("QPushButton{font-size: 10pt;}")
self.setStyleSheet("QLabel{font-size: 10pt;}")
self.notemdi.setMaximumSize(500,500)
#Setting MAin Menu Widget for this nested MDI#
self.NOTEmainMenuWidget = QWidget(self)
self.noteMMWidgetLayout = QVBoxLayout()
self.NOTEmainMenuWidget.setLayout(self.noteMMWidgetLayout)
self.NOTEmainMenuWidget.setWindowTitle("Note Menu")
self.mmButton1 = QPushButton("Admission", self)
self.mmButton2 = QPushButton("Discharge", self)
self.mmButton3 = QPushButton("Diagnostic Testing", self)
self.mmButton4 = QPushButton("Acute Visit", self)
self.mmButton5 = QPushButton("Fall", self)
self.mmButton6 = QPushButton("Med Review/Comp", self)
self.mmButton7 = QPushButton("Coumadin", self)
self.mmButton8 = QPushButton("Noncompliance", self)
self.mmButton9 = QPushButton("Weight Loss", self)
self.mmButton10 = QPushButton("Simple Note",self)
self.noteMMWidgetLayout.addWidget(self.mmButton1)
self.noteMMWidgetLayout.addWidget(self.mmButton2)
self.noteMMWidgetLayout.addWidget(self.mmButton3)
self.noteMMWidgetLayout.addWidget(self.mmButton4)
self.noteMMWidgetLayout.addWidget(self.mmButton5)
self.noteMMWidgetLayout.addWidget(self.mmButton6)
self.noteMMWidgetLayout.addWidget(self.mmButton7)
self.noteMMWidgetLayout.addWidget(self.mmButton8)
self.noteMMWidgetLayout.addWidget(self.mmButton9)
self.noteMMWidgetLayout.addWidget(self.mmButton10)
self.NOTEmainMenuWidget.show()
def main():
app = QApplication(sys.argv)
font = QFont('Times', 10)
app.setFont(font)
mdiwindow = NOTEWindow()
mdiwindow.show()
app.exec_()
if __name__ == '__main__':
main()

Multithread and AttributeError: 'NoneType' object has no attribute 'groups'

We wrote this code in order to plot the data conteined in a txt file:
import pandas as pd
import plotly.express as px
import matplotlib.pyplot as plt
import re
import numpy as np
import os
names = ['CH','LG','HG','Ts(ns)','ToT(ns)']
righe_primo_header = 5
righe_header = 5
canali = 64
# input file
infile = 'Run1_list.txt'
# determinare numero di righe, poi di eventi nel file di input
stream = os.popen('wc -l '+ infile)
nrighe = stream.read()
match = re.match(r" (\S+)\s*", nrighe, re.I)
items = match.groups()
nrighe = float(items[0])
#print( 'nrighe = ',nrighe)
# numero di blocchi di dati da leggere
ntrigger = (nrighe - righe_primo_header) / (canali + righe_header) - 1
ntrigger = int( ntrigger)
print('trovati ',ntrigger,' eventi')
ncanali_histo = int(np.sqrt(ntrigger))
ncanali_histo = 4096
events = []
file1 = open( infile, 'r')
for line in range(righe_primo_header-1):
line = file1.readline()
#print('saltiamo riga ', line)
line=file1.readline()
for trigger in range(ntrigger):
#while line:
for lineh in range(righe_header):
line = file1.readline()
#print('saltiamo ',line)
for canale in range(canali):
line = file1.readline()
#print(' elaboriamo ',line)
match = re.match(r"(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+", line, re.I)
temparray = []
if match:
items = match.groups()
#print(items)
for colonna in range(len(items)):
col = items[colonna]
if col == '-':
valore = 0
else:
valore = float(items[colonna])
temparray.append( valore )
#print('blocco ', trigger, ' colonna ', colonna, ' ', items[colonna],' -> ',valore)
#print('temparray = ',temparray)
events.append(temparray)
file1.close()
print('ultimo trigger ID letto: ', trigger)
#print('events = ',events)
df = pd.DataFrame( events, columns = names)
print(df)
# istogramma di HG per canale fissato
canale = 44
plot_df = df.loc[ df['CH'] == canale ]
print('plot_df per istogramma:')
print(plot_df)
plot_df.hist(column='HG', bins=ncanali_histo)
plt.title('Multiphoton spectrum HG channel ' + str(canale) )
# seleziona un evento
evento = 3
plot_df = df[ (canali * evento):(canali*evento + canali) ]
print('plot_df per scatter plot:')
print(plot_df)
plot_df.plot.scatter(x='CH', y='HG', c='red')
plt.title('HG vs CH event ' + str(evento) )
plt.show()
This code perfectly works in MacOs but not in Linux and Windows (of course becouse we dont use wc command, no problem) and we get the following error:
Traceback (most recent call last):
File "Read_list.py", line 20, in <module>
items = match.groups()
AttributeError: 'NoneType' object has no attribute 'groups'
Why this errors happens?
Then, the txt file is of the order of GB, how can i run the code using the multithread? Can you help me?
I upload a small example of data here (see raw): https://pastebin.com/raw/PjVYc3vn
I resolve the firt issue:
import pandas as pd
import plotly.express as px
import matplotlib.pyplot as plt
import plotly.express as px
import plotly.graph_objects as go
import re
import numpy as np
import os
names = ['CH','LG','HG','Ts(ns)','ToT(ns)']
righe_primo_header = 5
righe_header = 5
canali = 64
# input file
infile = 'Run1_list.txt'
# determinare numero di righe, poi di eventi nel file di input
stream = os.popen('wc -l '+ infile)
nrighe = stream.read()
#print( 'nrighe = ',nrighe)
match = re.match(r"\s*(\S+) (.*)", nrighe, re.I)
#print( match)
items = match.groups()
nrighe = float(items[0])
#print( 'nrighe = ',nrighe)
# numero di blocchi di dati da leggere
ntrigger = (nrighe - righe_primo_header) / (canali + righe_header) - 1
ntrigger = int( ntrigger)
print('trovati ',ntrigger,' eventi')
ncanali_histo = int(np.sqrt(ntrigger))
ncanali_histo = 4096
events = []
file1 = open( infile, 'r')
for line in range(righe_primo_header-1):
line = file1.readline()
#print('saltiamo riga ', line)
line=file1.readline()
for trigger in range(ntrigger):
#while line:
for lineh in range(righe_header):
line = file1.readline()
#print('saltiamo ',line)
for canale in range(canali):
line = file1.readline()
#print(' elaboriamo ',line)
match = re.match(r"(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+", line, re.I)
temparray = []
if match:
items = match.groups()
#print(items)
for colonna in range(len(items)):
col = items[colonna]
if col == '-':
valore = 0
else:
valore = float(items[colonna])
temparray.append( valore )
#print('blocco ', trigger, ' colonna ', colonna, ' ', items[colonna],' -> ',valore)
#print('temparray = ',temparray)
events.append(temparray)
file1.close()
print('ultimo trigger ID letto: ', trigger)
#print('events = ',events)
df = pd.DataFrame( events, columns = names)
print('Il dataframe totale è il seguente: ', df)
# istogramma di HG per canale fissato
canale = 44
plot_df = df.loc[ (df['CH'] == canale) | (df['CH'] == 50)]
print('Il dataframe selezionato è il seguente: ', plot_df)
pd.options.mode.chained_assignment = None # default='warn'
plot_df['HG'][df['CH']==44] *= (1.096)
fig = px.histogram(plot_df, x='HG', color='CH', barmode='overlay', opacity=0.8, title='Multiphoton spectrum HG channel')
fig.update_traces(xbins=dict(start=0.0, end=4096.0, size=1))
fig.show()
# seleziona un evento
evento = 3
plot_df2 = df[(canali * evento):(canali*evento + canali)]
print('Il dataframe per lo scatter plot HG vs Ch relativo all evento ',evento, 'è il seguente: ', plot_df2)
fig2 = px.scatter(plot_df2, x='CH', y='HG', title='HG vs CH event ' + str(evento) )
fig2.show()
Now, how can i compile it in multithread?

Why the script doesn't receive data from mosquitto?

I have following code which receive data from different MQTT topics.
#!/usr/bin/python3
import paho.mqtt.client as mqtt
import pymysql
import json
import sys
import time
#-### Constantes ####
PUERTO_MQTT = ...
USUARIO = ...
CLAVE = ...
#DB_LOCAL = ...
DB_LOCAL = ...
RETARDO_SUSCRIP = 30 #s
#-### Variables ####
idsNgsConectados = set()
clienteMQTT = mqtt.Client("receptor_datos_ngs")
db_local = None
t1 = 0
t2 = 0
#-### Funciones ####
def on_connect(clienteMQTT, userdata, flags, rc):
print("Conexion establecida con el broker MQTT correctamente")
def on_message(clienteMQTT, userdata, msg):
msg_str = msg.payload.decode('utf-8')
# procesamiento de los mensajes MQTT
posPrimeraBarra = msg.topic.find('/')
print("topic: {}".format(msg.topic))
print("datos: {}".format(msg_str))
if posPrimeraBarra != -1:
id_ngs = int(msg.topic[:posPrimeraBarra])
ref_medicion = msg.topic[posPrimeraBarra+1:]
variables = json.loads(msg_str)
if type(variables) is dict:
if id_ngs in idsNgsConectados:
try:
cursor = db_local.cursor()
cursor.execute("INSERT INTO mediciones (id_ngs, referencia) VALUES ({}, '{}')".format(id_ngs, ref_medicion))
db_local.commit()
cursor.execute("SELECT id FROM mediciones WHERE (id_ngs={} AND referencia='{}') ORDER BY id DESC LIMIT 1".format(id_ngs, ref_medicion))
id_medicion = cursor.fetchone()[0]
for var in variables:
cursor.execute("INSERT INTO valores_mediciones (id_medicion, variable, valor) VALUES ({},'{}',{})".format(id_medicion, var, variables[var]))
db_local.commit()
cursor.close()
except Exception as e:
db_local.rollback()
print("Error 1: fallo el procesamiento de un mensaje MQTT: " + str(e), file=sys.stderr)
sys.exit(1)
else:
print("Advertencia: un ngs envio datos sin haberse presentado, por lo que se le indicara que salude primero", file=sys.stderr)
clienteMQTT.publish(str(id_ngs),"saludar",qos=1)
else:
print("Advertencia: un ngs envio datos con un formato incorrecto por lo que se le indicara que se reinicie", file=sys.stderr)
clienteMQTT.publish(str(id_ngs),"reiniciar",qos=1)
def sub_topics():
global clienteMQTT
cursor = db_local.cursor()
cursor.execute('SELECT id FROM ngs')
ids_ngs = cursor.fetchall()
cursor.close()
print("Topics suscriptos:")
for id_ngs in ids_ngs:
id_ngs = id_ngs[0]
idsNgsConectados.add(id_ngs)
topic = str(id_ngs) + '/#'
print("\t{}".format(topic))
clienteMQTT.subscribe(topic)
try:
db_local = pymysql.connect( unix_socket='/run/mysqld/mysqld.sock',
user=USUARIO,
password=CLAVE,
db=DB_LOCAL )
clienteMQTT.on_connect = on_connect
clienteMQTT.on_message = on_message
clienteMQTT.username_pw_set(username=USUARIO, password=CLAVE)
clienteMQTT.connect("localhost", PUERTO_MQTT)
clienteMQTT.loop_start()
# Bucle infinito
while True:
time.sleep(RETARDO_SUSCRIP)
# Suscripcion a los topics de todos los ngs
sub_topics()
except Exception as e:
db_local.close()
clienteMQTT.loop_stop()
clienteMQTT.disconnect()
print("Error 2: desconocido: " + str(e), file=sys.stderr)
sys.exit(2)
The script subscribe dinamically to the topics. If I run the script from the shell it works well, but if a setup it to be run at boot using systemd, it fails. I've setup the unit file to require and to be run after mosquitto, mariadb, dhcpcd and wpa_supplicant services. I'm sure the data is being publish from another device because I can receive it using "mosquitto_sub".
Which could it be the reason?
It runs in a Raspberry pi zero w and the Mosquitto version is 1.5.7.
I could find the cause of the problem and it wasn't because of mosquitto or paho-mqtt, it was because of pymysql. The fail in the code was that I wasn't using the method commit() in the sql transaction. That was causing the code to not being able to get the new data that were being introduced by another process in the database. That's because of the InnoDB's default isolation level REPEATABLE READ. You can read more about that here. The correct way to make that sql transaction is the following:
def sub_topics():
cursor = db_local.cursor()
cursor.execute('SELECT id FROM ngs')
ids_ngs = cursor.fetchall()
print("Topics suscriptos:")
for id_ngs in ids_ngs:
id_ngs = id_ngs[0]
idsNgsConectados.add(id_ngs)
topic = str(id_ngs) + '/#'
print("\t{}".format(topic))
clienteMQTT.subscribe(topic)
db_local.commit()
cursor.close()
That data is used by this code to determine which topics it has to subscribe to, and because of that the code wasn't subscribing to the expected topics and so it wasn't receiving the related data from mosquitto.
The pymysql documentation doesn't cover that topic, so I recommend to the newbies (I've realizaed that I'm 50% newbie 50% pro jaja) to read about ACID and the implementation details of the RDBMS that you're using.

Dimension problems in scipy.optimize.minimize

I'm having some dimensions problems but I've checked all the constraints dimensions and there doesn't seem to be an error, if someone could help me I would appreciate it.
# Librerias necesarias
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize
# Constantes de eficiencia de los conversores del EH
# CHP
n_W = 0.3 # Electricidad
n_Q = 0.45 # Termal
# AB
n_T = 0.8 # Termal
# CERG
COP_CERG = 3
# WARG
COP_WARG = 0.7
# Limites superiores
v_p_CHP = np.array([0,300,450,0])
v_p_AB = np.array([0,0,900,0])
v_p_CERG = np.array([0,0,0,400])
v_p_WARG = np.array([0,0,0,400])
# Limites inferiores
v_d_CHP = np.array([0,300/2,450/2,0])
v_d_AB = np.array([0,0,0,0])
v_d_CERG = np.array([0,0,0,0])
v_d_WARG = np.array([0,0,0,0])
# Precio del gas
P_g = 0.02 #kW/h
# Precio electricidad
P_e = np.array([0,40,20,35,40,60,110,120,115,75,80,120,90,70,60,40])
# Demanda de electricidad, calefacción y refrigeración
D_h = np.array([0,200,320,400,580,550,520,500,470,420,320,200])
D_e = np.array([0,150,210,180,175,180,210,160])
D_c = np.array([0,0,25,50,75,125,150,125,75,50,25,0])
# Matrices de espeficicacion por componente
M = 4 # Numero de vectores de energia (Electricidad,gas,calefaccion y regrigeracion)
zero_vect_v = np.zeros((1,4))
zero_vect_h = np.zeros((4,1))
# H_CHP
H_CHP = np.array([[0,0,0,0],
[n_W,0,0,0],
[n_Q,0,0,0],
[0,0,0,0]])
# H_AB
H_AB = np.array([[0,0,0,0],
[0,0,0,0],
[n_T,0,0,0],
[0,0,0,0]])
# H_WARG
H_WARG = np.array([[0,0,0,0],
[0,0,0,0],
[0,0,0,0],
[0,0,COP_WARG,0]])
# H_CERG
H_CERG = np.array([[0,0,0,0],
[0,0,0,0],
[0,0,0,0],
[0,COP_CERG,0,0]])
# Matrices de interconección
def T_o_AB(X):
return np.diag([0,0,X[5],0])
def T_o_CHP(X):
return np.diag([0,X[2],X[3],0])
T_o_CERG = np.diag([0,0,0,1])
T_o_WARG = np.diag([0,0,0,1])
def T_o_EDS(X):
return np.diag([0,X[0],0,0])
def T_AB_i(X):
return np.diag([1-X[1],0,0,0])
def T_CHP_i(X):
return np.diag([X[1],0,0,0])
def T_CERG_CHP(X):
return np.diag([0,1-X[2],0,0])
def T_CERG_i(X):
return np.diag([0,1,1-X[0],0])
def T_WARG_AB(X):
return np.diag([0,0,1-X[5],0])
def T_WARG_CHP(X):
return np.diag([0,0,X[4],0])
T_zero = np.zeros((M,M))
I = np.identity(M)
# Costo de la electricidad por horas
# Dominio del tiempo (rangos de tiempo)
P_tiempo = np.arange(1,25,1)
# Definicion del vector de demanda eléctrica
P_e_vect_1 = np.zeros((P_tiempo.shape[0]))
P_e_vect_1[(P_tiempo>=0) & (P_tiempo<=2)] = P_e[1]
P_e_vect_1[(P_tiempo>2) & (P_tiempo<=6)] = P_e[2]
P_e_vect_1[(P_tiempo>6) & (P_tiempo<=7)] = P_e[3]
P_e_vect_1[(P_tiempo>7) & (P_tiempo<=8)] = P_e[4]
P_e_vect_1[(P_tiempo>8) & (P_tiempo<=9)] = P_e[5]
P_e_vect_1[(P_tiempo>9) & (P_tiempo<=10)] = P_e[6]
P_e_vect_1[(P_tiempo>10) & (P_tiempo<=12)] = P_e[7]
P_e_vect_1[(P_tiempo>12) & (P_tiempo<=13)] = P_e[8]
P_e_vect_1[(P_tiempo>13) & (P_tiempo<=15)] = P_e[9]
P_e_vect_1[(P_tiempo>15) & (P_tiempo<=19)] = P_e[10]
P_e_vect_1[(P_tiempo>19) & (P_tiempo<=20)] = P_e[11]
P_e_vect_1[(P_tiempo>20) & (P_tiempo<=21)] = P_e[12]
P_e_vect_1[(P_tiempo>21) & (P_tiempo<=22)] = P_e[13]
P_e_vect_1[(P_tiempo>22) & (P_tiempo<=23)] = P_e[14]
P_e_vect_1[(P_tiempo>23) & (P_tiempo<=24)] = P_e[15]
P_e_vect_1 = P_e_vect_1/1000
# Demanda
# Definicion del vector para demanda electricidad
P_e_vect_d_1 = np.zeros((P_tiempo.shape[0]))
P_e_vect_d_1[(P_tiempo>=0) & (P_tiempo<=8)] = D_e[1]
P_e_vect_d_1[(P_tiempo>8) & (P_tiempo<=12)] = D_e[2]
P_e_vect_d_1[(P_tiempo>12) & (P_tiempo<=15)] = D_e[3]
P_e_vect_d_1[(P_tiempo>15) & (P_tiempo<=18)] = D_e[4]
P_e_vect_d_1[(P_tiempo>18) & (P_tiempo<=19)] = D_e[5]
P_e_vect_d_1[(P_tiempo>19) & (P_tiempo<=20)] = D_e[6]
P_e_vect_d_1[(P_tiempo>20) & (P_tiempo<=24)] = D_e[7]
# Definicion del vector para demanda refrigeracion
P_c_vect_d_1 = np.zeros((P_tiempo.shape[0]))
P_c_vect_d_1[(P_tiempo>=0) & (P_tiempo<=9)] = D_c[1]
P_c_vect_d_1[(P_tiempo>=9) & (P_tiempo<=10)] = D_c[2]
P_c_vect_d_1[(P_tiempo>=10) & (P_tiempo<=12)] = D_c[3]
P_c_vect_d_1[(P_tiempo>=12) & (P_tiempo<=13)] = D_c[4]
P_c_vect_d_1[(P_tiempo>=13) & (P_tiempo<=14)] = D_c[5]
P_c_vect_d_1[(P_tiempo>=14) & (P_tiempo<=15)] = D_c[6]
P_c_vect_d_1[(P_tiempo>=15) & (P_tiempo<=16)] = D_c[7]
P_c_vect_d_1[(P_tiempo>=16) & (P_tiempo<=17)] = D_c[8]
P_c_vect_d_1[(P_tiempo>=17) & (P_tiempo<=18)] = D_c[9]
P_c_vect_d_1[(P_tiempo>=18) & (P_tiempo<=19)] = D_c[10]
P_c_vect_d_1[(P_tiempo>=19) & (P_tiempo<=24)] = D_c[11]
# Definicion del vector para demanda calefaccion
P_h_vect_d_1 = np.zeros((P_tiempo.shape[0]))
P_h_vect_d_1[(P_tiempo>=0) & (P_tiempo<=6)] = D_h[1]
P_h_vect_d_1[(P_tiempo>=6) & (P_tiempo<=7)] = D_h[2]
P_h_vect_d_1[(P_tiempo>=7) & (P_tiempo<=8)] = D_h[3]
P_h_vect_d_1[(P_tiempo>=8) & (P_tiempo<=12)] = D_h[4]
P_h_vect_d_1[(P_tiempo>=12) & (P_tiempo<=13)] = D_h[5]
P_h_vect_d_1[(P_tiempo>=13) & (P_tiempo<=14)] = D_h[6]
P_h_vect_d_1[(P_tiempo>=14) & (P_tiempo<=16)] = D_h[7]
P_h_vect_d_1[(P_tiempo>=16) & (P_tiempo<=17)] = D_h[8]
P_h_vect_d_1[(P_tiempo>=17) & (P_tiempo<=21)] = D_h[9]
P_h_vect_d_1[(P_tiempo>=21) & (P_tiempo<=23)] = D_h[10]
P_h_vect_d_1[(P_tiempo>=23) & (P_tiempo<=24)] = D_h[11]
# Arreglo de dimensiones
P_e_vect_d_1 = np.array([P_e_vect_d_1])
P_c_vect_d_1 = np.array([P_c_vect_d_1])
P_h_vect_d_1 = np.array([P_h_vect_d_1])
# Concatenar los vectores de demanda
Vout = np.concatenate((np.zeros((1,24)),P_e_vect_d_1,P_h_vect_d_1,P_c_vect_d_1),axis=0)
Vout = Vout.T
# Construccion de matriz H
def H_matrix(X):
return T_o_EDS(X)*I + T_o_AB(X)*H_AB*T_AB_i(X)*I + T_o_CHP(X)*H_CHP*T_CHP_i(X)*I + T_o_CERG#H_CERG*(T_CERG_i(X)*I + T_CERG_CHP(X)*H_CHP*T_CHP_i(X)*I) + T_o_WARG#H_WARG*(T_WARG_AB(X)*H_AB*T_AB_i(X)*I + T_WARG_CHP(X)*H_CHP*T_CHP_i(X)*I)
save_results = [] # Lista para guardar los resultados
# Problema de optimizacion
for t in P_tiempo:
# Definicion de la funcion de costo
def objective_function(X):
return P_e_vect_1[t-1]*X[7] + P_g*X[6]
# Restricciones
cons = ({'type': 'eq',
'fun': lambda X: H_matrix(X)#np.array([[X[6]],[X[7]],[0],[0]]) - Vout[t-1,:].T },
{'type': 'eq',
'fun': lambda X: H_CHP#np.array([[X[1]*X[6]],[0],[0],[0]]) - np.array([[0],[X[8]],[X[9]],[0]])},
{'type': 'eq',
'fun': lambda X: H_AB#np.array([[(1-X[1])*X[6]],[0],[0],[0]]) - np.array([[0],[0],[X[10]],[0]])},
{'type': 'eq',
'fun': lambda X: H_WARG#np.array([[0],[0],[X[4]*X[9]+(1-X[5])*X[10]],[0]]) - np.array([[0],[0],[0],[X[12]]])},
{'type': 'eq',
'fun': lambda X: H_CERG#np.array([[0],[(1-X[0])*X[7]+(1-X[2])*X[8]],[0],[0]]) - np.array([[0],[0],[0],[X[11]]])},
{'type': 'ineq',
'fun': lambda X: -(X[0]-1)*X[7]},
{'type': 'ineq',
'fun': lambda X: -(H_CHP#np.array([[X[1]*X[6]],[0],[0],[0]]) - v_p_CHP.T)},
{'type': 'ineq',
'fun': lambda X: -(H_AB#np.array([[(1-X[1])*X[6]],[0],[0],[0]]) - v_p_AB.T)},
{'type': 'ineq',
'fun': lambda X: -(H_WARG#np.array([[0],[0],[X[4]*X[9]+(1-X[5])*X[10]],[0]]) - v_p_WARG.T)},
{'type': 'ineq',
'fun': lambda X: -(H_CERG#np.array([[0],[(1-X[0])*X[7]+(1-X[2])*X[8]],[0],[0]]) - v_p_CERG.T)},
{'type': 'ineq',
'fun': lambda X: -(v_d_CHP.T - H_CHP#np.array([[X[1]*X[6]],[0],[0],[0]]))},
{'type': 'ineq',
'fun': lambda X: (H_AB#np.array([[(1-X[1])*X[6]],[0],[0],[0]]))},
{'type': 'ineq',
'fun': lambda X: (H_WARG#np.array([[0],[0],[X[4]*X[9]+(1-X[5])*X[10]],[0]]))},
{'type': 'ineq',
'fun': lambda X: (H_CERG#np.array([[0],[(1-X[0])*X[7]+(1-X[2])*X[8]],[0],[0]]))})
# Condicion inicial
if t == 1:
x0 = np.zeros((13,1))
else:
x0 = save_results[t-2]
# Bounds
bnds = ((0, 1),(0, 1),(0, 1),(0, 1),(0, 1),(0, 1),(0, None),(0, None),(0, None),(0, None),(0, None),(0, None),(0, None))
# Problema de optimizacion
sol = minimize(objective_function,x0,constraints=cons,bounds=bnds)
solution = sol.x
save_results.append(solution)
It shows this error: ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 1, the array at index 0 has size 4 and the array at index 1 has size 1.
I look at the eq constraints because apparently the error's there but all the dimensions of the matrices and vector match.

Scrapy CrawlSpider - Yielding multiple items from a single spider

i'm very new either with Scrapy or Python so my vocabulary might be inacurate
I'm trying to get two different items with my CrawlSpider, but i cannot find out how to do it. Currently only the first item "CourseItem" is crawled, the other one is not executed at all.
I believe it's probably the way im calling everything but can't figure exactly what. (callback=parse_course) ?
Each function is working properly if i make one spider per item.
I've tried to put everything in the same function but it doesn't help either.
spider.py
# -*- coding: utf-8 -*-
import scrapy
import re
import datetime
from scrapy.http import Request
from scrapy_spider.items import CourseItem, PronosticItem
from scrapy.spiders import Rule
from scrapy.linkextractors import LinkExtractor
class GenycourseSpider(scrapy.spiders.CrawlSpider):
name = 'genycourse'
allowed_domains = ['www.geny.com']
rules = (
Rule(
LinkExtractor(allow='/partants-pmu/*'), callback="parse_course"
),
)
def start_requests(self):
date = datetime.date(2016, 03, 12)
datefin = datetime.date(2016, 03, 12)
while date <= datefin:
url = 'http://www.geny.com/reunions-courses-pmu?date=%s' % date.isoformat()
date = date + datetime.timedelta(days=1)
yield Request(url)
def parse_course(self, response):
#Recupération des valeurs
date = response.request.url
reunion = response.xpath("//*[#id='yui-main']/div/div[2]/div[1]/text()").extract_first().strip()
course = response.xpath("//*[#id='yui-main']/div/div[2]/div[3]/span/strong/text()[1]").extract_first().strip()
type = response.xpath("//*[#id='yui-main']/div/div[2]/span").extract_first().strip()
hippodrome = response.xpath("//*[#id='navigation']/a[3]/text()").extract_first()
#Nettoyage du resultat
#On isole la date
date = date[33:43]
#On coupe au niveau de ( et on garde le numéro de la réunion
temp = re.split(r"\(", reunion)
reunion = temp [1]
reunion = re.sub(r'[R\)]', '', reunion)
#On identifie les courses et les stocke
type = re.findall(r'(Attel|Plat|Haies|Steeple-chase|Cross|Mont)', type)
plat = "Plat" in type
obstacle = "Haies" or "Steeple-chase" in type
#On met en place l'objet
courseinfo = CourseItem()
courseinfo['date'] = date
courseinfo['reunion'] = reunion
courseinfo['course'] = course
courseinfo['type'] = type
courseinfo['hippodrome'] = hippodrome
loopcheval = 1
numerocheval = 1
while numerocheval != None:
numerocheval = response.xpath("//*[#id='tableau_partants']/tbody/tr["+ str(loopcheval) +"]/td[1]/text()").extract_first()
if plat is True:
cotecheval = response.xpath("//*[#id='tableau_partants']/tbody/tr["+ str(loopcheval) +"]/td[12]/text()").extract_first().strip()
elif obstacle is True:
cotecheval = response.xpath("//*[#id='tableau_partants']/tbody/tr["+ str(loopcheval) +"]/td[11]/text()").extract_first().strip()
else:
cotecheval = response.xpath("//*[#id='tableau_partants']/tbody/tr["+ str(loopcheval) +"]/td[10]/text()").extract_first().strip()
if numerocheval is not None:
courseinfo['numero'] = numerocheval
courseinfo['cote'] = cotecheval
yield courseinfo
loopcheval = loopcheval + 1
def parse_prono(self, response):
date = response.request.url
reunion = response.xpath("//*[#id='yui-main']/div/div[2]/div[1]/text()").extract_first().strip()
course = response.xpath("//*[#id='yui-main']/div/div[2]/div[3]/span/strong/text()[1]").extract_first().strip()
date = date[33:43]
temp = re.split(r"\(", reunion)
reunion = temp [1]
reunion = re.sub(r'[R\)]', '', reunion)
pronoinfo = PronosticItem()
pronoinfo['date'] = date
pronoinfo['reunion'] = reunion
pronoinfo['course'] = course
ligne = 1
testpronostique = pronostiqueur = response.xpath("//*[#id='selectionsPresse']/table/tr[1]/td[1]/div/div[1]").extract_first()
if testpronostique is None:
pronoinfo['pronostiqueur'] = 'Pas de pronostic'
pronoinfo['premier'] = 0
pronoinfo['second'] = 0
yield pronoinfo
else:
while ligne <= 3:
while ligne <= 2:
colonne = 1
while colonne <= 3:
pronostiqueur = response.xpath("//*[#id='selectionsPresse']/table/tr["+ str(ligne) +"]/td["+ str(colonne) +"]/div/div[1]").extract_first()
pronostiqueur = re.findall(r'(Radio|AIP|Sud|Presse|Casaque|Courrier|che)', pronostiqueur)
pronostique = response.xpath("//*[#id='selectionsPresse']/table/tr["+ str(ligne) +"]/td["+ str(colonne) +"]/div/div[2]/text()").extract_first().strip()
pronostique = re.split(r" - ", pronostique)
premier = pronostique [0]
second = pronostique [1]
pronoinfo['pronostiqueur'] = pronostiqueur
pronoinfo['premier'] = premier
pronoinfo['second'] = second
yield pronoinfo
colonne = colonne + 1
if colonne == 4:
ligne = ligne + 1
if ligne == 3:
pronostiqueur = response.xpath("//*[#id='selectionsPresse']/table/tr[3]/td[1]/div/div[1]").extract_first()
pronostiqueur = re.findall(r'(Radio|AIP|Sud|Presse|Casaque|Courrier|che)', pronostiqueur)
pronostique = response.xpath("//*[#id='selectionsPresse']/table/tr[3]/td[1]/div/div[2]/text()").extract_first().strip()
pronostique = re.split(r" - ", pronostique)
premier = pronostique [0]
second = pronostique [1]
pronoinfo['pronostiqueur'] = pronostiqueur
pronoinfo['premier'] = premier
pronoinfo['second'] = second
yield pronoinfo
ligne = ligne + 1
items.py
class CourseItem(scrapy.Item):
date = scrapy.Field()
reunion = scrapy.Field()
course = scrapy.Field()
type = scrapy.Field()
hippodrome = scrapy.Field()
numero = scrapy.Field()
cote = scrapy.Field()
class PronosticItem(scrapy.Item):
date = scrapy.Field()
reunion = scrapy.Field()
course = scrapy.Field()
pronostiqueur = scrapy.Field()
premier = scrapy.Field()
second = scrapy.Field()
Im expecting to get both CourseItem() and PronosticItem() to get populated and sent to pipeplines and not just only CourseItem()
Thanks for your help !