How to assign a global variable in multi-threading in python - python

I am using multithreading and its working fine.In the first thread as mentioned in the code, I need my csv file to be saved with filename as Logger1 for the first time and after this logger1 file has crossed 1000 lines it should be converted into zip file, and removed while 'i' gets incremented by 1.Now after this, the further data should be saved in the csv file with filename as logger2.
If variable 'i' is assigned value the way, as shown in the code then unbound local error appears stating variable i is referenced before assignment. If I declare it like global i instead of just i=1 in the beginning, same error appears. If I assigned value inside the u1thread this value never gets actually incremented because every time the thread is executed i is set to be 1.
i=1
class u1Thread(threading.Thread):
def run(self):
while True:
export_csv = x.to_csv (r'/home/pi/Logger' + str(i)
+ '.csv', index = None, mode='a',
header=False)
input_file = open("Logger" + str(i) + ".csv","r+")
reader_file = csv.reader(input_file)
l = len(list(reader_file))
if (l > 1000) :
jungle_zip = zipfile.ZipFile('Logger' + str(i) +
'.zip', 'w')
jungle_zip.write('Logger' + str(i) + '.csv',
compress_type=zipfile.ZIP_DEFLATED)
jungle_zip.close()
os.remove("Logger" + str(i) + ".csv")
i +=1
class vfThread(threading.Thread):
def run(self):
while True:
ret, frame=video.read()

Related

Python replace str in list with new value

I’m writing a program that makes music albums into files that you can search for, and for that i need a str in the file that have a specific value that is made after the list is complete. Can you go back in that list and change a blank str with a new value?
I have searched online and found something called words.replace, but it doesn’t work, i get a Attribute error.
def create_album():
global idnumber, current_information
file_information = []
if current_information[0] != 'N/A':
save()
file_information.append(idnumber)
idnumber += 1
print('Type c at any point to abort creation')
for i in creation_list:
value = input('\t' + i)
if value.upper == 'C':
menu()
else:
-1file_information.append('')
file_information.append(value)
file_information.append('Album created - ' + file_information[2] +'\nSongs:')
-2file_information = [w.replace(file_information[1], str(file_information[0]) + '-' + file_information[2]) for w in file_information]
current_information = file_information
save_name = open(save_path + str(file_information[0]) + '-' + str(file_information[2]) + '.txt', 'w')
for i in file_information:
save_name.write(str(i) + '\n')
current_files_ = open(information_file + 'files.txt', 'w')
filenames.append(file_information[0])
for i in filenames:
current_files_.write(str(i) + '\n')
id_file = open(information_file + 'albumid.txt', 'w')
id_file.write(str(idnumber))
-1 is where i have put aside a blank row
-2 is the where i try to replace row 1 in the list with the value of row 0 and row 2.
The error message I receive is ‘int’ object has no attribute ‘replace’
Did you try this?
-2file_information = [w.replace(str(file_information[1]), str(file_information[0]) + '-' + file_information[2]) for w in file_information]

How to write an integer variable to log file with f.write?

This script is a simple while True loop that checks a voltage value and writes a log file. However, I am not able to get the voltage value written in the log.
Simple log files with a text string and date / timestamp work fine but the write fails when I try to use the variable name.
ina3221 = SDL_Pi_INA3221.SDL_Pi_INA3221(addr=0x40)
LIPO_BATTERY_CHANNEL = 1
busvoltage1 = ina3221.getBusVoltage_V(LIPO_BATTERY_CHANNEL)
while True:
if busvoltage1 <= 3.70:
with open("/<path>/voltagecheck.log", "a") as f:
f.write("battery voltage below threshold: " + busvoltage1 + "\n")
f.write("timestamp: " + time.asctime() + "\n")
f.write("-------------------------------------------" + "\n")
f.close()
else:
time.sleep(3600)
I've also tried:
with open("/<path>/voltagecheck.log", "a") as f:
f.write("battery voltage below threshold: " + str(busvoltage1) + "\n")
f.write("timestamp: " + time.asctime() + "\n")
f.write("-------------------------------------------" + "\n")
f.close()
Without trying to add the busvoltage1 value to the log, the log is created and the timestamp line works fine.
With the busvoltage1 value, the log is created but nothing is written.
When running this in the terminal, the errors for "str(busvoltage1)" and just the plain "busvoltage1" are:
ValueError: I/O operation on closed file
and
TypeError: cannot concatenate 'str' and 'float' objects
The value needs to be formatted as a string before f.write is used.
Added v = str(busvoltage1) and then referenced v in f.write: f.write(battery voltage below threshold: " + v + "\n")
This is referenced in the 5th example of 7.2.1 here: https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files. Thanks #PatrickArtner

Increment file name while writing file in Python

My code works and increments filename but only for two first files, after that it creates new strings in existing second file. Please help me upgrade code to increment go further.
text = 'some text'
file_path = '/path/to/file'
filename = 'textfile'
i = 1
txtfile = self.file_path + filename + str(i) + '.txt'
if not os.path.exists(txtfile):
text_file = open(txtfile, "a")
text_file.write(self.text)
text_file.close()
elif os.path.exists(txtfile) and i >= 1:
i += 1
text_file1 = open(self.file_path + filename + str(i) + '.txt', "a")
text_file1.write(self.text)
text_file1.close()
If your example is part of a loop, your resetting i to 1 in every iteration. Put the i=1 outside of this part.
And it will also start at 1 when you restart your program - sometimes not what you want.

Appending to Created File in Python

I have a file, which I am writing data to, however I would like the naming convention to have the time, the file was created at and then stream to the same file for one hour before creating a new text file.
My problem is that I am using a while loop to create the text file while reading from a GPIO and so when the code runs, it creates a new text file every time it moves through the loop. How can I create the file, then write to the existing file for a predetermined amount of time?
import spidev
import time
import datetime
import os
spi = spidev.SpiDev()
spi.open(0,0) #open port 0 of the SPI
count = 0
def timeStamp(fname, fmt ='%Y-%m-%d-%H-%M-%S_{fname}'):
#this function adds the time and date
return datetime.datetime.now().strftime(fmt).format(fname = fname)
def alarm_check(int):
#this function checks the value read in by the SPI
#creating an alarm if the value is 0
if int == 0:
return ("System Alarm!")
else:
return ("System OK")
def write_to_file(int):
# this function will write the current value to a file,
# the time it was read in
# and if the system was im alarm
with open (('SPI_Input_Values'), 'a') as output:
output.write("Input = " + str(int) + '\t' + timeStamp('ADC') + '\t\t' + str(alarm_check(int)) + '\n')
def readadc(adcnum):
#this function will open the SPI and read it to see the current value
# this will then be written to a text value
# using the write_to_file function
if adcnum > 7 or adcnum < 0:
return -1
r = spi.xfer2([1,8 + adcnum << 4,0])
adcout = ((r[1] & 3) << 8) + r[2]
return adcout
while True:
Inp1 = int(round(readadc(0)/10.24)) # defines Inp1 as an integer to be read in
write_to_file(Inp1)
count = count +1
time.sleep(0.1) # puts the systemm to sleep for 0.1 seconds
You need to dynamically create your filename. At the moment it was a hardcoded string. Here's an example:
fname = 'SPI_Input_Values'
fmt ='%Y-%m-%d-%H'
date_str = datetime.datetime.now().strftime(fmt)
file_name = date_str + "_" + fname
with open ((file_name, 'a') as output:
output.write("Input = " + str(int) + '\t' + timeStamp('ADC') + '\t\t' + str(alarm_check(int)) + '\n')
This will constantly append to the file that represents the current hour. When the next hour begins, it will automatically create a new file and begin appending data to it instead.
Something like:
def write_to_file(output, int):
output.write("Input = " + str(int) + '\t' + timeStamp('ADC') + '\t\t' + str(alarm_check(int)) + '\n')
with open (('SPI_Input_Values'), 'a') as output:
while True:
Inp1 = int(round(readadc(0)/10.24)) # defines Inp1 as an integer to be read in
write_to_file(output, Inp1)
count = count +1
time.sleep(0.1)

Copy a file to a new location and increment filename, python

I am trying to:
Loop through a bunch of files
makes some changes
Copy the old file to a sub directory. Here's the kicker I don't want to overwrite the file in the new directory if it already exists. (e.g. if "Filename.mxd" already exists, then copy and rename to "Filename_1.mxd". If "Filename_1.mxd" exists, then copy the file as "Filename_2.mxd" and so on...)
save the file (but do a save, not a save as so that it overwrites the existing file)
it goes something like this:
for filename in glob.glob(os.path.join(folderPath, "*.mxd")):
fullpath = os.path.join(folderPath, filename)
mxd = arcpy.mapping.MapDocument(filename)
if os.path.isfile(fullpath):
basename, filename2 = os.path.split(fullpath)
# Make some changes to my file here
# Copy the in memory file to a new location. If the file name already exists, then rename the file with the next instance of i (e.g. filename + "_" + i)
for i in range(50):
if i > 0:
print "Test1"
if arcpy.Exists(draftloc + "\\" + filename2) or arcpy.Exists(draftloc + "\\" + shortname + "_" + str(i) + extension):
print "Test2"
pass
else:
print "Test3"
arcpy.Copy_management(filename2, draftloc + "\\" + shortname + "_" + str(i) + extension)
mxd.save()
So, 2 things I decided to do, was to just set the range of files well beyond what I expect to ever occur (50). I'm sure there's a better way of doing this, by just incrementing to the next number without setting a range.
The second thing, as you may see, is that the script saves everything in the range. I just want to save it once on the next instance of i that does not occur.
Hope this makes sense,
Mike
Use a while loop instead of a for loop. Use the while loop to find the appropriate i, and then save afterwards.
The code/pseudocode would look like:
result_name = original name
i = 0
while arcpy.Exists(result_name):
i+=1
result_name = draftloc + "\\" + shortname + "_" + str(i) + extension
save as result_name
This should fix both issues.
thanks to Maty suggestion above, I've come up with my answer. For those who are interested, my code is:
result_name = filename2
print result_name
i = 0
# Check if file exists
if arcpy.Exists(draftloc + "\\" + result_name):
# If it does, increment i by 1
i+=1
# While each successive filename (including i) does not exists, then save the next filename
while not arcpy.Exists(draftloc + "\\" + shortname + "_" + str(i) + extension):
mxd.saveACopy(draftloc + "\\" + shortname + "_" + str(i) + extension)
# else if the original file didn't satisfy the if, the save it.
else:
mxd.saveACopy(draftloc + "\\" + result_name)

Categories