I'm trying to change multiple variables in another file, but only one variable will get updated unless I close out and reenter the program. This is a simple version of the code:
import pyVars
def loop():
newVar = int(input('New var: '))
temp1 = newVar
temp2 = pyVars.varA
temp3 = pyVars.varB
f = open('pyVars.py', 'w')
f.close()
f = open('pyVars.py', 'a')
f.write('varA = ' + str(temp1) + '\n')
f.write('varB = ' + str(temp2) + '\n')
f.write('varC = ' + str(temp3) + '\n')
f.close()
f = open('pyVars.py')
print(f.read())
f.close()
loop()
loop()
And I get the variables from another file I created in the same folder:
varA = 0
varB = 0
varC = 0
Only varA keeps changing. How do I fix this?
You can use Python's clever variable swapping syntax as follows:
import pyVars
def loop():
newVar = int(input('New var: '))
pyVars.varA, pyVars.varB, pyVars.varC = newVar, pyVars.varA, pyVars.varB
with open('pyVars.py', 'rb') as f:
print(f.read())
loop()
loop()
This most probably has to do with the import statement. When you write:
import pyVars
You get varA=0, varB=0, varC=0 as copies of the pyVars variables.
No matter how many times you change the values of varA, varB, varC, whenever you try to read pyVars.varA, pyVars.varB, it is always returning 0 as that was the vaues it had imported. I initally set varA=700, varB=800, varC=900 and debugged, and on each loop, the initial values of varA was still 700. I checked the initial values by making changes to the code:
from pyVar import varA, varB, varC
While debugging, varA always returned 700, even though the actual value of varA was different in pyVars.py file.
That is also the reason why only varA is getting updated on your pyVars.py file. A is getting the input from the user, but B and C were set to the values of A and B, which were imported as 0. So they always stay as 0.
This is my understanding after fiddling with the code for more than 30 mins now. I would be happy to be corrected by someone, but nevertheless, it has been a great question/learning experience for me. Thank you!
Edit: So I have finally got it to work. It was related to the import statement. Since you are changing the source file that was imported, you will need to reload the file if you need to use the new values. Please see the code that I have changed, which works for me:
import importlib
def loop():
import pyVars
pyVars = importlib.reload(pyVars)
newVar = int(input('New var: '))
temp1 = newVar
temp2 = pyVars.varA
temp3 = pyVars.varB
f = open('pyVars.py', 'w')
f.close()
f = open('pyVars.py', 'a')
f.write('varA = ' + str(temp1) + '\n')
f.write('varB = ' + str(temp2) + '\n')
f.write('varC = ' + str(temp3) + '\n')
f.close()
f = open('pyVars.py')
print(f.read())
f.close()
loop()
loop()
Related
Could someone please explain why this code won't write to a text file?
I run the code but a text file is not created and also cannot be opened using f.open("data.txt","r")
f = open("data.txt", "w+")
n = 1
s = 0
for n in range(1, 999999):
s += 1/n**2
print(s, end="\r")
x = s*6
pisquare = math.sqrt(x)
f.write("Pi is ", pisquare)
f.close()
The recommended way to open and write to a file is as follow:
with open(file_path, 'w') as file:
file.write(f'Pi is {pisquare}')
We use the context manager with so the file closes automatically when done with .write(). This prevents memory corruption when your program exits prematurely I believe.
However, as you have probably noticed, your problem comes from this line:
f.write("Pi is ", pisquare)
You are giving .write() two arguments rather than one string.
import math
f = open("data.txt", "w+")
n = 1
s = 0
for n in range(1, 999999):
s += 1/n**2
print(s, end="\r")
x = s*6
pisquare = math.sqrt(x)
f.write("Pi is " + str(pisquare))
f.close()
I am able to create the text file. Please check for it in your current directory. But if I understand your code correctly, this is what you are looking for -
import math
n = 1
s = 0
with open("data.txt", "w+") as f:
for n in range(1, 9999):
s += 1/n**2
print(s, end="\r")
x = s*6
pisquare = math.sqrt(x)
f.write(" Pi is " + str(pisquare) + "\n")
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()
I have a problem with writing to file.
What seems to happen is that a program prints numbers to screen in the order 0,1,2,3 (zeroth, first, second, third) but writes to file in the order -1, 0, 1, 2. Even when the print to screen command follows the write to file command.
Sample code follows. Any ideas how to make it write to file in order 0,1,2,3?
Many thanks - Scriptham.
import random
import time
ln = 4
mins = 10
j = 0
n_sensor = 0
temp_c = 0
data_file = "/home/pi/laboratory/test.csv"
def read_temp():
temp_c = 100 * random.random()
return str("%.3f"% temp_c)
for j in range (1,mins):
f = open(data_file,'a')
f.write("\n" + str(j))
f.close
for n_sensor in range (0,ln):
#device_file_1 =
print("A " + str(n_sensor))
x = read_temp()
f = open(data_file, 'a')
f.write("," + x)
f.close
print("OP temp_c = ", x)
#time.sleep(0.5)
time.sleep(10) #normally would be 59.5 or 60 or similar
quit()
The problem is most likely that you're opening the output file dozens of times, but never closing it.
You should do f = open(data_file,'a') before the loop and only once. Then when everything's done, call f.close() (f.close is not the same as f.close()!).
To make sure the file is always closed, you should use the with statement.
For example:
with open(data_file, 'a') as f:
f.write("\n" + str(j))
This will close the file, even if an exception happens during the write.
Alternatively, you need to use something like:
f = open(data_file, 'a')
try:
f.write("\n" + str(j))
finally:
f.close()
Essentially what I am attempting to do is read 'n' number of lines from a file and then write them to a separate file. This program essentially should take a file that has 100 lines and separate that file into 50 separate files.
def main():
from itertools import islice
userfile = raw_input("Please enter the file you wish to open\n(must be in this directory): ")
file1 = open(userfile, "r+")
#print "Name: ", file1.name
#print "Closed or not", file1.closed
#print "Opening mode: ", file1.mode
#print "Softspace flag: ", file1.softspace
jcardtop = file1.read(221);
#print jcardtop
n = 2
count = 0
while True:
next_n_lines = list(islice(file1,n))
print next_n_lines
count = count + 1
fileout = open(str(count)+ ".txt", "w+")
fileout.write(str(jcardtop))
fileout.write(str(next_n_lines))
fileout.close()
break
if not next_n_lines:
break
I do have the file printing as well to show what is in the variable next_n_lines.
*['\n', "randomtext' more junk here\n"]
I would like it instead to look like
randomtext' more junk here
Is this a limitatoin of the islice function? Or am I missing a portion of the syntax?
Thanks for your time!
Where you call str() or print, you want to ''.join(next_n_lines) instead:
print ''.join(next_n_lines)
and
fileout.write(''.join(next_n_lines))
You can store the flattened string in a variable if you don't want to call join twice.
Did you mean something like this?
f = open(userfile,"r")
start = 4
n_lines = 100
for line in f.readlines()[start:(start + n_lines)]:
print line
#do stuff with line
or maybe this rough, yet effective code:
f = open(userfile,"r")
start = 4
end = start + 100
count = start
while count != end:
for line in f.readlines()[count:(count + 2)]:
fileout = open(str(count)+ ".txt", "w+")
fileout.write(str(line))
fileout.close()
count = count + 2
I am very new in python, but I have been able to make few useful python codes (at least useful for my work). I would like to combine two of my codes, but I have a hard time making it work, I think I am completely lost in how the code should looks like.
The first code basically takes a file, read it, extract to columns from it, and then write the columns in a new file. I repeat this with several files:
import sys
import re
filetowrite = sys.argv[1]
filetoread = sys.argv[2]
newfile = str(filetowrite) + ".txt"
openold = open(filetoread,"r")
opennew = open(newfile,"w")
rline = openold.readlines()
number = int(len(rline))
start = 0
for i in range (len(rline)) :
if "2theta" in rline[i] :
start = i
opennew.write ("q" + "\t" + "I" + "\n")
opennew.write ("1/A" + "\t" + "1/cm" + "\n")
opennew.write (str(filetowrite) + "\t" + str(filetowrite) + "\n")
for line in rline[start + 1 : number] :
words = line.split()
word1 = (words[1])
word2 = (words[2])
opennew.write (word1 + "\t" + word2 + "\n")
openold.close()
opennew.close()
The second code takes the new previously created files and combine them in a way in which the columns are next to each other in the final file.
import sys
from itertools import izip
filenames = sys.argv[2:]
filetowrite = sys.argv[1]
newfile = str(filetowrite) + ".txt"
opennew = open(newfile, "w")
files = map(open, filenames)
for lines in izip(*files):
opennew.write(('\t'.join(i.strip() for i in lines))+"\n")
Any help in how to proceed to make a single code out of these two codes is highly appreciated.
All the best
Make each file into a function in one larger file, then call the functions as necessary. Make use of __main__ to do that.
import sys
import re
from itertools import izip
def func_for_file1():
# All of the code from File 1 goes here.
def func_for_file2():
# ALl of the code from File 2 goes here.
def main():
# Decide what order you want to call these methods.
func_for_file1()
func_for_file2()
if __name__ == '__main__':
main()