I'm making a joke program that has a text file storing jokes. On program load, it grabs all the lines from the file and assigns them to a jokes list Everything but the remove joke function is working. Whenever you call remove joke, it ends up re-writing every line in the text file to an empty string instead of the selected line
When running this function, it does remove the joke from the jokes list properly
def remove_joke():
for i in range(len(jokes)):
print(f"{i}\t{jokes[i]}")
remove_index = int(input("Enter the number of the joke you want to remove:\t"))
with open("jokes.txt", "r") as f:
lines = f.readlines()
with open("jokes.txt", "w") as f:
for line in lines:
print(line)
if line == jokes[remove_index]:
f.write("")
jokes.remove(jokes[remove_index])
Instead of
if line == jokes[remove_index]:
f.write("")
you want:
if line != jokes[remove_index]:
f.write(line+'\n')
Or even:
if line != jokes[remove_index]:
print(line, file=f)
Related
I am attempting to print the file, split by line using two methods: one is using the method read on files and the second is using a for loop and splitting the files into lines. I am getting a Traceback error on the last line stating that "words" is not defined. I cannot see why this is the case.
fname = input('enter file name')
try:
fhandle = open(fname, 'r')
except:
print('file does not exist')
exit()
#store entire file in a variable called data
data = fhandle.read()
print(data)
#iterate through each line in a file handle
for line in fhandle:
line = line.strip()
words = line.split()
print(words)
When reading a file, Python keeps track of a cursor within the file. Data is read from the position of the cursor onwards, and reading moves the cursor forward to the end of the data that was read. This is so that, e.g., calling f.readline() twice will return the next line each time, rather than the first line both times.
When you call f.read(), the whole file is read, so the cursor is moved to the end of the file. Then, when you iterate through fhandle, Python only considers the lines ahead of the cursor — of which there are none. Since the object being iterated through is empty, the body of the for loop is never executed, so words is never assigned to.
You can fix this by calling fhandle.seek(0) directly before the for loop to return the cursor to the start of the file.
There is also a logical error in your program. If you want to print every line, not just the last, in your for loop, you need to indent print(words) so that it's in the for loop.
As a best practice, you should also call fhandle.close() when you're finished using the file.
words it not define because of read(), it makes for loop didn't return anything.
Python file method read() reads at most size bytes from the file. If
the read hits EOF before obtaining size bytes, then it reads only
available bytes.
When print(words) is indented in for loop, it just return nothing too. But if read() is removed while print(words) isn't indented, it'll return a list of the last line:
fname = input('enter file name')
try:
fhandle = open(fname, 'r')
except:
print('file does not exist')
exit()
# store entire file in a variable called data
# data = fhandle.read()
# print(data)
# iterate through each line in a file handle
for line in fhandle:
line = line.strip()
words = line.split()
print(words)
# ['Line', '4']
And if print(words) is indented while read() is removed, it'll return this:
fname = input('enter file name')
try:
fhandle = open(fname, 'r')
except:
print('file does not exist')
exit()
# store entire file in a variable called data
# data = fhandle.read()
# print(data)
# iterate through each line in a file handle
for line in fhandle:
line = line.strip()
words = line.split()
print(words)
# ['Line', '1']
# ['Line', '2']
# ['Line', '3']
# ['Line', '4']
I'm not sure what is your intent using split() but if you just want to print line by line using read(), your code already did that.
When using for loop, just comment or remove read() then just print line
fname = input('enter file name')
try:
fhandle = open(fname, 'r')
except:
print('file does not exist')
exit()
# store entire file in a variable called data
# data = fhandle.read()
# print(data)
# iterate through each line in a file handle
for line in fhandle:
print(line.strip())
# Line 1
# Line 2
# Line 3
# Line 4
But if you're intend to make a list consisted of each line, you can use splitlines()
fname = input('enter file name')
try:
fhandle = open(fname, 'r')
except:
print('file does not exist')
exit()
#store entire file in a variable called data
data = fhandle.read().splitlines()
print(data)
# ['Line 1', 'Line 2', 'Line 3', 'Line 4']
Hopes this help.
Program Goal: Search a defined yamlfile (scan_dcn.yaml) and return all lines matching the search criteria as defined in the function_search_search_key() and function_search_event_type() functions.
Input File - scan_dcn.yaml:
search_dict:
[
{search_key: ["Failed to Process the file"],
event_type: "evttyp_repl_dcn_error",
event_description: "Failure to process DCN file",
priority: 50,
scan_interval: 1,
remove_dups: True,
category: "dcn",
context_begin: 0,
context_end: 1,
reportable: False,
offset: 0
},
Problem:
My program will return function_search_search_key() but will not proceed to function_search_event_type().
I would think that my problem is that I have no logic to proceed to the second function after the completion of the first.
Do I need to return a value in each function to proceed?
Python Source Code
yamlfile = open('scan_dcn.yaml', 'r')
def function_search_search_key():
search_search_key = ['{search_key:']
for line in yamlfile.readlines():
for word in search_search_key:
if word in line:
print(line)
def function_search_event_type():
search_event_type = ['event_type:']
for line in yamlfile.readlines():
for word in search_event_type:
if word in line:
print(line)
def main():
function_search_search_key()
function_search_event_type()
main()
In your first function you read the whole file with readlines. When you use readlines again in your second function you're already at the end of the file and there is no more data to read, so the for loop is not even entered.
But there's no need to read the file again for every function. Read the file outside of the functions and put it in a list. Then add a parameter to each of those functions that takes this list. In the function you can loop over the list.
def function_search_search_key(lines):
search_search_key = ['{search_key:']
for line in lines:
for word in search_search_key:
if word in line:
print(line)
def function_search_event_type(lines):
search_event_type = ['event_type:']
for line in lines:
for word in search_event_type:
if word in line:
print(line)
def main():
with open('scan_dcn.yaml', 'r') as yamlfile:
lines = yamlfile.readlines()
function_search_search_key(lines)
function_search_event_type(lines)
if __name__ = '__main__':
main()
If you ever need to change the name of the file you can do it in one place. If you open and read the file in every single function you would have to change all occurrances of the file name.
Your second function is being entered. It must if the call above it has finished.
You aren't seeing anything printed because you're attempting to loop though the same file more than once. Once you've read the file, it's exhausted. You can just re-read the file as a simple fix:
def function_search_search_key():
with open('scan_dcn.yaml', 'r') as yamlfile:
search_search_key = ['{search_key:']
for line in yamlfile.readlines():
for word in search_search_key:
if word in line:
print(line)
def function_search_event_type():
with open('scan_dcn.yaml', 'r') as yamlfile: # Read the file again
search_event_type = ['event_type:']
for line in yamlfile.readlines():
for word in search_event_type:
if word in line:
print(line)
You can read a file descriptor only once (if you don't seek to start), so you may open your file in each function
def function_search_search_key():
search_search_key = ['{search_key:']
with open('scan_dcn.yaml') as fic:
for line in fic:
for word in search_search_key:
if word in line:
print(line)
def function_search_event_type():
search_event_type = ['event_type:']
with open('scan_dcn.yaml') as fic:
for line in fic:
for word in search_event_type:
if word in line:
print(line)
def sort_domain():
if self.cb1.isChecked():
for line in f:
line= line.strip()
if line.endswith('.com') is True:
self.textBrowser.append(line)
else:
pass
elif not self.cb1.isChecked() and not self.cb2.isChecked():
for line in f:
line=line.strip()
self.textBrowser.append(line)
if self.cb2.isChecked():
for line in f:
line= line.strip()
if line.endswith('.net') is True:
self.textBrowser.append(line)
else:
pass
elif not self.cb1.isChecked() and not self.cb2.isChecked():
for line in f:
line=line.strip()
self.textBrowser.append(line)
self.btn2.clicked.connect(sort_domain)
If I checked cb1 and cb2 ((checkbox1 and chekbok2))
the results are all domains with extension .com only.
What is the correct way to write a function to show all Domains when you press the chekBox1 ".com" and chekBox2 ".net"?
Your implementation is not really efficient: it reads the contents of the file more than once. And this is also the issue of your program. After the first for-loop the file object points to the end of the file and to make it work you'd have to seek to the start again: f.seek(0)
I am very new to programming and the python language.
I know how to open a file in python, but the question is how can I open the file as a parameter of a function?
example:
function(parameter)
Here is how I have written out the code:
def function(file):
with open('file.txt', 'r') as f:
contents = f.readlines()
lines = []
for line in f:
lines.append(line)
print(contents)
You can easily pass the file object.
with open('file.txt', 'r') as f: #open the file
contents = function(f) #put the lines to a variable.
and in your function, return the list of lines
def function(file):
lines = []
for line in f:
lines.append(line)
return lines
Another trick, python file objects actually have a method to read the lines of the file. Like this:
with open('file.txt', 'r') as f: #open the file
contents = f.readlines() #put the lines to a variable (list).
With the second method, readlines is like your function. You don't have to call it again.
Update
Here is how you should write your code:
First method:
def function(file):
lines = []
for line in f:
lines.append(line)
return lines
with open('file.txt', 'r') as f: #open the file
contents = function(f) #put the lines to a variable (list).
print(contents)
Second one:
with open('file.txt', 'r') as f: #open the file
contents = f.readlines() #put the lines to a variable (list).
print(contents)
Hope this helps!
Python allows to put multiple open() statements in a single with. You comma-separate them. Your code would then be:
def filter(txt, oldfile, newfile):
'''\
Read a list of names from a file line by line into an output file.
If a line begins with a particular name, insert a string of text
after the name before appending the line to the output file.
'''
with open(newfile, 'w') as outfile, open(oldfile, 'r', encoding='utf-8') as infile:
for line in infile:
if line.startswith(txt):
line = line[0:len(txt)] + ' - Truly a great person!\n'
outfile.write(line)
# input the name you want to check against
text = input('Please enter the name of a great person: ')
letsgo = filter(text,'Spanish', 'Spanish2')
And no, you don't gain anything by putting an explicit return at the end of your function. You can use return to exit early, but you had it at the end, and the function will exit without it. (Of course with functions that return a value, you use the return to specify the value to return.)
def fun(file):
contents = None
with open(file, 'r') as fp:
contents = fp.readlines()
## if you want to eliminate all blank lines uncomment the next line
#contents = [line for line in ''.join(contents).splitlines() if line]
return contents
print fun('test_file.txt')
or you can even modify this, such a way it takes file object as a function arguement as well
Here's a much simpler way of opening a file without defining your own function in Python 3.4:
var=open("A_blank_text_document_you_created","type_of_file")
var.write("what you want to write")
print (var.read()) #this outputs the file contents
var.close() #closing the file
Here are the types of files:
"r": just to read a file
"w": just to write a file
"r+": a special type which allows both reading and writing of the file
For more information see this cheatsheet.
def main():
file=open("chirag.txt","r")
for n in file:
print (n.strip("t"))
file.close()
if __name__== "__main__":
main()
the other method is
with open("chirag.txt","r") as f:
for n in f:
print(n)
I am processing a file line by line. Each line is checked, whether it contains a given text. Then, the next line needs to be assigned to the variable
i_line = iter(file)
for i_line in file:
if text in i_line:
#Go to the next line
line = next(i_line, None) #A problem
break
How to increment iterator i_line so as to point to the next line of the file? Both constructions do not work for me
next(i_line, None)
i_line.next()
Just do next(f).
Something like
>>> with open('testFile.txt', 'r') as f:
for line in f:
if 'cat' in line:
final_string = next(f)
So, for an input text file of
My Name is ABC.
I am a male.
My pet is a cat.
It's name is Ronald.
I hate rats.
The above code gives
>>> final_string
"It's name is Ronald.\n"
Use line = file.next() instead of line = next(i_line, None).
Here's a way of processing a file with next().
with open(filename) as file:
line = next(file, None)
while line:
print(line.strip())
line=next(file, None)
Using both the for line in file iterator and next would print every other line:
with open(filename) as file:
for line in file:
print(line.strip())
line = next(file,None)