I'm trying to write this code so that once it ends the previous answers are saved and the code could be run again without the old answers being overwritten. I moved the how, why and scale_of_ten variables into 'with open' section and I had some success with the code being able to work for the amount of times the files was executed, but each time it was executed the old answers were overwritten. How would I write the code so that it saves the old answers while it takes in new answers?
import csv
import datetime
# imports modules
now = datetime.datetime.now()
# define current time when file is executed
how = str(raw_input("How are you doing?"))
why = str(raw_input("Why do you feel that way?"))
scale_of_ten = int(raw_input("On a scale of 1-10. With 10 being happy and 1 being sad. How happy are you?"))
#creates variables for csv file
x = [now.strftime("%Y-%m-%d %H:%M"),how,why,scale_of_ten]
# creates list for variables to be written in
with open ('happy.csv','wb') as f:
wtr = csv.writer(f)
wtr.writerow(x)
wtr.writerow(x)
f.close()
With w mode, open truncates the file. Use a (append) mode.
....
with open ('happy.csv', 'ab') as f:
# ^
....
BTW, f.close() is not needed if you use with statement.
Related
This question already has answers here:
Why does my text file keep overwriting the data on it?
(3 answers)
Closed 2 years ago.
So, I did this python program and whenever I run it it says in the file "This is an update" and only one of the quotes I entered. Any help? Program below.
file_name = "my_quote.txt"
new_file = open(file_name, "w")
new_file.close()
def update_file(file_name,quote):
new_file = open(file_name, "w")
new_file.write("This is an update\n")
new_file.write(quote)
new_file.write("\n\n")
new_file.close()
for index in range(1,3):
quote = input("Enter your favorite quote:")
update_file(file_name, quote)
new_file = open(file_name, "r")
print(new_file.read())
new_file.close()
You're opening your file in w mode, which overwrites the file.
Use a for append mode, which, well, appends new content at the end.
You are writing over the current file as you are not opening the file in append mode.
If you change the open command to this instead:
file.open(file_path, 'a')
You will append the text instead of writing over the file.
Whenever you re-open a file, and use write it removes all content previously in the file and overwrites it. And since every time you call update_file you are re-opening it and writeing to it, only the last piece of info written in the last open will be kept (as all previous data was overwritten.
I think you want to use append mode when writing data to the file. See here for a list of all the modes, and their function.
Hope it helps!
I'm writing to a file in three functions and i'm trying not overwrite the file. I want every time i run the code i generate a new file
with open("atx.csv", 'w')as output:
writer = csv.writer(output)
If you want to write to different files each time you execute the script, you need to change the file names, otherwise they will be overwritten.
import os
import csv
filename = "atx"
i = 0
while os.path.exists(f"{filename}{i}.csv"):
i += 1
with open(f"{filename}{i}.csv", 'w') as output:
writer = csv.writer(output)
writer.writerow([1, 2, 3]) #or whatever you want to write in the file, this line is just an example
Here I use os.path.exists() to check if a file is already present on the disk, and increment the counter.
First time you run the script, you get axt0.csv, second time axt1.csv, and so on.
Replicate this for your three files.
EDIT
Also note that here I'm using formatted string literals which are available since python3.6. If you have an earlier version of python, use "{}{:d}.csv".format(filename, i) instead of f"{filename}{i}.csv"
EDIT bis after comments
If the same file is needed to be manipulated by more functionsduring the execution of the script, the easiest thing came to my mind is to open the writer outside the functions and pass it as an argument.
filename = "atx"
i = 0
while os.path.exists(f"{filename}{i}.csv"):
i += 1
with open(f"{filename}{i}.csv", 'w') as output:
writer = csv.writer(output)
foo(writer, ...) #put the arguments of your function instead of ...
bar(writer, ...)
etc(writer, ...)
This way each time you call one of the functions it writes to the same file, appending the output at the bottom of the file.
Of course there are other ways. You might check for the file name existence only in the first function you call, and in the others just open the file with the 'a' options, to append the output.
you can do something like this so that each file gets named something a little different and therefore will not be overwritten:
for v in ['1','2','3']:
with open("atx_{}.csv".format(v), 'w')as output:
writer = csv.writer(output)
You are using just one filename. When using the same value as a name atx.csv you will either overwritte it with w or append with a.
If you want new files to be created, just check first if the file is there.
import os
files = os.listdir()
files = [f for f in files if 'atx' in f]
num = str(len(files)) if len(files) > 0 else ''
filename = "atx{0}.csv".format(num)
with open(filename, 'w')as output:
writer = csv.writer(output)
Change with open("atx.csv", 'w') to with open("atx.csv", 'a')
https://www.guru99.com/reading-and-writing-files-in-python.html#2
I have a Python script that I want to increment a global variable every time it is run. Is this possible?
Pretty easy to do with an external file, you can create a function to do that for you so you can use multiple files for multiple vars if needed, although in that case you might want to look into some sort of serialization and store everything in the same file. Here's a simple way to do it:
def get_var_value(filename="varstore.dat"):
with open(filename, "a+") as f:
f.seek(0)
val = int(f.read() or 0) + 1
f.seek(0)
f.truncate()
f.write(str(val))
return val
your_counter = get_var_value()
print("This script has been run {} times.".format(your_counter))
# This script has been run 1 times
# This script has been run 2 times
# etc.
It will store in varstore.dat by default, but you can use get_var_value("different_store.dat") for a different counter file.
example:-
import os
if not os.path.exists('log.txt'):
with open('log.txt','w') as f:
f.write('0')
with open('log.txt','r') as f:
st = int(f.read())
st+=1
with open('log.txt','w') as f:
f.write(str(st))
Each time you run your script,the value inside log.txt will increment by one.You can make use of it if you need to.
Yes, you need to store the value into a file and load it back when the program runs again. This is called program state serialization or persistency.
For a code example:
with open("store.txt",'r') as f: #open a file in the same folder
a = f.readlines() #read from file to variable a
#use the data read
b = int(a[0]) #get integer at first position
b = b+1 #increment
with open("store.txt",'w') as f: #open same file
f.write(str(b)) #writing a assuming it has been changed
The a variable will I think be a list when using readlines.
Im writing a simple command line program involving id's, i want to make it so that every time i run a function it should add a value to a CSV file. I have made a function that i thought worked, but apparently not. One of my for loops is not running correctly ;( Here is my code:
def addId(id):
file = open(ID_FILE_PATH, 'wb+')
read = csv.reader(file)
write = csv.writer(file)
existingRows = []
existingRows.append(id)
for rows in read: # This does not run
print rows
if len(rows) > 0 and rows[0] not in existingRows:
existingRows.append(rows[0])
for rows in existingRows: # This runs
write.writerow([rows])
file.close()
Sorry for my bad English btw.
You open the file with:
file = open(ID_FILE_PATH, 'wb+')
According to the documentation:
note that 'w+' truncates the file
You truncate the file, so no wonder there is nothing to read in! Use rb+ instead.
This is similar or identical to csv writer not closing file but I'm not 100% sure why my behaviour is different.
def LoadCSV:
with open('test.csv', 'r') as csvfile:
targetReader = csv.reader(csvfile, delimiter=',')
for row in targetReader:
...
then finally in the function
csvfile.close()
This opens the test.csv file in the same direction as the script. Desired behaviour is for when the script has done what it's doing to the rows in the function, it renames the sheet to test.[timestamp] to archive it and watches the directory for a new sheet to arrive.
Later down the code;
os.rename('test.csv', "test." + time.strftime("%x") )
Gives an error that the file can't be renamed because a process is still using it. How do I close this file once I'm done? csvfile.close() doesn't raise an exception, and if I step through my code in interactive mode I can see that csvfile is a "closed file object." What even is that? Surely an open file is an object but a closed one isn't, how do I make my code forget this even exists so I can then do IO on the file?
NOT FOR POINTS.
Code is not valid anyway, since your function name is wrong. If that was not intentional, better edit it or to produce a pseudo-replica of your code, rather than have us guess what the issue is.
To iterate, the issues with your code:
def LoadCSV is not valid. def LoadCSV() is. Proof in following screenshot. Notice how the lack of () is showing syntax error markers.
Fixing (1) above, your next problem is using csvfile.close(). If the code is properly written, once the code is out of the scope of with, the file is closed automatically. Even if the renaming part of the code is inside the function, it shouldn't pose any problems.
Final word of warning -- using the format string %x will produce date-strings like 08/25/14, depending on locale. Obviously, this is erroneous, as a / is invalid in filenames in Windows (try renaming a file manually with this). Better to be very explicit and just use %m%d%y instead.
Finally, see the running code on my end. If your code is not structured like this, then other errors we cannot guess might arise.
Result as follows after running:
Code for reference:
import csv
import os
import time
def LoadCSV():
with open("test.csv", "r") as csvfile:
targetReader = csv.reader(csvfile, delimiter=",")
for row in targetReader:
print row
new_name = "test.%s.csv" % time.strftime("%m%d%y")
print new_name
os.rename("test.csv", new_name)
LoadCSV()
Note that on my end, there is nothing that watches my file. Antivirus is on, and no multithreading obviously is enabled. Check if one of your other scripts concurrently watches this file for changes. It's better if instead of watching the file, the file is sent as an argument post-renaming to this other function instead, as this might be the reason why it's "being used". On the one hand, and this is untested on my side, possibly better to copy the file with a new name rather than rename it.
Hope this helps.
When you are using a with block you do not need to close the file, it should be released outside the scope. If you want python to "forget" the entire filehandle you could delete it with del csvfile. But since you are using with you should not delete the variable inside the scope.
Try without the with scope instead:
csvfile = open('test.csv','r')
targetReader = csv.reader(csvfile, delimiter=',')
for row in targetReader:
....
csvfile.close()
del targetReader
os.rename('test.csv','test.'+time.strftime('%x'))
It might be the csv reader that still access the file when you are using a with block.