I am writing a Python program where I need to write to a file. I need an if condition to determine if I need to keep writing to same file or open a new file. How do I declare the file so that I can access it with both the if and else? Right now I'm making a test file before the loop just so I have access to the variable. How to avoid opening a TEST.txt file while still having a variable f that I can operate on?
f = open(outputFolder + "TEST.txt", 'w') # how to avoid opening TEST.txt here
while row:
#print(str(row[0]) + '|' + str(row[4]))
currentFileName = getFileName(str(row[0]))
# If coming up on new date open new file
if currentFileName != fileName:
f.close()
fileName = currentFileName
print("Processing: " + fileName)
f = open(outputFolder + fileName, 'w')
f.write(getLine(row))
# else write to current file
else:
f.write(getLine(row))
row = cursor.fetchone()
You didn't work out your logic before writing the program. What you describe in words does not match what you wrote. Start with the words, draw a flowchart, and then write your code.
In your posted program, you're trying to open currentFile multiple times, you don't initialize or change row, and it's not clear what you intend the program to do.
if [condition]:
filename = currentFileName
else:
filename = "TEST.txt"
f = open(filename)
for ... # whatever you're trying to do with your input and output,
# look up the proper method in a file-handling tutorial.
Related
If I want to run a program that writes a print("hello world") in the code of my main file, where I wrote the original program, how would I do that in Python?
I thought something like:
import main
with open("main.py " , "a+") as file_object:
file_object.seek(0)
data = file_object.read(100)
if len(data)>0:
file_object.write("\n")
file_object.write('print("hello world)')
but the console shows this:
ValueError: I/O operation on closed file.
From my understanding, you are trying to determine if a file has content and if it does include a new line, and then append the print statement.
You do not need to use seek you can just check the size of the file:
import os
if os.path.getsize(filename):
# file isn't empty
else:
# file is empty
You should also close the quotation marks in your print statement
You can use __file__ which gives you the path of your file and then append your text to it.
path = __file__
f = open(path, "a")
f.write('\nprint("hello world")')
f.close()
you wrong because Indent correctly, like this. You can modify like:
import main
with open("main.py" , "a+") as file_object:
file_object.seek(0)
data = file_object.read(100)
if len(data)>0:
file_object.write("\n")
file_object.write('print("hello world")')
I'm farily new to python and I'm currently stuck when trying to improve my script. I have a script that performs a lot of operations using selenium to automate a manual task. The scripts opens two pages, searches for an email, fetches data from that page and sends it to another tab. I need help to feed the script a textfile containing a list of email addresses, one line at a time and using each line to search the webpage. What I need is the following:
Open file "test.txt"
Read first line in text file and store this value for use in another function.
perform function which uses line from text file as its input value.
Add "Completed" behind the first line in the text file before moving to the next
Move to and read next line i text file, store as variable and repeat from step 3.
I'm not sure how I can do this.
Here is a snippet of my code at the time:
def fetchEmail():
fileName = input("Filename: ")
fileNameExt = fileName + ".txt" #to make sure a .txt extension is used
line = f.readline()
for line in f:
print(line) # <-- How can I store the value here for use later?
break
def performSearch():
emailSearch = driver.find_element_by_id('quicksearchinput')
emailSearch.send_keys(fetchEmail, Keys.RETURN) <--- This is where I want to be able to paste current line for everytime function is called.
return main
I would appreciate any help how I can solve this.
It's a bit tricky to diagnose your particular issue, since you don't actually provide real code. However, probably one of the following will help you:
Return the list of all lines from fetchEmail, then search for all of them in send_keys:
def fetchEmail():
fileName = input("Filename: ")
fileNameExt = fileName + ".txt"
with open(fileNameExt) as f:
return f.read().splitlines()
def performSearch():
emailSearch = driver.find_element_by_id('quicksearchinput')
emailSearch.send_keys(fetchEmail(), Keys.RETURN)
# ...
Yield them one at a time, and look for them individually:
def fetchEmail():
fileName = input("Filename: ")
fileNameExt = fileName + ".txt"
with open(fileNameExt) as f:
for line in f:
yield line.strip()
def performSearch():
emailSearch = driver.find_element_by_id('quicksearchinput')
for email in fetchEmail():
emailSearch.send_keys(email, Keys.RETURN)
# ...
I don't recommend using globals, there should be a better way to share information between functions (such as having both of these in a class instance, or having one function call the other like I show above), but here would be an example of how you could save the value when the first function gets called, and retrieve the results in the second function at an arbitrary later time:
emails = []
def fetchEmail():
global emails
fileName = input("Filename: ")
fileNameExt = fileName + ".txt"
with open(fileNameExt) as f:
emails = f.read().splitlines()
def performSearch():
emailSearch = driver.find_element_by_id('quicksearchinput')
emailSearch.send_keys(emails, Keys.RETURN)
# ...
In one of my games, I need to append to the end of the game saves file if I the user is new or change the balance in the file if the user already has a game save. This requires me to open the file separately in write and append modes. Is there a way I could do this sumultaneously?
def write_to_txt(self):
if self.saved_game:
with open("Game Saves.txt", "w") as f:
new_saved_game = self.list_saved_game[0] + self.list_saved_game[1][:10] + str(self.balance) + "\n"
f.write(''.join(self.contents_of_txt_file).replace(self.saved_game, new_saved_game))
else:
with open("Game Saves.txt", "a") as f:
f.write("User: {}\nBalance = {}\n".format(self.name, self.balance))
It seems to me that you want a way to delete the contents of the file while in append mode? You could open it in append mode and then use the .truncate() method when you want to start writing from a clean file (as you would if you opened it in write mode).
See this answer: How to erase the file contents of text file in Python?
You can use something like:
with open("Game Saves.txt", ('a' if self.saved_game else 'w')) as f:
<rest of the code>
I modified the code based on the comments from experts in this thread. Now the script reads and writes all the individual files. The script reiterates, highlight and write the output. The current issue is, after highlighting the last instance of the search item, the script removes all the remaining contents after the last search instance in the output of each file.
Here is the modified code:
import os
import sys
import re
source = raw_input("Enter the source files path:")
listfiles = os.listdir(source)
for f in listfiles:
filepath = source+'\\'+f
infile = open(filepath, 'r+')
source_content = infile.read()
color = ('red')
regex = re.compile(r"(\b be \b)|(\b by \b)|(\b user \b)|(\bmay\b)|(\bmight\b)|(\bwill\b)|(\b's\b)|(\bdon't\b)|(\bdoesn't\b)|(\bwon't\b)|(\bsupport\b)|(\bcan't\b)|(\bkill\b)|(\betc\b)|(\b NA \b)|(\bfollow\b)|(\bhang\b)|(\bbelow\b)", re.I)
i = 0; output = ""
for m in regex.finditer(source_content):
output += "".join([source_content[i:m.start()],
"<strong><span style='color:%s'>" % color[0:],
source_content[m.start():m.end()],
"</span></strong>"])
i = m.end()
outfile = open(filepath, 'w+')
outfile.seek(0)
outfile.write(output)
print "\nProcess Completed!\n"
infile.close()
outfile.close()
raw_input()
The error message tells you what the error is:
No such file or directory: 'sample1.html'
Make sure the file exists. Or do a try statement to give it a default behavior.
The reason why you get that error is because the python script doesn't have any knowledge about where the files are located that you want to open.
You have to provide the file path to open it as I have done below. I have simply concatenated the source file path+'\\'+filename and saved the result in a variable named as filepath. Now simply use this variable to open a file in open().
import os
import sys
source = raw_input("Enter the source files path:")
listfiles = os.listdir(source)
for f in listfiles:
filepath = source+'\\'+f # This is the file path
infile = open(filepath, 'r')
Also there are couple of other problems with your code, if you want to open the file for both reading and writing then you have to use r+ mode. More over in case of Windows if you open a file using r+ mode then you may have to use file.seek() before file.write() to avoid an other issue. You can read the reason for using the file.seek() here.
I have a program which writes a user's highscore to a text file. The file is named by the user when they choose a playername.
If the file with that specific username already exists, then the program should append to the file (so that you can see more than one highscore). And if a file with that username doesn't exist (for example, if the user is new), it should create a new file and write to it.
Here's the relevant, so far not working, code:
try:
with open(player): #player is the varible storing the username input
with open(player, 'a') as highscore:
highscore.write("Username:", player)
except IOError:
with open(player + ".txt", 'w') as highscore:
highscore.write("Username:", player)
The above code creates a new file if it doesn't exist, and writes to it. If it exists, nothing has been appended when I check the file, and I get no errors.
Have you tried mode 'a+'?
with open(filename, 'a+') as f:
f.write(...)
Note however that f.tell() will return 0 in Python 2.x. See https://bugs.python.org/issue22651 for details.
It's not clear to me exactly where the high-score that you're interested in is stored, but the code below should be what you need to check if the file exists and append to it if desired. I prefer this method to the "try/except".
import os
player = 'bob'
filename = player+'.txt'
if os.path.exists(filename):
append_write = 'a' # append if already exists
else:
append_write = 'w' # make a new file if not
highscore = open(filename,append_write)
highscore.write("Username: " + player + '\n')
highscore.close()
Just open it in 'a' mode:
a Open for writing. The file is created if it does not exist. The stream is positioned at the end of the file.
with open(filename, 'a') as f:
f.write(...)
To see whether you're writing to a new file, check the stream position. If it's zero, either the file was empty or it is a new file.
with open('somefile.txt', 'a') as f:
if f.tell() == 0:
print('a new file or the file was empty')
f.write('The header\n')
else:
print('file existed, appending')
f.write('Some data\n')
If you're still using Python 2, to work around the bug, either add f.seek(0, os.SEEK_END) right after open or use io.open instead.
Notice that if the file's parent folder doesn't exist you'll get the same error:
IOError: [Errno 2] No such file or directory:
Below is another solution which handles this case:
(*) I used sys.stdout and print instead of f.write just to show another use case
# Make sure the file's folder exist - Create folder if doesn't exist
folder_path = 'path/to/'+folder_name+'/'
if not os.path.exists(folder_path):
os.makedirs(folder_path)
print_to_log_file(folder_path, "Some File" ,"Some Content")
Where the internal print_to_log_file just take care of the file level:
# If you're not familiar with sys.stdout - just ignore it below (just a use case example)
def print_to_log_file(folder_path ,file_name ,content_to_write):
#1) Save a reference to the original standard output
original_stdout = sys.stdout
#2) Choose the mode
write_append_mode = 'a' #Append mode
file_path = folder_path + file_name
if (if not os.path.exists(file_path) ):
write_append_mode = 'w' # Write mode
#3) Perform action on file
with open(file_path, write_append_mode) as f:
sys.stdout = f # Change the standard output to the file we created.
print(file_path, content_to_write)
sys.stdout = original_stdout # Reset the standard output to its original value
Consider the following states:
'w' --> Write to existing file
'w+' --> Write to file, Create it if doesn't exist
'a' --> Append to file
'a+' --> Append to file, Create it if doesn't exist
In your case I would use a different approach and just use 'a' and 'a+'.
Using the pathlib module (python's object-oriented filesystem paths)
Just for kicks, this is perhaps the latest pythonic version of the solution.
from pathlib import Path
path = Path(f'{player}.txt')
path.touch() # default exists_ok=True
with path.open('a') as highscore:
highscore.write(f'Username:{player}')