[Python] [Risolto] Sequenza di comandi che non funziona se inserito in script diversi

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Scrivi risposta
Avatar utente
Lapa
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 362
Iscrizione: mercoledì 30 dicembre 2009, 17:01

[Python] [Risolto] Sequenza di comandi che non funziona se inserito in script diversi

Messaggio da Lapa »

Buongiorno,
mi capita un problema che ho difficoltà a spiegarmi.
Sto editando uno script che contiene diverse funzioni.
Queste le provo singolarmente in un file di prova con tutte le librerie. Quando funzionano le inserisco sul file completo che ha le stesse librerie.
Con una di queste funzioni mi capita che nel file di prova esegue correttamente i comandi, nel file completo sembra funzionare perché non mi dà nessun errore ma in effetti non esegue quanto scritto nei comandi.
La parte di script che sto provando si occupa di operazioni all'interno di un foglio elettronico Excell, del tipo: fa la media dei dati in una colonna e li inserisce in caselle specifiche di un altro foglio e così via. Può darsi che il comando che funziona nel file di prova e in quello completo no, sia quello che salva il foglio Excell per cui quando vado a verificare il file Excell non lo trovo aggiornato.

Vi ringrazio per i suggerimenti che vorrete fornirmi.
Un saluto a tutti
LaPa
Ultima modifica di Lapa il domenica 11 dicembre 2022, 20:22, modificato 1 volta in totale.
Eterno imbranato su Ubuntu Linux e .... in tantissime altre cose :D
korda
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1230
Iscrizione: giovedì 24 dicembre 2020, 15:58

Re: [Python] Sequenza di comandi che non funziona se inserito in script diversi

Messaggio da korda »

Per poterti aiutare dovresti postare qui il tuo codice o quantomeno il chunck che presenta problemi :ciao:
Io non sono Bagheera né Akela, io non frequento la Rupe.
Io sono Kaa: faccio ballare le scimmie alle Tane Fredde.
Avatar utente
nuzzopippo
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1532
Iscrizione: giovedì 12 ottobre 2006, 11:34

Re: [Python] Sequenza di comandi che non funziona se inserito in script diversi

Messaggio da nuzzopippo »

Quoto @korda, serve il codice e forse potrebbe non essere sufficiente, dici di non avere errori, quindi mancherebbe un traceback da valutare, hai provato a valutare (magari con dei print) eventuali variabili interessate in entrambi gli ambienti?
Fatti non foste a viver come bruti ...
Avatar utente
Lapa
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 362
Iscrizione: mercoledì 30 dicembre 2009, 17:01

Re: [Python] Sequenza di comandi che non funziona se inserito in script diversi

Messaggio da Lapa »

Buonasera,
Ecco il primo chunk:

Chunk che funziona

Codice: Seleziona tutto

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




#******* M O D U L I   *********

import datetime
from datetime import datetime
import openpyxl
#import RPi.GPIO as GPIO
#GPIO.setwarnings(False)
import time
import sys
import gspread
#import oauth2client.client
#import json
import os
import ftplib


#*****************  D E F I N I Z I O N I   D E I   F O G L I   S T O R E  *****************     

wb=openpyxl.load_workbook('/home/pi/plant+out/store.xlsx')
ws=wb["Sheet1"]
ws1=wb["ultime48ore"]
ws2=wb["ultimaSettimana"]
ws3=wb["ultime2settimane"]
ws4=wb["ultimoMese"]
ws5=wb["datiGiornalieri"]

#*****************  F U N Z I O N I  D A   P R O V A R E  *****************
def mediaDatiInRiga49DiUltime48Ore():
#se lo script viene lanciato allo scoccare dell'ora verranno fatte le medie del 4 valori
#partendo dal quintultimo e la media saranno i 4 volori rilevati nell'ora precedente.
    nc=9#indichiamo il numero di colonne per il quale deve essere ripetuta la media
    mediaValori=[]
    for s in range (2,nc):#s=il numero della colonna
        l=[]#creo una lista vuota
        n=(ws.max_row-3)
        print ("il numero della colonna dove sto facendo la media degli ultimi 4 valori rilevati è ", s)
        print (n, " è la riga dove iniziare la media dei valori")
        
    
        for d in range (4):#per 4 volte
            print("la riga di lettura attuale è ",n)
            v=ws.cell(row=n,column=s).value #estrae il valore della prima riga della colonna s e lo chiama v
            #v=cell.value
            if v!=None:
                v=float(v)#lo converto in numero altrimenti non fa i calcoli
            else:
                v=0
                #print("il valore della cella estratta alla riga ", n," è ", v)
            l[d:d]=[v] #dovrebbe inserirlo nell lista
            n=n+1
            d=d+1#sposta la posizione nella lista di 1
            
            
        print(l)
        a=sum(l)/len(l)#chiamo a la media dei valori nella lista
        a=round(a,2) #arrotondo la media a 2 cifre
        print("la media dei valori di ", ws.cell(row=1, column=s).value," degli ultimi 4 rilievi è ",a)
        print(s)
       
      
        #time.sleep(2)
        mediaValori.append(a)
       
    
    
    print("La media oraria dei valori rilevati è ",mediaValori)
    ultimaRigaSheet1=ws.max_row
    dataOra=ws.cell(row=(ultimaRigaSheet1-1),column=1).value
    #print (dataOra)
    #print("data è ",type(dataOra))
    dataOra=datetime.strptime(dataOra, "%d/%m/%Y %H:%M:%S")
    #print (dataOra)
    dataOra=dataOra.strftime('%d/%m/%Y %H')
    print ("data ora con strftime è ",dataOra)
    #print (type(dataOra))

    TAmb=mediaValori[0]
    UR=mediaValori[1]
    Luce=mediaValori[2]
    BS10=mediaValori[3]
    TS10=mediaValori[4]
    BS30=mediaValori[5]
    TS30=mediaValori[6]
    
    ws1['A49'] = dataOra
    ws1['B49'] = TAmb
    ws1['C49'] = UR
    ws1['D49'] = Luce
    ws1['E49'] = BS10
    ws1['F49'] = TS10
    ws1['G49'] = BS30
    ws1['H49'] = TS30
    print ("ho inserito tutti i dati orari al rigo 49 del foglio 48ore di store")
    wb.save("/home/pi/plant+out/store.xlsx")
    print("ho salvato store")
    
    
#***********************

def scrivi48oreStore():        
    ultimaRigaSheet1=ws.max_row
    print("l'ultima riga del foglio 1 di store e' ",ultimaRigaSheet1)

    ultima48ore=ws1.max_row
    print("l'ultima riga del foglio 48 ore e' ",ultima48ore)


    if ultimaRigaSheet1<5:
        print("ci sono meno di 4 dati scritti nel foglio1 di store non fare nessun calcolo, termina questa funzione e proseguo altre")
        print("non ho salvato store perchÉ non ho scritto niente di nuovo")
    elif ultimaRigaSheet1>=5 and ultima48ore<49:
        print("attiva la parte di script che fa la media oraria e aggiunge i dati della media oraria al foglio 48 ore")
        #se lo script viene lanciato allo scoccare dell'ora verranno fatte le medie del 4 valori
        #partendo dal quintultimo e la media saranno i 4 volori rilevati nell'ora precedente.
        ultimaRigaSheet1=ws.max_row
        print("l'ultima riga scritta nello sheet1 nel file store è ", ultimaRigaSheet1)
        nc=9#indichiamo il numero di colonne per il quale deve essere ripetuta la media
        mediaValori=[]
        for s in range (2,nc):#s=il numero della colonna
            l=[]#creo una lista vuota
            n=(ws.max_row-3)
            print ("il numero della colonna dove sto facendo la media degli ultimi 4 valori rilevati è ", s)
            print (n, " è la riga dove iniziare la media dei valori")          
            for d in range (4):#per 4 volte
                print("la riga di lettura attuale è ",n)
                v=ws.cell(row=n,column=s).value #estrae il valore della prima riga della colonna s e lo chiama v
                #v=cell.value
                if v!=None:
                    v=float(v)#lo converto in numero altrimenti non fa i calcoli
                else:
                    v=0
                    #print("il valore della cella estratta alla riga ", n," è ", v)
                l[d:d]=[v] #dovrebbe inserirlo nell lista
                n=n+1
                d=d+1#sposta la posizione nella lista di 1
        
        
            print(l)
            a=sum(l)/len(l)#chiamo a la media dei valori nella lista
            a=round(a,2) #arrotondo la media a 2 cifre
            print("la media dei valori di ", ws.cell(row=1, column=s).value," degli ultimi 4 rilievi è ",a)
            print(s)
   
  
            #time.sleep(2)
            mediaValori.append(a)
   


        print("La media oraria dei valori rilevati è ",mediaValori)
        dataOra=ws.cell(row=(ultimaRigaSheet1-1),column=1).value
        #print (dataOra)
        #print("data è ",type(dataOra))
        dataOra=datetime.strptime(dataOra, "%d/%m/%Y %H:%M:%S")
        #print (dataOra)
        dataOra=dataOra.strftime('%d/%m/%Y %H')
        print ("data ora con strftime è ",dataOra)
        #print (type(dataOra))

        TAmb=mediaValori[0]
        UR=mediaValori[1]
        Luce=mediaValori[2]
        BS10=mediaValori[3]
        TS10=mediaValori[4]
        BS30=mediaValori[5]
        TS30=mediaValori[6]
        print ("la media dei dati orari in ", dataOra, "è ", TAmb," ", UR," ", Luce," ", BS10," ", TS10," ", BS30," ", TS30)
        ws1.cell(row=ultima48ore+1, column=1).value = dataOra
        ws1.cell(row=ultima48ore+1, column=2).value = TAmb
        ws1.cell(row=ultima48ore+1, column=3).value = UR
        ws1.cell(row=ultima48ore+1, column=4).value = Luce
        ws1.cell(row=ultima48ore+1, column=5).value = BS10
        ws1.cell(row=ultima48ore+1, column=6).value = TS10
        ws1.cell(row=ultima48ore+1, column=7).value = BS30
        ws1.cell(row=ultima48ore+1, column=8).value = TS30
        print ("ho inserito tutti i dati orari al rigo ",ultima48ore+1,"del foglio ultime48ore di store")
        wb.save("/home/pi/plant+out/store.xlsx")
        print("ho salvato store")
        
    elif ultimaRigaSheet1>=5 and ultima48ore==49:
        print("attiva la parte di script che fa la media oraria e in 48ore sposta i dati un rigo più in alto ed inserisce la media appena fatta al rigo 49")
        ws1.move_range("A3:H49", rows=-1, cols=0)
        print("ho spostato i dati di una riga in alto in ultime48ore")
        mediaDatiInRiga49DiUltime48Ore()
        wb.save("/home/pi/plant+out/store.xlsx")
        print ("ho salvato store")




        
#************  S C R I P T   D A   P R O V A R E ***********************
scrivi48oreStore()



Grazie

Saluti :ciao:

LaPa
Eterno imbranato su Ubuntu Linux e .... in tantissime altre cose :D
Avatar utente
Lapa
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 362
Iscrizione: mercoledì 30 dicembre 2009, 17:01

Re: [Python] Sequenza di comandi che non funziona se inserito in script diversi

Messaggio da Lapa »

... e questo è il secondo Chunk


Chunk che non funziona

Codice: Seleziona tutto


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


import datetime
from datetime import datetime
import openpyxl
#import RPi.GPIO as GPIO
#GPIO.setwarnings(False)
import time
import sys
import gspread
#import oauth2client.client
#import json
import os
import ftplib

#*****************  D E F I N I Z I O N I   D E I   F O G L I   S T O R E  *****************     

wb=openpyxl.load_workbook('/home/pi/plant+out/store.xlsx')
ws=wb["Sheet1"]
ws1=wb["ultime48ore"]
ws2=wb["ultimaSettimana"]
ws3=wb["ultime2settimane"]
ws4=wb["ultimoMese"]
ws5=wb["datiGiornalieri"]

#*******  R I L I E V O   D E I   S E N S O R I   *********

#librerie per il sensore della luce
import smbus

from ctypes import c_short
from ctypes import c_byte
from ctypes import c_ubyte

from tsl2561 import TSL2561








#definizione di data e ora

now=datetime.now()
ora=now.strftime('%d/%m/%Y %H:%M:%S')

print (ora)

time.sleep(1)


#script per il sensore temperatura, umidità dell'aria (BME280)
DEVICE = 0x76 # Default device I2C address


bus = smbus.SMBus(1) # Rev 2 Pi, Pi 2 & Pi 3 uses bus 1
                     # Rev 1 Pi uses bus 0

def getShort(data, index):
  # return two bytes from data as a signed 16-bit value
    return c_short((data[index+1] << 8) + data[index]).value

def getUShort(data, index):
  # return two bytes from data as an unsigned 16-bit value
    return (data[index+1] << 8) + data[index]

def getChar(data,index):
  # return one byte from data as a signed char
    result = data[index]
    if result > 127:
        result -= 256
    return result

def getUChar(data,index):
  # return one byte from data as an unsigned char
    result =  data[index] & 0xFF
    return result

def readBME280ID(addr=DEVICE):
  # Chip ID Register Address
    REG_ID     = 0xD0
    (chip_id, chip_version) = bus.read_i2c_block_data(addr, REG_ID, 2)
    return (chip_id, chip_version)

def readBME280All(addr=DEVICE):
    # Register Addresses
    REG_DATA = 0xF7
    REG_CONTROL = 0xF4
    REG_CONFIG  = 0xF5

    REG_CONTROL_HUM = 0xF2
    REG_HUM_MSB = 0xFD
    REG_HUM_LSB = 0xFE

  # Oversample setting - page 27
    OVERSAMPLE_TEMP = 2
    OVERSAMPLE_PRES = 2
    MODE = 1

  # Oversample setting for humidity register - page 26
    OVERSAMPLE_HUM = 2
    bus.write_byte_data(addr, REG_CONTROL_HUM, OVERSAMPLE_HUM)

    control = OVERSAMPLE_TEMP<<5 | OVERSAMPLE_PRES<<2 | MODE
    bus.write_byte_data(addr, REG_CONTROL, control)

  # Read blocks of calibration data from EEPROM
  # See Page 22 data sheet
    cal1 = bus.read_i2c_block_data(addr, 0x88, 24)
    cal2 = bus.read_i2c_block_data(addr, 0xA1, 1)
    cal3 = bus.read_i2c_block_data(addr, 0xE1, 7)

  # Convert byte data to word values
    dig_T1 = getUShort(cal1, 0)
    dig_T2 = getShort(cal1, 2)
    dig_T3 = getShort(cal1, 4)

    dig_P1 = getUShort(cal1, 6)
    dig_P2 = getShort(cal1, 8)
    dig_P3 = getShort(cal1, 10)
    dig_P4 = getShort(cal1, 12)
    dig_P5 = getShort(cal1, 14)
    dig_P6 = getShort(cal1, 16)
    dig_P7 = getShort(cal1, 18)
    dig_P8 = getShort(cal1, 20)
    dig_P9 = getShort(cal1, 22)

    dig_H1 = getUChar(cal2, 0)
    dig_H2 = getShort(cal3, 0)
    dig_H3 = getUChar(cal3, 2)

    dig_H4 = getChar(cal3, 3)
    dig_H4 = (dig_H4 << 24) >> 20
    dig_H4 = dig_H4 | (getChar(cal3, 4) & 0x0F)

    dig_H5 = getChar(cal3, 5)
    dig_H5 = (dig_H5 << 24) >> 20
    dig_H5 = dig_H5 | (getUChar(cal3, 4) >> 4 & 0x0F)

    dig_H6 = getChar(cal3, 6)

  # Wait in ms (Datasheet Appendix B: Measurement time and current calculation)
    wait_time = 1.25 + (2.3 * OVERSAMPLE_TEMP) + ((2.3 * OVERSAMPLE_PRES) + 0.575) + ((2.3 * OVERSAMPLE_HUM)+0.575)
    time.sleep(wait_time/1000)  # Wait the required time  

  # Read temperature/pressure/humidity
    data = bus.read_i2c_block_data(addr, REG_DATA, 8)
    pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)
    temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4)
    hum_raw = (data[6] << 8) | data[7]

  #Refine temperature
    var1 = ((((temp_raw>>3)-(dig_T1<<1)))*(dig_T2)) >> 11
    var2 = (((((temp_raw>>4) - (dig_T1)) * ((temp_raw>>4) - (dig_T1))) >> 12) * (dig_T3)) >> 14
    t_fine = var1+var2
    temperature = float(((t_fine * 5) + 128) >> 8);

  # Refine pressure and adjust for temperature
    var1 = t_fine / 2.0 - 64000.0
    var2 = var1 * var1 * dig_P6 / 32768.0
    var2 = var2 + var1 * dig_P5 * 2.0
    var2 = var2 / 4.0 + dig_P4 * 65536.0
    var1 = (dig_P3 * var1 * var1 / 524288.0 + dig_P2 * var1) / 524288.0
    var1 = (1.0 + var1 / 32768.0) * dig_P1
    if var1 == 0:
        pressure=0
    else:
        pressure = 1048576.0 - pres_raw
        pressure = ((pressure - var2 / 4096.0) * 6250.0) / var1
        var1 = dig_P9 * pressure * pressure / 2147483648.0
        var2 = pressure * dig_P8 / 32768.0
        pressure = pressure + (var1 + var2 + dig_P7) / 16.0

  # Refine humidity
    humidity = t_fine - 76800.0
    humidity = (hum_raw - (dig_H4 * 64.0 + dig_H5 / 16384.0 * humidity)) * (dig_H2 / 65536.0 * (1.0 + dig_H6 / 67108864.0 * humidity * (1.0 + dig_H3 / 67108864.0 * humidity)))
    humidity = humidity * (1.0 - dig_H1 * humidity / 524288.0)
    if humidity > 100:
        humidity = 100
    elif humidity < 0:
        humidity = 0

    return temperature/100.0,pressure/100.0,humidity

def main():

    (chip_id, chip_version) = readBME280ID()
    print ("Chip ID     :", chip_id)
    print ("Version     :", chip_version)

    temperature,pressure,humidity = readBME280All()
    pressure=round(pressure,2)
    humidity=round(humidity,2)

    print ("Temperature : ", temperature, "C")
    print ("Pressure : ", pressure, "hPa")
    print ("Humidity : ", humidity, "%")

if __name__=="__main__":
    main()
temperature,pressure,humidity = readBME280All()
#print (temperature)

#chiamo la temperatura dell'aria taria
taria=temperature

print (taria)
time.sleep(1)


#chiamo l'umidità dell'aria RH
RH=round(humidity,2)


print (RH)

#segue adesso lo script per il sensore bagnatura e temperatore del suolo

import smbus2 as smbus


class Chirp:
	def __init__(self, bus=1, address=0x20):
		self.bus_num = bus
		self.bus = smbus.SMBus(bus)
		self.address = address
    
	def get_reg(self, reg):
		# read 2 bytes from register
		val = self.bus.read_word_data(self.address, reg)
		# return swapped bytes (they come in wrong order)
		return (val >> 8) + ((val & 0xFF) << 8)

	def reset(self):
		# To reset the sensor, write 6 to the device I2C address
		self.bus.write_byte(self.address, 6)

	def set_addr(self, new_addr):
		# To change the I2C address of the sensor, write a new address
		# (one byte [1..127]) to register 1; the new address will take effect after reset
		self.bus.write_byte_data(self.address, 1, new_addr)
		# second request is required since FW 0x26 to protect agains spurious address changes
		self.bus.write_byte_data(self.address, 1, new_addr)
		self.reset()
		self.address = new_addr

	def moist(self):
		# To read soil moisture, read 2 bytes from register 0
		return self.get_reg(0)

	def temp(self):
		# To read temperature, read 2 bytes from register 5
		return self.get_reg(5)

	def light(self):
		# To read light level, start measurement by writing 3 to the
		# device I2C address, wait for 3 seconds, read 2 bytes from register 4
		self.bus.write_byte(self.address, 3)
		time.sleep(1.5)
		return self.get_reg(4)

	def __repr__(self):
		return "<Chirp sensor on bus %d, addr %d>" % (self.bus_num, self.address)

if __name__ == "__main__":
	addr = 0x20
	if len(sys.argv) == 2:
		if sys.argv[1].startswith("0x"):
			addr = int(sys.argv[1], 16)
		else:
			addr = int(sys.argv[1])
	chirp = Chirp(1, addr)
	#print (chirp)
	#print ("Moisture\tTemperature\tBrightness")
	bs1=chirp.moist()
	
	ts1=chirp.temp()/10
	print ("La bagnatura del suolo a 10 Cm. di profondità è ",bs1)
	print ("La temperatura del suolo a 10 Cm. di profondità è ",ts1, " al momento ho applicato una correzione per allineare a BME280")
	bs1=chirp.moist()
	
	ts1=(chirp.temp()/10)-2.11 #al momento c'è uno scostamento rilievo temperaura con BME280 pertanto ho compensato con 2.11
	print ("La bagnatura del suolo a 10 Cm. di profondità è ",bs1)
	print ("La temperatura del suolo corretta a 10 Cm. di profondità è ",ts1)
	#while True:
	#print ("%d\t%d" % (chirp.moist(), chirp.temp()))#chirp.light()))
	#time.sleep(1)
	#chirp.moist()=bs1
	#tsuolo1=(chirp.temp()/10)-1.6#questo per allinearlo ai valori di BME280 fai ulteriori verifiche
	#print(bs1)
	#print(tsuolo1)

#aggiungo qui la parte del 2° sensore di bagnatura poi lo cambierò
#attualmente non ho capito come cambiare indirizzo I2C a 21 ma attendo risposta da Miceuz



class Chirp:
	def __init__(self, bus=1, address=0x20):
		self.bus_num = bus
		self.bus = smbus.SMBus(bus)
		self.address = address
    
	def get_reg(self, reg):
		# read 2 bytes from register
		val = self.bus.read_word_data(self.address, reg)
		# return swapped bytes (they come in wrong order)
		return (val >> 8) + ((val & 0xFF) << 8)

	def reset(self):
		# To reset the sensor, write 6 to the device I2C address
		self.bus.write_byte(self.address, 6)

	def set_addr(self, new_addr):
		# To change the I2C address of the sensor, write a new address
		# (one byte [1..127]) to register 1; the new address will take effect after reset
		self.bus.write_byte_data(self.address, 1, 0x21)
		# second request is required since FW 0x26 to protect agains spurious address changes
		self.bus.write_byte_data(self.address, 1, 0x21)
		self.reset()
		self.address = new_addr

	def moist(self):
		# To read soil moisture, read 2 bytes from register 0
		return self.get_reg(0)

	def temp(self):
		# To read temperature, read 2 bytes from register 5
		return self.get_reg(5)

	def light(self):
		# To read light level, start measurement by writing 3 to the
		# device I2C address, wait for 3 seconds, read 2 bytes from register 4
		self.bus.write_byte(self.address, 3)
		time.sleep(1.5)
		return self.get_reg(4)

	def __repr__(self):
		return "<Chirp sensor on bus %d, addr %d>" % (self.bus_num, self.address)

if __name__ == "__main__":
	addr = 0x20
	if len(sys.argv) == 2:
		if sys.argv[1].startswith("0x"):
			addr = int(sys.argv[1], 16)
		else:
			addr = int(sys.argv[1])
	chirp = Chirp(1, addr)

	#print (chirp)
	#print ("Moisture\tTemperature\tBrightness")
	print (chirp.moist())
	print (chirp.temp()/10, " al momento ho applicato una correzione per allineare a BME280")
	bs2=chirp.moist()
	
	ts2=(chirp.temp()/10)-2.11 #al momento c'è uno scostamento rilievo temperaura con BME280 pertanto ho compensato con 2.11
	print ("La bagnatura del suolo a 30 Cm. di profondità è ",bs2)
	print ("La temperatura del suolo corretta a 30 Cm. di profondità è ",ts2)


if __name__ == "__main__":
    tsl = TSL2561(debug=True)
    print(tsl.lux())
    lux=tsl.lux()
    print(lux)
#******* F I N E   D E L   R I L I E V O   D E I   S E N S O R I *********


    
#******* S C R I T T U R A     D E L    R I L I E V O   D E I   S E N S O R I  I N   W S   D I   S T O R E . X L S X *********


#conta il numero di righe già scritte
nr=ws.max_row
print ("la riga di scrittura di ws di store è ",nr)

wb=openpyxl.load_workbook('/home/pi/plant+out/store.xlsx')
ws=wb["Sheet1"]
#accoda la riga con i dati
ws.append([ora,taria,RH,lux,bs1,ts1,bs2,ts2])
#ws.append([ora,taria,RH,lux,l_amb])
wb.save('/home/pi/plant+out/store.xlsx')

print("ho scritto tutti i dati rilevati nel file store.xlsx")







#*****************  F U N Z I O N I  D A   P R O V A R E  *****************
def mediaDatiInRiga49DiUltime48Ore():
#se lo script viene lanciato allo scoccare dell'ora verranno fatte le medie del 4 valori
#partendo dal quintultimo e la media saranno i 4 volori rilevati nell'ora precedente.
    nc=9#indichiamo il numero di colonne per il quale deve essere ripetuta la media
    mediaValori=[]
    for s in range (2,nc):#s=il numero della colonna
        l=[]#creo una lista vuota
        n=(ws.max_row-3)
        print ("il numero della colonna dove sto facendo la media degli ultimi 4 valori rilevati è ", s)
        print (n, " è la riga dove iniziare la media dei valori")
        
    
        for d in range (4):#per 4 volte
            print("la riga di lettura attuale è ",n)
            v=ws.cell(row=n,column=s).value #estrae il valore della prima riga della colonna s e lo chiama v
            #v=cell.value
            if v!=None:
                v=float(v)#lo converto in numero altrimenti non fa i calcoli
            else:
                v=0
                #print("il valore della cella estratta alla riga ", n," è ", v)
            l[d:d]=[v] #dovrebbe inserirlo nell lista
            n=n+1
            d=d+1#sposta la posizione nella lista di 1
            
            
        print(l)
        a=sum(l)/len(l)#chiamo a la media dei valori nella lista
        a=round(a,2) #arrotondo la media a 2 cifre
        print("la media dei valori di ", ws.cell(row=1, column=s).value," degli ultimi 4 rilievi è ",a)
        print(s)
       
      
        #time.sleep(2)
        mediaValori.append(a)
       
    
    
    print("La media oraria dei valori rilevati è ",mediaValori)
    ultimaRigaSheet1=ws.max_row
    dataOra=ws.cell(row=(ultimaRigaSheet1-1),column=1).value
    #print (dataOra)
    #print("data è ",type(dataOra))
    dataOra=datetime.strptime(dataOra, "%d/%m/%Y %H:%M:%S")
    #print (dataOra)
    dataOra=dataOra.strftime('%d/%m/%Y %H')
    print ("data ora con strftime è ",dataOra)
    #print (type(dataOra))

    TAmb=mediaValori[0]
    UR=mediaValori[1]
    Luce=mediaValori[2]
    BS10=mediaValori[3]
    TS10=mediaValori[4]
    BS30=mediaValori[5]
    TS30=mediaValori[6]
    
    ws1['A49'] = dataOra
    ws1['B49'] = TAmb
    ws1['C49'] = UR
    ws1['D49'] = Luce
    ws1['E49'] = BS10
    ws1['F49'] = TS10
    ws1['G49'] = BS30
    ws1['H49'] = TS30
    print ("ho inserito tutti i dati orari al rigo 49 del foglio 48ore di store")
    wb.save("/home/pi/plant+out/store.xlsx")
    print("ho salvato store")
    
    
#***********************

def scrivi48oreStore():        
    ultimaRigaSheet1=ws.max_row
    print("l'ultima riga del foglio 1 di store e' ",ultimaRigaSheet1)

    ultima48ore=ws1.max_row
    print("l'ultima riga del foglio 48 ore e' ",ultima48ore)


    if ultimaRigaSheet1<5:
        print("ci sono meno di 4 dati scritti nel foglio1 di store non fare nessun calcolo, termina questa funzione e proseguo altre")
        print("non ho salvato store perchÉ non ho scritto niente di nuovo")
    elif ultimaRigaSheet1>=5 and ultima48ore<49:
        print("attiva la parte di script che fa la media oraria e aggiunge i dati della media oraria al foglio 48 ore")
        #se lo script viene lanciato allo scoccare dell'ora verranno fatte le medie del 4 valori
        #partendo dal quintultimo e la media saranno i 4 volori rilevati nell'ora precedente.
        ultimaRigaSheet1=ws.max_row
        print("l'ultima riga scritta nello sheet1 nel file store è ", ultimaRigaSheet1)
        nc=9#indichiamo il numero di colonne per il quale deve essere ripetuta la media
        mediaValori=[]
        for s in range (2,nc):#s=il numero della colonna
            l=[]#creo una lista vuota
            n=(ws.max_row-3)
            print ("il numero della colonna dove sto facendo la media degli ultimi 4 valori rilevati è ", s)
            print (n, " è la riga dove iniziare la media dei valori")          
            for d in range (4):#per 4 volte
                print("la riga di lettura attuale è ",n)
                v=ws.cell(row=n,column=s).value #estrae il valore della prima riga della colonna s e lo chiama v
                #v=cell.value
                if v!=None:
                    v=float(v)#lo converto in numero altrimenti non fa i calcoli
                else:
                    v=0
                    #print("il valore della cella estratta alla riga ", n," è ", v)
                l[d:d]=[v] #dovrebbe inserirlo nell lista
                n=n+1
                d=d+1#sposta la posizione nella lista di 1
        
        
            print(l)
            a=sum(l)/len(l)#chiamo a la media dei valori nella lista
            a=round(a,2) #arrotondo la media a 2 cifre
            print("la media dei valori di ", ws.cell(row=1, column=s).value," degli ultimi 4 rilievi è ",a)
            print(s)
   
  
            #time.sleep(2)
            mediaValori.append(a)
   


        print("La media oraria dei valori rilevati è ",mediaValori)
        dataOra=ws.cell(row=(ultimaRigaSheet1-1),column=1).value
        #print (dataOra)
        #print("data è ",type(dataOra))
        dataOra=datetime.strptime(dataOra, "%d/%m/%Y %H:%M:%S")
        #print (dataOra)
        dataOra=dataOra.strftime('%d/%m/%Y %H')
        print ("data ora con strftime è ",dataOra)
        #print (type(dataOra))

        TAmb=mediaValori[0]
        UR=mediaValori[1]
        Luce=mediaValori[2]
        BS10=mediaValori[3]
        TS10=mediaValori[4]
        BS30=mediaValori[5]
        TS30=mediaValori[6]
        print ("la media dei dati orari in ", dataOra, "è ", TAmb," ", UR," ", Luce," ", BS10," ", TS10," ", BS30," ", TS30)
        ws1.cell(row=ultima48ore+1, column=1).value = dataOra
        ws1.cell(row=ultima48ore+1, column=2).value = TAmb
        ws1.cell(row=ultima48ore+1, column=3).value = UR
        ws1.cell(row=ultima48ore+1, column=4).value = Luce
        ws1.cell(row=ultima48ore+1, column=5).value = BS10
        ws1.cell(row=ultima48ore+1, column=6).value = TS10
        ws1.cell(row=ultima48ore+1, column=7).value = BS30
        ws1.cell(row=ultima48ore+1, column=8).value = TS30
        print ("ho inserito tutti i dati orari al rigo ",ultima48ore+1,"del foglio ultime48ore di store")
        wb.save("/home/pi/plant+out/store.xlsx")
        print("ho salvato store")
        
    elif ultimaRigaSheet1>=5 and ultima48ore==49:
        print("attiva la parte di script che fa la media oraria e in 48ore sposta i dati un rigo più in alto ed inserisce la media appena fatta al rigo 49")
        ws1.move_range("A3:H49", rows=-1, cols=0)
        print("ho spostato i dati di una riga in alto in ultime48ore")
        mediaDatiInRiga49DiUltime48Ore()
        wb.save("/home/pi/plant+out/store.xlsx")
        print ("ho salvato store")




        
#************  S C R I P T   D A   P R O V A R E ***********************
scrivi48oreStore()


   
        
        



Grazie ancora

Salutoni :ciao: :ciao:
LaPa
Eterno imbranato su Ubuntu Linux e .... in tantissime altre cose :D
Avatar utente
nuzzopippo
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1532
Iscrizione: giovedì 12 ottobre 2006, 11:34

Re: [Python] Sequenza di comandi che non funziona se inserito in script diversi

Messaggio da nuzzopippo »

Lapa ha scritto:
mercoledì 30 novembre 2022, 21:37
... e questo è il secondo Chunk ...
Ho scaricato i due segmenti di codice postati, vedo che è una applicazione per la domotica che, purtroppo, non sono in grado di far girare, non disponendo tanto dei sensori interessati quanto della opportuna conoscenza delle librerie per farli "girare", posso intanto, fornire una risposta ad una indicazione presente in entrambi i codici:

Codice: Seleziona tutto

#attualmente non ho capito come cambiare indirizzo I2C a 21 ma attendo risposta da Miceuz
se guardi la definizione della istanza della classe "Chirp"

Codice: Seleziona tutto

class Chirp:
	def __init__(self, bus=1, address=0x20):
vedrai che le variabili posizionali "bus" ed "address" hano dei valori di default impostati ma tali valori di default intervengono solo in caso NON vengano definite in fase di istanza, puoi definirle, instanziando la classe, inserendo i voluti valori ordinatamente per posizione ovvero valorizzandone lo specifico parametro, giusto ad esempio questo codice giù

Codice: Seleziona tutto

class Prova:
    def __init__(self, bus=1, address=0x20):
        self.bus_num = bus
        self.address = address

    def __repr__(self):
        return '<Sensor on bus %d, addr %d>' % (self.bus_num, self.address)

if __name__ == '__main__':
    sens_0 = Prova()
    sens_1 = Prova(2, 0x20)
    sens_2 = Prova(address=0x21)
    print(sens_0)
    print(sens_1)
    print(sens_2)
produce quale risultato

Codice: Seleziona tutto

Python 3.10.6 (main, Nov  2 2022, 18:53:38) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license()" for more information.

============ RESTART: /home/nuzzopippo/src/posts/la_pa/mytest_02.py ============
<Sensor on bus 1, addr 32>
<Sensor on bus 2, addr 32>
<Sensor on bus 1, addr 33>
Per altro, guardando il codice vedo un susseguirsi di istruzioni "if __name__ == "__main__":" e dichiarazioni di variabili e classi ripetute, oltre che di import sparsi ... è un unico modulo o sono più moduli riassunti?

Qualora fosse un unico modulo suggerirei di evitare punti multipli con istruzioni "if __name__ == "__main__":", si può fare ma ciò incasina di molto la logica, così come la ingarbugliano le dichiarazioni multiple di variabili, tipo per il foglio elettronico (ce ne sono due) o definizione di classe (tipo le due di "Chirp") perché verranno usate dipendentemente dalla loro posizione nel codice ... penso che una attenta revisione sarebbe utile.

Per altro, vedo un "import gspread", che non viene utilizzano ... non è che il prodotto finale vada su google, vero?

Cosa Ti da di output il lancio dello script?
Fatti non foste a viver come bruti ...
Avatar utente
Lapa
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 362
Iscrizione: mercoledì 30 dicembre 2009, 17:01

Re: [Python] Sequenza di comandi che non funziona se inserito in script diversi

Messaggio da Lapa »

Grazie Nuzzopippo!!!


Sì è un'applicazione che gira su Raspberry Pi. E' un sistema di monitoraggio delle piante. ha diversi sensori che rilevano dati e anche una telecamera che fa foto e poi un time-lapse.
Io ho postato solo un pezzo, pertanto ci sono delle librerie che non siutilizzano nel chunk inviato.
Il pezzo che ho postato e che non funziona, fa sostanzialmente 3 cose:
1) rileva i dati ambientali
2) inserisce i dati rilevati in foglio elettronico
3) prende i dati dal foglio, fa le medie orarie e le inserisce in un altro foglio dove ci sono le medie orarie dei dati delle ultime 48 ore.

l'operazione 3 se la provo da sola funziona (scrive i dati nel foglio excell), se la
provo dopo 1 e 2 non funziona

Per l'operazione 1 si usano i driver dei sensori scritti in Python che forniscono le ditte produttrici dei sensori, io non li ho modificati, ho solo individuato nello script dove era l'output per rinominarlo e utilizzarlo successivamente.


Sono questi driver problematici?

Posso provare a inserire dei dati inventati e fare la 2 e la 3
in sequenza.


In effetti quello dell'indirizzo I2C è un altro problema del mio listato. Che ho tentato di risolvere e poi ho accantonato ma accetto ben volentieri i tuoi suggerimenti. Magari in un post ad hoc.
Eterno imbranato su Ubuntu Linux e .... in tantissime altre cose :D
Avatar utente
Lapa
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 362
Iscrizione: mercoledì 30 dicembre 2009, 17:01

Re: [Python] Sequenza di comandi che non funziona se inserito in script diversi

Messaggio da Lapa »

Ok ho semplificato ho eliminato tutti driver dei sensori, e ho inserito dei dati numerici alle variabili al posto dei rilievi dei dati. Non funziona ugualmente: sembrerebbe che l'operazione 2 (#******* S C R I T T U R A D E L R I L I E V O D E I S E N S O R I I N W S D I S T O R E . X L S X *********) impedisca di fare funzionare bene l'operazione 3.
Posto qui il chunk che non funziona senza i diver dei sensori (ora è molto semplificato).

Codice: Seleziona tutto


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


import datetime
from datetime import datetime
import openpyxl
#import RPi.GPIO as GPIO
#GPIO.setwarnings(False)
import time
import sys
import gspread
#import oauth2client.client
#import json
import os
import ftplib

#*****************  D E F I N I Z I O N I   D E I   F O G L I   S T O R E  *****************     

wb=openpyxl.load_workbook('/home/pi/plant+out/store.xlsx')
ws=wb["Sheet1"]
ws1=wb["ultime48ore"]
ws2=wb["ultimaSettimana"]
ws3=wb["ultime2settimane"]
ws4=wb["ultimoMese"]
ws5=wb["datiGiornalieri"]

#*******  R I L I E V O   D E I   S E N S O R I   *********

#librerie per il sensore della luce
import smbus

from ctypes import c_short
from ctypes import c_byte
from ctypes import c_ubyte

from tsl2561 import TSL2561








#definizione di data e ora

now=datetime.now()
ora=now.strftime('%d/%m/%Y %H:%M:%S')

print (ora)

time.sleep(1)
taria=19

print (taria)
time.sleep(1)


#chiamo l'umidità dell'aria RH
RH=56


print (RH)


bs1=225

ts1=21
print ("La bagnatura del suolo a 10 Cm. di profondità è ",bs1)
print ("La temperatura del suolo a 10 Cm. di profondità è ",ts1, " al momento ho applicato una correzione per allineare a BME280")

print ("La bagnatura del suolo a 10 Cm. di profondità è ",bs1)
print ("La temperatura del suolo corretta a 10 Cm. di profondità è ",ts1)



bs2=305

ts2=22
print ("La bagnatura del suolo a 30 Cm. di profondità è ",bs2)
print ("La temperatura del suolo corretta a 30 Cm. di profondità è ",ts2)




lux=15
print(lux)
#******* F I N E   D E L   R I L I E V O   D E I   S E N S O R I *********


    
#******* S C R I T T U R A     D E L    R I L I E V O   D E I   S E N S O R I  I N   W S   D I   S T O R E . X L S X *********


#conta il numero di righe già scritte
nr=ws.max_row
print ("la riga di scrittura di ws di store è ",nr)

wb=openpyxl.load_workbook('/home/pi/plant+out/store.xlsx')
ws=wb["Sheet1"]
#accoda la riga con i dati
ws.append([ora,taria,RH,lux,bs1,ts1,bs2,ts2])
#ws.append([ora,taria,RH,lux,l_amb])
wb.save('/home/pi/plant+out/store.xlsx')

print("ho scritto tutti i dati rilevati nel file store.xlsx")







#*****************  F U N Z I O N I  D A   P R O V A R E  *****************
def mediaDatiInRiga49DiUltime48Ore():
#se lo script viene lanciato allo scoccare dell'ora verranno fatte le medie del 4 valori
#partendo dal quintultimo e la media saranno i 4 volori rilevati nell'ora precedente.
    nc=9#indichiamo il numero di colonne per il quale deve essere ripetuta la media
    mediaValori=[]
    for s in range (2,nc):#s=il numero della colonna
        l=[]#creo una lista vuota
        n=(ws.max_row-3)
        print ("il numero della colonna dove sto facendo la media degli ultimi 4 valori rilevati è ", s)
        print (n, " è la riga dove iniziare la media dei valori")
        
    
        for d in range (4):#per 4 volte
            print("la riga di lettura attuale è ",n)
            v=ws.cell(row=n,column=s).value #estrae il valore della prima riga della colonna s e lo chiama v
            #v=cell.value
            if v!=None:
                v=float(v)#lo converto in numero altrimenti non fa i calcoli
            else:
                v=0
                #print("il valore della cella estratta alla riga ", n," è ", v)
            l[d:d]=[v] #dovrebbe inserirlo nell lista
            n=n+1
            d=d+1#sposta la posizione nella lista di 1
            
            
        print(l)
        a=sum(l)/len(l)#chiamo a la media dei valori nella lista
        a=round(a,2) #arrotondo la media a 2 cifre
        print("la media dei valori di ", ws.cell(row=1, column=s).value," degli ultimi 4 rilievi è ",a)
        print(s)
       
      
        #time.sleep(2)
        mediaValori.append(a)
       
    
    
    print("La media oraria dei valori rilevati è ",mediaValori)
    ultimaRigaSheet1=ws.max_row
    dataOra=ws.cell(row=(ultimaRigaSheet1-1),column=1).value
    #print (dataOra)
    #print("data è ",type(dataOra))
    dataOra=datetime.strptime(dataOra, "%d/%m/%Y %H:%M:%S")
    #print (dataOra)
    dataOra=dataOra.strftime('%d/%m/%Y %H')
    print ("data ora con strftime è ",dataOra)
    #print (type(dataOra))

    TAmb=mediaValori[0]
    UR=mediaValori[1]
    Luce=mediaValori[2]
    BS10=mediaValori[3]
    TS10=mediaValori[4]
    BS30=mediaValori[5]
    TS30=mediaValori[6]
    
    ws1['A49'] = dataOra
    ws1['B49'] = TAmb
    ws1['C49'] = UR
    ws1['D49'] = Luce
    ws1['E49'] = BS10
    ws1['F49'] = TS10
    ws1['G49'] = BS30
    ws1['H49'] = TS30
    print ("ho inserito tutti i dati orari al rigo 49 del foglio 48ore di store")
    wb.save("/home/pi/plant+out/store.xlsx")
    print("ho salvato store")
    
    
#***********************

def scrivi48oreStore():        
    ultimaRigaSheet1=ws.max_row
    print("l'ultima riga del foglio 1 di store e' ",ultimaRigaSheet1)

    ultima48ore=ws1.max_row
    print("l'ultima riga del foglio 48 ore e' ",ultima48ore)


    if ultimaRigaSheet1<5:
        print("ci sono meno di 4 dati scritti nel foglio1 di store non fare nessun calcolo, termina questa funzione e proseguo altre")
        print("non ho salvato store perchÉ non ho scritto niente di nuovo")
    elif ultimaRigaSheet1>=5 and ultima48ore<49:
        print("attiva la parte di script che fa la media oraria e aggiunge i dati della media oraria al foglio 48 ore")
        #se lo script viene lanciato allo scoccare dell'ora verranno fatte le medie del 4 valori
        #partendo dal quintultimo e la media saranno i 4 volori rilevati nell'ora precedente.
        ultimaRigaSheet1=ws.max_row
        print("l'ultima riga scritta nello sheet1 nel file store è ", ultimaRigaSheet1)
        nc=9#indichiamo il numero di colonne per il quale deve essere ripetuta la media
        mediaValori=[]
        for s in range (2,nc):#s=il numero della colonna
            l=[]#creo una lista vuota
            n=(ws.max_row-3)
            print ("il numero della colonna dove sto facendo la media degli ultimi 4 valori rilevati è ", s)
            print (n, " è la riga dove iniziare la media dei valori")          
            for d in range (4):#per 4 volte
                print("la riga di lettura attuale è ",n)
                v=ws.cell(row=n,column=s).value #estrae il valore della prima riga della colonna s e lo chiama v
                #v=cell.value
                if v!=None:
                    v=float(v)#lo converto in numero altrimenti non fa i calcoli
                else:
                    v=0
                    #print("il valore della cella estratta alla riga ", n," è ", v)
                l[d:d]=[v] #dovrebbe inserirlo nell lista
                n=n+1
                d=d+1#sposta la posizione nella lista di 1
        
        
            print(l)
            a=sum(l)/len(l)#chiamo a la media dei valori nella lista
            a=round(a,2) #arrotondo la media a 2 cifre
            print("la media dei valori di ", ws.cell(row=1, column=s).value," degli ultimi 4 rilievi è ",a)
            print(s)
   
  
            #time.sleep(2)
            mediaValori.append(a)
   


        print("La media oraria dei valori rilevati è ",mediaValori)
        dataOra=ws.cell(row=(ultimaRigaSheet1-1),column=1).value
        #print (dataOra)
        #print("data è ",type(dataOra))
        dataOra=datetime.strptime(dataOra, "%d/%m/%Y %H:%M:%S")
        #print (dataOra)
        dataOra=dataOra.strftime('%d/%m/%Y %H')
        print ("data ora con strftime è ",dataOra)
        #print (type(dataOra))

        TAmb=mediaValori[0]
        UR=mediaValori[1]
        Luce=mediaValori[2]
        BS10=mediaValori[3]
        TS10=mediaValori[4]
        BS30=mediaValori[5]
        TS30=mediaValori[6]
        print ("la media dei dati orari in ", dataOra, "è ", TAmb," ", UR," ", Luce," ", BS10," ", TS10," ", BS30," ", TS30)
        ws1.cell(row=ultima48ore+1, column=1).value = dataOra
        ws1.cell(row=ultima48ore+1, column=2).value = TAmb
        ws1.cell(row=ultima48ore+1, column=3).value = UR
        ws1.cell(row=ultima48ore+1, column=4).value = Luce
        ws1.cell(row=ultima48ore+1, column=5).value = BS10
        ws1.cell(row=ultima48ore+1, column=6).value = TS10
        ws1.cell(row=ultima48ore+1, column=7).value = BS30
        ws1.cell(row=ultima48ore+1, column=8).value = TS30
        print ("ho inserito tutti i dati orari al rigo ",ultima48ore+1,"del foglio ultime48ore di store")
        wb.save("/home/pi/plant+out/store.xlsx")
        print("ho salvato store")
        
    elif ultimaRigaSheet1>=5 and ultima48ore==49:
        print("attiva la parte di script che fa la media oraria e in 48ore sposta i dati un rigo più in alto ed inserisce la media appena fatta al rigo 49")
        ws1.move_range("A3:H49", rows=-1, cols=0)
        print("ho spostato i dati di una riga in alto in ultime48ore")
        mediaDatiInRiga49DiUltime48Ore()
        wb.save("/home/pi/plant+out/store.xlsx")
        print ("ho salvato store")




        
#************  S C R I P T   D A   P R O V A R E ***********************
scrivi48oreStore()


Qui inserisco l'output sempre del chunk che non funziona semplificato.

Codice: Seleziona tutto

>>> %Run ChunkCheNonFunziona1.py
01/12/2022 22:31:47
19
56
La bagnatura del suolo a 10 Cm. di profondità è 225
La temperatura del suolo a 10 Cm. di profondità è 21 al momento ho applicato una correzione per allineare a BME280
La bagnatura del suolo a 10 Cm. di profondità è 225
La temperatura del suolo corretta a 10 Cm. di profondità è 21
La bagnatura del suolo a 30 Cm. di profondità è 305
La temperatura del suolo corretta a 30 Cm. di profondità è 22
15
la riga di scrittura di ws di store è 58
ho scritto tutti i dati rilevati nel file store.xlsx
l'ultima riga del foglio 1 di store e' 59
l'ultima riga del foglio 48 ore e' 47
attiva la parte di script che fa la media oraria e aggiunge i dati della media oraria al foglio 48 ore
l'ultima riga scritta nello sheet1 nel file store è 59
il numero della colonna dove sto facendo la media degli ultimi 4 valori rilevati è 2
56 è la riga dove iniziare la media dei valori
la riga di lettura attuale è 56
la riga di lettura attuale è 57
la riga di lettura attuale è 58
la riga di lettura attuale è 59
[17.96, 19.0, 19.0, 19.0]
la media dei valori di Temperatura dell'aria degli ultimi 4 rilievi è 18.74
2
il numero della colonna dove sto facendo la media degli ultimi 4 valori rilevati è 3
56 è la riga dove iniziare la media dei valori
la riga di lettura attuale è 56
la riga di lettura attuale è 57
la riga di lettura attuale è 58
la riga di lettura attuale è 59
[52.31, 56.0, 56.0, 56.0]
la media dei valori di Umidità Relativa degli ultimi 4 rilievi è 55.08
3
il numero della colonna dove sto facendo la media degli ultimi 4 valori rilevati è 4
56 è la riga dove iniziare la media dei valori
la riga di lettura attuale è 56
la riga di lettura attuale è 57
la riga di lettura attuale è 58
la riga di lettura attuale è 59
[3.0, 15.0, 15.0, 15.0]
la media dei valori di Luce alla pianta degli ultimi 4 rilievi è 12.0
4
il numero della colonna dove sto facendo la media degli ultimi 4 valori rilevati è 5
56 è la riga dove iniziare la media dei valori
la riga di lettura attuale è 56
la riga di lettura attuale è 57
la riga di lettura attuale è 58
la riga di lettura attuale è 59
[228.0, 225.0, 225.0, 225.0]
la media dei valori di Bagnatura del suolo a -10 Cm. degli ultimi 4 rilievi è 225.75
5
il numero della colonna dove sto facendo la media degli ultimi 4 valori rilevati è 6
56 è la riga dove iniziare la media dei valori
la riga di lettura attuale è 56
la riga di lettura attuale è 57
la riga di lettura attuale è 58
la riga di lettura attuale è 59
[17.49, 21.0, 21.0, 21.0]
la media dei valori di Temperatura del suolo a -10 cm degli ultimi 4 rilievi è 20.12
6
il numero della colonna dove sto facendo la media degli ultimi 4 valori rilevati è 7
56 è la riga dove iniziare la media dei valori
la riga di lettura attuale è 56
la riga di lettura attuale è 57
la riga di lettura attuale è 58
la riga di lettura attuale è 59
[228.0, 305.0, 305.0, 305.0]
la media dei valori di Bagnatura del suolo a -30 Cm. degli ultimi 4 rilievi è 285.75
7
il numero della colonna dove sto facendo la media degli ultimi 4 valori rilevati è 8
56 è la riga dove iniziare la media dei valori
la riga di lettura attuale è 56
la riga di lettura attuale è 57
la riga di lettura attuale è 58
la riga di lettura attuale è 59
[17.49, 22.0, 22.0, 22.0]
la media dei valori di Temperatura del suolo a -30 cm degli ultimi 4 rilievi è 20.87
8
La media oraria dei valori rilevati è [18.74, 55.08, 12.0, 225.75, 20.12, 285.75, 20.87]
data ora con strftime è 01/12/2022 22
la media dei dati orari in 01/12/2022 22 è 18.74 55.08 12.0 225.75 20.12 285.75 20.87
ho inserito tutti i dati orari al rigo 48 del foglio ultime48ore di store
ho salvato store

invece non ha scritto proprio niente al rigo 48 del foglio ultime48ore :( :muro:

Grazie di tutto

buona serata

:ciao: LaPa
Eterno imbranato su Ubuntu Linux e .... in tantissime altre cose :D
Avatar utente
nuzzopippo
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1532
Iscrizione: giovedì 12 ottobre 2006, 11:34

Re: [Python] Sequenza di comandi che non funziona se inserito in script diversi

Messaggio da nuzzopippo »

Lapa ha scritto:
giovedì 1 dicembre 2022, 22:43
,,,buona serata
beh @Lapa, per i vecchietti come me le 23:34 sono notte fonda ;)

Spirito a parte, ho scaricato il Tuo ultimo script, creato un venv per openpyxl, creato (con libreoffice) un documento xlsx con i fogli riportati nel tuo codice e provato lo script, adattando ovviamente il path-name del documento : neanche a me scriveva niente nel foglio "ultime48ore", mentre venivano scritti i dati nella prima operazione sul foglio "Sheet1".

Ho voluto, pur essendo la situazione abbastanza ovvia, controllare con la documentazione di openpyxl le varie operazioni eseguite nel Tuo script, sono tutte nei limiti di conformità dovuti.

Mia opinione è che il problema nasca proprio dalla strutturazione del Tuo script, ove esegui in rapida successione ben tre diverse operazioni di apertura/scrittura dati/chiusura del documento ... penso proprio che il documento non sia disponibile per tali operazioni dopo l'avvio della prima scrittura, per questione dei tempi necessari credo che le altre due vadano perse.

Potresti provare a porre dei tempi di attesa dopo ogni fase di salvataggio, ma reputo tale procedimento un pessimo modo di procedere.

Secondo me dovresti sforzarti di codificare in modo un po' più astratto, utilizzando un unico punto di apertura/chiusura del documento e definendo funzioni parametrizzate per le varie necessità.
Con tale pensiero ho cercato di farti un piccolo esempio cercando di mantenere il più possibile i Tuoi nomi-variabile e forma, cosa non facile perché cambia proprio il pattern di scrittura del codice (da imperativo quale è il Tuo a funzionale), provalo su una copia del Tuo foglio, vedrai che questo ci scrive in "ultime48ore":

Codice: Seleziona tutto

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

import datetime
from datetime import datetime
import openpyxl
import time
import os

def prepare_data():
    now = datetime.now()
    ora = now.strftime('%d/%m/%Y %H:%M:%S')
    taria = 19
    RH = 56
    bs1 = 225
    ts1 = 21
    bs2 = 305
    ts2 = 22
    lux = 15
    return ora, taria, RH, bs1, ts1, bs2, ts2, lux

def media_dati(ws):
    nc = 9
    mediavalori = []
    for s in range(2, nc):
        l = []
        n = ws.max_row - 3
        for d in range(4):
            v = ws.cell(row=n+d, column=s).value
            v = float(v) if v else 0.0
            l.append(v)
        a = round(sum(l)/len(l), 2)
        print('Media righe %d-%d colonna %d = %.2f' %
              (n, n+d, s, a))
        mediavalori.append(a)
    print('Media oraria valori :', mediavalori)
    ultimaRigaSheet1=ws.max_row
    dataOra = ws.cell(row=ultimaRigaSheet1-1, column=1).value
    dataOra=datetime.strptime(dataOra, "%d/%m/%Y %H:%M:%S")
    dataOra=dataOra.strftime('%d/%m/%Y %H')
    return [dataOra] + mediavalori

def scrivi48oreStore(ws, ws1):
    ultimaRigaSheet1=ws.max_row
    ultima48ore=ws1.max_row
    if ultimaRigaSheet1 < 5:
        print('Meno di 4 dati, esco')
        return
    elif ultimaRigaSheet1>=5 and ultima48ore<49:
        riga = ultima48ore + 1
    elif ultimaRigaSheet1>=5 and ultima48ore<49:
        ws1.move_range("A3:H49", rows=-1, cols=0)
        riga = 49
    dataOra, TAmb, UR, Luce, BS10, TS10, BS30, TS30 = media_dati(ws)
    ws1.cell(row=riga, column=1).value = dataOra
    ws1.cell(row=riga, column=2).value = TAmb
    ws1.cell(row=riga, column=3).value = UR
    ws1.cell(row=riga, column=4).value = Luce
    ws1.cell(row=riga, column=5).value = BS10
    ws1.cell(row=riga, column=6).value = TS10
    ws1.cell(row=riga, column=7).value = BS30
    ws1.cell(row=riga, column=8).value = TS30
    

if __name__ == '__main__':
    wb=openpyxl.load_workbook('/home/nuzzopippo/src/posts/la_pa/store.xlsx')
    ws=wb["Sheet1"]
    ws1=wb["ultime48ore"]
    data = prepare_data()
    ws.append(data)
    scrivi48oreStore(ws, ws1)
    wb.save('/home/nuzzopippo/src/posts/la_pa/store.xlsx')
    print('Operazioni completate.')
Potrai osservare una diversa "razionalizione" nel codice, dove in "scrivi48oreStore" mi limito a decidere su quale riga del foglio scrivere le medie e non invocare una funzione spcifica per scrivere sulla riga "49", quella funzione per la riga 49 la ho trasformata in una funzione per il calcolo e restituzione dei dati di media.

Spero Ti sia utile. :ciao:
Fatti non foste a viver come bruti ...
Avatar utente
Lapa
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 362
Iscrizione: mercoledì 30 dicembre 2009, 17:01

Re: [Python] Sequenza di comandi che non funziona se inserito in script diversi

Messaggio da Lapa »

Buonasera a tutti,
un grosso ringraziamento a Nuzzopippo per il tempo che ha dedicato a questo post e per i preziosi suggerimenti!

nuzzopippo ha scritto:
venerdì 2 dicembre 2022, 11:11
beh @Lapa, per i vecchietti come me le 23:34 sono notte fonda ;)
Tranquillo, siamo tra vecchietti ;)

nuzzopippo ha scritto:
venerdì 2 dicembre 2022, 11:11
Mia opinione è che il problema nasca proprio dalla strutturazione del Tuo script, ove esegui in rapida successione ben tre diverse operazioni di apertura/scrittura dati/chiusura del documento ... penso proprio che il documento non sia disponibile per tali operazioni dopo l'avvio della prima scrittura, per questione dei tempi necessari credo che le altre due vadano perse.
Ma lo sai che ci avevo pensato anche io e ho provato anche a inserire qualche sleep ma nella funzione scrivi48oreStore() tra scrittura dati e salvataggio. Probabilmente invece li dovrei inserire prima di aprire il foglio.

nuzzopippo ha scritto:
venerdì 2 dicembre 2022, 11:11
Potresti provare a porre dei tempi di attesa dopo ogni fase di salvataggio, ma reputo tale procedimento un pessimo modo di procedere.
Non ho capito perché è un pessimo modo però ho fiducia in quel che dici.
nuzzopippo ha scritto:
venerdì 2 dicembre 2022, 11:11
Secondo me dovresti sforzarti di codificare in modo un po' più astratto, utilizzando un unico punto di apertura/chiusura del documento e definendo funzioni parametrizzate per le varie necessità.
Con tale pensiero ho cercato di farti un piccolo esempio cercando di mantenere il più possibile i Tuoi nomi-variabile e forma, cosa non facile perché cambia proprio il pattern di scrittura del codice (da imperativo quale è il Tuo a funzionale), provalo su una copia del Tuo foglio, vedrai che questo ci scrive in "ultime48ore":
Spero di non uscire fuori tema e che non riceva un richiamo ma mi sembra necessario raccontare un po' di storia.
Non sono un programmatore come si evince dal mio codice e dalle mie difficoltà, mi diletto e diverto un po' per hobby. Ho imparato i rudimenti di Python per fare un'attrezzatura di monitoraggio delle piante che ho sommariamente descritto nei post precedenti. Sfrutto i ritagli di tempo, veramente pochi e piccoli, che mi lascia il lavoro ed il resto per dedicarmici. Pertanto non ho una scadenza. Ho già una volta terminato l'oggetto in fase di test provato a casa. Ora sto facendo un prototipo con elettronica stabile, il codice lo sto rifacendo tutto daccapo per migliorare la funzionalità e per applicare le cose nuove che ho imparato nel frattempo. Ho intenzione di provare la strumentazione in una serra di una azienda agricola. Non ambisco a fare un oggetto che viene poi commercializzato (c'è già troppa roba simile). Alla fine mi piacerebbe condividere tutto in qualche posto tipo https://www.instructables.com/ o simili. Comunque questo è un pretesto per imparare a programmare un po' meglio in Python, per tenermi in esercizio in genere sul problem solving che quello è sempre utile per tutto e perché mi fa piacere :).
Al di là di come risolverò lo specifico problema che ho posto.
Non penso di poter utilizzare il tuo codice perché non posso usare nelle operazioni 2 e 3 un unico punto di apertura e chiusura file in quanto queste operazioni a volte vengono eseguite insieme altre no.
Comunque ben vengano i tuoi suggerimenti, sono un grande stimolo per me per fare un passettino avanti, stamperò il tuo codice, annoterò quello che ho capito di ogni riga. Alla fine forse riuscirò anche a capire cosa vuoi dire con
nuzzopippo ha scritto:
venerdì 2 dicembre 2022, 11:11
Secondo me dovresti sforzarti di codificare in modo un po' più astratto, utilizzando un unico punto di apertura/chiusura del documento e definendo funzioni parametrizzate per le varie necessità.
Ho provato a mettere dei time.sleep(5) in vari punti, ma "il pessimo modo " di procedere come volevasi dimostrare non ha dato risultati.

Nel frattempo ho trovato un modo, probabilmente altretttanto pessimo visto che nemmeno io ne ho capito bene le ragioni, per fare funzionare il pezzo che non funzionava: ho specificato all'interno delle funzioni il foglio su cui queste devono agire.
Pensavo che fosse sufficiente farlo all'esterno della funzione. Insomma non ho capito bene. Se c'avete qualche idea ...

Chunk che non funzionava e ora sì

Codice: Seleziona tutto


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


import datetime
from datetime import datetime
import openpyxl
#import RPi.GPIO as GPIO
#GPIO.setwarnings(False)
import time
import sys
import gspread
#import oauth2client.client
#import json
import os
import ftplib

#*****************  D E F I N I Z I O N I   D E I   F O G L I   S T O R E  *****************     

wb=openpyxl.load_workbook('/home/pi/plant+out/store.xlsx')
ws=wb["Sheet1"]
ws1=wb["ultime48ore"]
ws2=wb["ultimaSettimana"]
ws3=wb["ultime2settimane"]
ws4=wb["ultimoMese"]
ws5=wb["datiGiornalieri"]

#*******  R I L I E V O   D E I   S E N S O R I   *********

#librerie per il sensore della luce
import smbus

from ctypes import c_short
from ctypes import c_byte
from ctypes import c_ubyte

from tsl2561 import TSL2561








#definizione di data e ora

now=datetime.now()
ora=now.strftime('%d/%m/%Y %H:%M:%S')

print (ora)

time.sleep(1)
taria=19

print ("la temperatura dell'aria è ",taria)
time.sleep(1)


#chiamo l'umidità dell'aria RH
RH=56


print ("l'umidità relativa è ",RH)


bs1=225

ts1=21
print ("La bagnatura del suolo a 10 Cm. di profondità è ",bs1)
print ("La temperatura del suolo a 10 Cm. di profondità è ",ts1, " al momento ho applicato una correzione per allineare a BME280")

print ("La bagnatura del suolo a 10 Cm. di profondità è ",bs1)
print ("La temperatura del suolo corretta a 10 Cm. di profondità è ",ts1)



bs2=305

ts2=22
print ("La bagnatura del suolo a 30 Cm. di profondità è ",bs2)
print ("La temperatura del suolo corretta a 30 Cm. di profondità è ",ts2)




lux=15
print("la luce alla pianta è ",lux)
#******* F I N E   D E L   R I L I E V O   D E I   S E N S O R I *********


    
#******* S C R I T T U R A     D E L    R I L I E V O   D E I   S E N S O R I  I N   W S   D I   S T O R E . X L S X *********


#conta il numero di righe già scritte
nr=ws.max_row
print ("la riga di scrittura di ws di store è ",nr)

wb=openpyxl.load_workbook('/home/pi/plant+out/store.xlsx')
ws=wb["Sheet1"]
#accoda la riga con i dati
ws.append([ora,taria,RH,lux,bs1,ts1,bs2,ts2])
#time.sleep(5)#ws.append([ora,taria,RH,lux,l_amb])
wb.save('/home/pi/plant+out/store.xlsx')
#time.sleep(5)
print("ho scritto tutti i dati rilevati nel file store.xlsx")

#time.sleep(5)





#*****************  F U N Z I O N I  D A   P R O V A R E  *****************
def mediaDatiInRiga49DiUltime48Ore():
#se lo script viene lanciato allo scoccare dell'ora verranno fatte le medie del 4 valori
#partendo dal quintultimo e la media saranno i 4 volori rilevati nell'ora precedente.
    time.sleep(5)
    #wb=openpyxl.load_workbook('/home/pi/plant+out/store.xlsx')
    #ws=wb["Sheet1"]
    ws1=wb["ultime48ore"]
    #ws2=wb["ultimaSettimana"]
    #ws3=wb["ultime2settimane"]
    #ws4=wb["ultimoMese"]
    #ws5=wb["datiGiornalieri"]
    nc=9#indichiamo il numero di colonne per il quale deve essere ripetuta la media
    mediaValori=[]
    for s in range (2,nc):#s=il numero della colonna
        l=[]#creo una lista vuota
        n=(ws.max_row-3)
        print ("il numero della colonna dove sto facendo la media degli ultimi 4 valori rilevati è ", s)
        print (n, " è la riga dove iniziare la media dei valori")
        
    
        for d in range (4):#per 4 volte
            print("la riga di lettura attuale è ",n)
            v=ws.cell(row=n,column=s).value #estrae il valore della prima riga della colonna s e lo chiama v
            #v=cell.value
            if v!=None:
                v=float(v)#lo converto in numero altrimenti non fa i calcoli
            else:
                v=0
                #print("il valore della cella estratta alla riga ", n," è ", v)
            l[d:d]=[v] #dovrebbe inserirlo nell lista
            n=n+1
            d=d+1#sposta la posizione nella lista di 1
            
            
        print(l)
        a=sum(l)/len(l)#chiamo a la media dei valori nella lista
        a=round(a,2) #arrotondo la media a 2 cifre
        print("la media dei valori di ", ws.cell(row=1, column=s).value," degli ultimi 4 rilievi è ",a)
        print(s)
       
      
        #time.sleep(2)
        mediaValori.append(a)
       
    
    
    print("La media oraria dei valori rilevati è ",mediaValori)
    ultimaRigaSheet1=ws.max_row
    dataOra=ws.cell(row=(ultimaRigaSheet1-1),column=1).value
    #print (dataOra)
    #print("data è ",type(dataOra))
    dataOra=datetime.strptime(dataOra, "%d/%m/%Y %H:%M:%S")
    #print (dataOra)
    dataOra=dataOra.strftime('%d/%m/%Y %H')
    print ("data ora con strftime è ",dataOra)
    #print (type(dataOra))

    TAmb=mediaValori[0]
    UR=mediaValori[1]
    Luce=mediaValori[2]
    BS10=mediaValori[3]
    TS10=mediaValori[4]
    BS30=mediaValori[5]
    TS30=mediaValori[6]
    
    ws1['A49'] = dataOra
    ws1['B49'] = TAmb
    ws1['C49'] = UR
    ws1['D49'] = Luce
    ws1['E49'] = BS10
    ws1['F49'] = TS10
    ws1['G49'] = BS30
    ws1['H49'] = TS30
    #time.sleep(10)
    print ("ho inserito tutti i dati orari al rigo 49 del foglio 48ore di store")
    wb.save("/home/pi/plant+out/store.xlsx")
    print("ho salvato store")
    #time.sleep(5)
    
    
#***********************

def scrivi48oreStore():
    #wb=openpyxl.load_workbook('/home/pi/plant+out/store.xlsx')
    #ws=wb["Sheet1"]
    ws1=wb["ultime48ore"]
    #ws2=wb["ultimaSettimana"]
    #ws3=wb["ultime2settimane"]
    #ws4=wb["ultimoMese"]
    #ws5=wb["datiGiornalieri"]
    ultimaRigaSheet1=ws.max_row
    print("l'ultima riga del foglio 1 di store e' ",ultimaRigaSheet1)

    ultima48ore=ws1.max_row
    print("l'ultima riga del foglio 48 ore e' ",ultima48ore)


    if ultimaRigaSheet1<5:
        print("ci sono meno di 4 dati scritti nel foglio1 di store non fare nessun calcolo, termina questa funzione e proseguo altre")
        print("non ho salvato store perchÉ non ho scritto niente di nuovo")
    elif ultimaRigaSheet1>=5 and ultima48ore<49:
        print("attiva la parte di script che fa la media oraria e aggiunge i dati della media oraria al foglio 48 ore")
        #se lo script viene lanciato allo scoccare dell'ora verranno fatte le medie del 4 valori
        #partendo dal quintultimo e la media saranno i 4 volori rilevati nell'ora precedente.
        ultimaRigaSheet1=ws.max_row
        print("l'ultima riga scritta nello sheet1 nel file store è ", ultimaRigaSheet1)
        nc=9#indichiamo il numero di colonne per il quale deve essere ripetuta la media
        mediaValori=[]
        for s in range (2,nc):#s=il numero della colonna
            l=[]#creo una lista vuota
            n=(ws.max_row-3)
            print ("il numero della colonna dove sto facendo la media degli ultimi 4 valori rilevati è ", s)
            print (n, " è la riga dove iniziare la media dei valori")          
            for d in range (4):#per 4 volte
                print("la riga di lettura attuale è ",n)
                v=ws.cell(row=n,column=s).value #estrae il valore della prima riga della colonna s e lo chiama v
                #v=cell.value
                if v!=None:
                    v=float(v)#lo converto in numero altrimenti non fa i calcoli
                else:
                    v=0
                    #print("il valore della cella estratta alla riga ", n," è ", v)
                l[d:d]=[v] #dovrebbe inserirlo nell lista
                n=n+1
                d=d+1#sposta la posizione nella lista di 1
        
        
            print(l)
            a=sum(l)/len(l)#chiamo a la media dei valori nella lista
            a=round(a,2) #arrotondo la media a 2 cifre
            print("la media dei valori di ", ws.cell(row=1, column=s).value," degli ultimi 4 rilievi è ",a)
            print(s)
   
  
            #time.sleep(2)
            mediaValori.append(a)
   


        print("La media oraria dei valori rilevati è ",mediaValori)
        dataOra=ws.cell(row=(ultimaRigaSheet1-1),column=1).value
        #print (dataOra)
        #print("data è ",type(dataOra))
        dataOra=datetime.strptime(dataOra, "%d/%m/%Y %H:%M:%S")
        #print (dataOra)
        dataOra=dataOra.strftime('%d/%m/%Y %H')
        print ("data ora con strftime è ",dataOra)
        #print (type(dataOra))
        
        TAmb=mediaValori[0]
        UR=mediaValori[1]
        Luce=mediaValori[2]
        BS10=mediaValori[3]
        TS10=mediaValori[4]
        BS30=mediaValori[5]
        TS30=mediaValori[6]
        print ("la media dei dati orari in ", dataOra, "è ", TAmb," ", UR," ", Luce," ", BS10," ", TS10," ", BS30," ", TS30)
        #time.sleep(10)
        ws1.cell(row=ultima48ore+1, column=1).value = dataOra
        ws1.cell(row=ultima48ore+1, column=2).value = TAmb
        ws1.cell(row=ultima48ore+1, column=3).value = UR
        ws1.cell(row=ultima48ore+1, column=4).value = Luce
        ws1.cell(row=ultima48ore+1, column=5).value = BS10
        ws1.cell(row=ultima48ore+1, column=6).value = TS10
        ws1.cell(row=ultima48ore+1, column=7).value = BS30
        ws1.cell(row=ultima48ore+1, column=8).value = TS30
        #time.sleep(10)
        print ("ho inserito tutti i dati orari al rigo ",ultima48ore+1,"del foglio ultime48ore di store")
        wb.save("/home/pi/plant+out/store.xlsx")
        print("ho salvato store")
        
    elif ultimaRigaSheet1>=5 and ultima48ore==49:
        print("attiva la parte di script che fa la media oraria e in 48ore sposta i dati un rigo più in alto ed inserisce la media appena fatta al rigo 49")
        ws1.move_range("A3:H49", rows=-1, cols=0)
        print("ho spostato i dati di una riga in alto in ultime48ore")
        wb.save("/home/pi/plant+out/store.xlsx")
        print ("ho salvato store con i dati spostati una riga più in alto")
        mediaDatiInRiga49DiUltime48Ore()
        #wb.save("/home/pi/plant+out/store.xlsx")
        #print ("ho salvato store")




        
#************  S C R I P T   D A   P R O V A R E ***********************
scrivi48oreStore()
Lo so sono stato troppo lungo .....

Comunque Grazie, anche per la pazienza

:ciao: LaPa
Eterno imbranato su Ubuntu Linux e .... in tantissime altre cose :D
Avatar utente
nuzzopippo
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1532
Iscrizione: giovedì 12 ottobre 2006, 11:34

Re: [Python] Sequenza di comandi che non funziona se inserito in script diversi

Messaggio da nuzzopippo »

Lapa ha scritto:
domenica 4 dicembre 2022, 19:08
un grosso ringraziamento a Nuzzopippo per il tempo che ha dedicato a questo post e per i preziosi suggerimenti!
Nessun ringraziamento, io approfitto delle Vostre domande per guardare in direzioni "insolite" e, magari, scrutare in qualcosa cui non ho pensato di mio, quindi c'è un interesse anche mio.

Detto questo, neanche io sono un programmatore, l'argomento è solo un hobby per tenere in esercizio il cervello, quindi non prendere per oro colato ciò che dico ma "cum grano salis", cantonate ne prendo. Riguardo
Lapa ha scritto:
domenica 4 dicembre 2022, 19:08
... Alla fine forse riuscirò anche a capire cosa vuoi dire con
nuzzopippo ha scritto:
venerdì 2 dicembre 2022, 11:11
Secondo me dovresti sforzarti di codificare in modo un po' più astratto, utilizzando un unico punto di apertura/chiusura del documento e definendo funzioni parametrizzate per le varie necessità.
beh, un programma è un insieme di passi esattamente determinati, Ti sollecitavo ad effettuare una completa valutazione delle scritture da farsi nel foglio elettronico in un unico punto in modo da utilizzare un unico processo di apertura/scrittura nello stesso.
Nell'esempio che Ti ho fatto, le discriminanti che ho individuato per la scrittura, che sarebbero :
1 - che "Sheet1" abbia più di 3 righe;
2 - che "ultime48ore" abbia 49 righe o meno.
Sono entrambe presenti, con le relative azioni, entro la funzione "scrivi48oreStore(ws, ws1)" del codice proposto ... ciò per evitare ripetute aperture del foglio elettronico.
Certamente tali considerazioni di design applicativo non è che siano "immediate", e neanche facili da "spiegare" (almeno per me), fai bene a considerarle "a passetti" ed intanto proseguire con i metodi conosciuti.

... devo dire che son rimasto sorpreso dall'ultimo codice da Te proposto, mi aspettavo che l'oggetto globale "ws1=wb["ultime48ore"]" rimanesse tale con tutte le sue proprietà e metodi, l'evidenza del mancato funzionamento del codice originario e del funzionamento del codice corrente con inserimento di tale variabile quale locale alla funzione mi dice chiaramente che le operazioni di "scrittura" relegano l'oggetto allo spazio dei nomi locale alla funzione, non me lo aspettavo.
Per altro, indagando nella docs di openpyxl (libreria che non uso tanto) ho trovato che i workbook hanno il metodo "close()" : possibile sia questo (e non gli sleep) un possibile fattore critico nel Tuo codice originale, che un foglio aperto debba essere "chiuso" prima di riaprirlo?

... come vedi, quanto sopra è istruttivo anche per me, Tu che puoi, fai una prova con "close()" alle singole tre fasi di scrittura del codice originario, fai sapere.

Ciao :ciao:
Fatti non foste a viver come bruti ...
Avatar utente
Lapa
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 362
Iscrizione: mercoledì 30 dicembre 2009, 17:01

Re: [Python] Sequenza di comandi che non funziona se inserito in script diversi

Messaggio da Lapa »

Salve a tutti!
nuzzopippo ha scritto:
lunedì 5 dicembre 2022, 8:38
/en/latest/api/openpyxl.workbook.workbook.html#openpyxl.workbook.workbook.Workbook.close]close()[/url]" : possibile sia questo (e non gli sleep) un possibile fattore critico nel Tuo codice originale, che un foglio aperto debba essere "chiuso" prima di riaprirlo?

... come vedi, quanto sopra è istruttivo anche per me, Tu che puoi, fai una prova con "close()" alle singole tre fasi di scrittura del codice originario, fai sapere.

Ciao :ciao:
Niente: ho provato a mettere wb.close() prima e dopo il salvataggio dei dati una volta scritto il ws di store ma la scrittura di 48ore non funziona.
Neanche io so spiegarmi perché ridefinendo in locale ws1 funziona.
Senza questa ridefininizione non dovrebbe dare un traceback?

Va bene, vado avanti
Grazie
:ciao: LaPa
Eterno imbranato su Ubuntu Linux e .... in tantissime altre cose :D
Avatar utente
nuzzopippo
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1532
Iscrizione: giovedì 12 ottobre 2006, 11:34

Re: [Python] Sequenza di comandi che non funziona se inserito in script diversi

Messaggio da nuzzopippo »

Lapa ha scritto:
lunedì 5 dicembre 2022, 23:06
Niente: ho provato a mettere wb.close() prima e dopo il salvataggio dei dati una volta scritto il ws di store ma la scrittura di 48ore non funziona.
Neanche io so spiegarmi perché ridefinendo in locale ws1 funziona.
Senza questa ridefininizione non dovrebbe dare un traceback?
Lo spazio dei nomi e la visibilità delle variabili sono un argomento piuttosto complesso in python, non sono certo di quanto espongo in seguito.
Non necessariamente la mancanza di definizione all'interno della funzione darebbe luogo ad un traceback, una variabile globale a livello di modulo (come ws1) è visibile all'interno delle funzioni del modulo, Ti faccio un esempio

Codice: Seleziona tutto

Python 3.10.6 (main, Nov  2 2022, 18:53:38) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license()" for more information.
x = 10
def dammi_id():
    identifier = id(x)
    return identifier

dammi_id()
140199942455824
Come vedi, all'interno di "dammi_id()" possiamo tranquillamente vedere la variabile "x" definita esternamente alla funzione ... le cose cambiano se noi operiamo una assegnazione utilizzando in nome "x" in tale assegnazione

Codice: Seleziona tutto

def dammi_id():
    identifier = id(x)
    x = 10
    return identifier

dammi_id()
Traceback (most recent call last):
  File "/usr/lib/python3.10/idlelib/run.py", line 578, in runcode
    exec(code, self.locals)
  File "<pyshell#8>", line 1, in <module>
  File "<pyshell#7>", line 2, in dammi_id
UnboundLocalError: local variable 'x' referenced before assignment
Ciò perché viene definita la variabile di nome "x" all'interno dello spazio dei nomi locale alla funzione, il che esclude la visibilità della variabile a livello globale, si ha pertanto un errore perché la variabile locale viene utilizzata (chiedenno lo id) prima della sua effettiva definizione.

... dirai: ma le primitive assegnazioni

Codice: Seleziona tutto

        ws1.cell(row=ultima48ore+1, column=1).value = dataOra
        ws1.cell(row=ultima48ore+1, column=2).value = TAmb
        ws1.cell(row=ultima48ore+1, column=3).value = UR
non dovrebbero produrre un traceback?

un "non saprei per certo" è ciò che posso rispondere, non necessariamente ciò che avviene per oggetti di tipo elementare avviene per oggetti complessi, faccio un ulteriore esempio

Codice: Seleziona tutto

l = [1, 2]
def varia_l():
    l.append(3)

    
varia_l()
l
[1, 2, 3]
def varia_l():
    l[2] = 4

    
varia_l()
l
[1, 2, 4]
come vedi, definita una lista a livello globale posso tranquillamente aggiungerci elementi od effettuare assegnazioni ai suoi componenti e tali operazioni avranno effetto, ciò (credo) perché in realtà il nome "l" altro non è che un puntatore ad una data zona di memoria, per contro, se facessimo una assegnazione diretta al nome di variabile

Codice: Seleziona tutto

def varia_l():
    l = [5, 6]

    
varia_l()
l
[1, 2, 4]
il prodotto sarà qualcosa "di nuovo" che non avrà effetto al di fuori della funzione, sempre per dette questioni di visibilità.

... resta il fatto che assegnazioni e metodi effettuati sulle variabili globali nel codice originario NON hanno avuto effetto (come personalmente mi aspettavo avessero) mentre dichiarando localmente il foglio, ovvero passandolo quale parametro come nel mio esempio, dette operazioni hanno luogo ... forse dipenderà da aspetti di implementazione delle classi di openpyxl interessate, forse da altri concetti che non si hanno presenti, comunque faccenda da tener presente e studiare.

Ciao
Fatti non foste a viver come bruti ...
Avatar utente
Lapa
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 362
Iscrizione: mercoledì 30 dicembre 2009, 17:01

Re: [Python] Sequenza di comandi che non funziona se inserito in script diversi

Messaggio da Lapa »

Salve a tutti,
confermo che anche un altro chunk che utilizza la libreria Openpyxl funzionante se usato in maniera a se stante, se inserito in un altro script non funziona se la definizione dei fogli Excell non è locale (all'interno della funzione).
Anche se continuo a non comprendere completamente (soprattutto la mancanza di un traceback quando non funziona) direi di mettere [Risolto] al primo post.

CIAO
LaPa
Eterno imbranato su Ubuntu Linux e .... in tantissime altre cose :D
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 4 ospiti