I'm trying to take a text file, and when the user presses any key 25 lines of a text file are printed, then when the key is pressed again, then next 25 lines are printed etc.
So far I've got this code:
f = open("lab6text.txt", "r");
print f
for line in f.readlines():
print line,
But no matter what number I put in the:
f.readlines(25):
Every line is still printed. How can I fix this?
Thanks!
The easier way to read files in "chunks" is to use the iter(callable, sentinel) function.
def make_lines_reader(fobj, number_of_lines):
def reader():
return ''.join(fobj.readline() for _ in range(number_of_lines))
return reader
with open('the-file.txt') as f:
for chunk in iter(make_lines_reader(f, 25), ''):
print(chunk, end='')
input() #assuming python3, in python2 use raw_input()
This will print 25 lines from the-file.txt then wait for the user to press enter. Afterwards it will print other 25 lines etc.
readlines does not take the number of lines as an argument. It instead takes a hint, which is the maximum number of bytes/characters to read in. Unless you know the length of each line, this probably won't serve your purposes well.
If you want to print the next 25 lines of a file, you could use a list comprehension, readline, and join:
print "".join([ f.readline() for _ in range(25) ])
In this manner, you wouldn't have to load all the file at once, but just the next 25 lines.
You could nest this (or something similar) inside a while loop to load more lines from the file when the user presses a key.
You could declare a function that prints a maximum of 25 lines and return whether the end of the file were encountered.
def print25lines(f):
for _ in range(25):
line = f.readline()
if line:
print line,
else:
return False
return True
with open('lab6text.txt', 'r') as f:
while print25lines(f):
# Wait user to press enter
raw_input("Press Enter to continue...")
Related
I have a text file with some data in it, and i've written a code that is supposed to delete a specific line when te if statement is true. Why does python delete every line except the first one? And how do i fix it?
def give_back():
number_input = input('What is ur number?')
code_input = input('Enter the code corresponding to your number.')
b = [f'{number_input};{code_input}']
with open('fa_kluizen.txt', 'r') as f:
x = f.readlines()
with open('fa_kluizen.txt', 'w') as f:
for line in x:
if line.strip('\n').strip() != b:
f.write(line)
return True
else:
return False
You have two basic issues. The first is the way you handle your loop:
def give_back():
...
return True # leaves the function `give_back`
Even though you have a for line in x between these two statements, it will only ever run the first loop because you use the keyword return. This leaves the function. If you expect more work to be done, you need to avoid doing this.
Secondly, you are using the read-write flags awkwardly. When you open a file with open('somefile.txt', 'w') it opens for writing, truncating (deleting the contents of) the file first. If you plan to write every line back, that is fine, but since your loop only occurs once, the first line will be all that is in the file when you're done.
You don't say what you want the actual end result to look like with a given input, so it's impossible to say what the correct way to fix this is, but I'd start by getting rid of your return statements and see whether that matches what you're looking for.
You probably meant something like this:
def give_back():
number_input = input('What is ur number?')
code_input = input('Enter the code corresponding to your number.')
b = [f'{number_input};{code_input}']
with open('fa_kluizen.txt', 'r') as f:
x = f.readlines()
with open('fa_kluizen.txt', 'w') as f:
for line in x:
if line.strip('\n').strip() != b:
f.write(line)
The problem is that if u return the function exits
So I am trying to make a game where the 'GameMaster' picks the first word from a .txt file, then the user tries to guess the word. Once the user correctly guess the word, the GameMaster looks to the next line in the file and the user has to guess again, so on and so forth...
The problem I am having, is getting the program to assign variables as the game continues. The program should iteratively look until there are no more words to choose from, whether that be 2 or infinity.
Since I don't have much experience working with file interaction in python, the best example I have is something like this:
file "input.txt" will contain:
dog
cat
bird
rat
mouse
And I am looking at what in in the .txt file with this:
def file_read():
with open ('/Users/someone/Desktop/input.txt', 'r') as myfile:
data = myfile.read()
for line in data:
line.rstrip()
return data
Your function returns the entire contents of the file, unaltered. myfile.read() returns the data from the file as a string. The for loop then iterates over every character in that string, not the lines. Furthermore, rstrip() operates only on each character. It does not affect the contents of data because data is an immutable string and the return value of rstrip() is not stored anywhere.
Something like this would better suit:
def file_read():
with open('/Users/someone/Desktop/input.txt') as myfile:
return [line.rstrip() for line in myfile]
This will return a list of the stripped lines from the file. Your word guessing code would then iterate over the list.
The above will work, however, it is not very efficient if the input file is large because all of the file would be read into memory to construct the list. A better way is to use a generator which yields a stripped line one at a time:
def file_read():
with open('/Users/someone/Desktop/input.txt') as myfile:
for line in myfile:
yield line.rstrip()
Now that function is so simple, it seems pointless to bother with it. Your code could simply be:
with open('/Users/someone/Desktop/input.txt') as myfile:
for line in myfile:
user_guess_word(line.rstrip())
where user_guess_word() is a function that interacts with the user to guess what the word is, and returns once the guess it correct.
This way uses readlines to get file contents in a list line by line. readlines returns a list containing lines.
Now iterate through list to check if user input matches with line content (which is a word in this case).
with open ('/Users/someone/Desktop/input.txt', 'r') as myfile:
words = myfile.readlines()
while x < len(words):
if words[x] == input('Enter word to guess'):
print('Predicted word correctly')
else:
print('Wrong word. Try again')
x -= 1
x += 1
You can do it like,
def fun():
data = open('filename', 'r').readlines()
user_guess, i = None, 0
while i < len(data):
user_guess = input()
if user_guess not None and user_guess == data[i]:
i = i + 1
Please trim() / strip() also while you compare user_guess and data[i]
I'm reading a large text file and I need to read a number from a specific line. The file looks like this:
....
unknown number of lines
....
ABCD
some random stuff
a number I want to read
....
....
I want to read the number from the line that is 2 lines after a "signature" line that's ABCD, which is unique. Right now what I'm doing is:
with open(filename,'r') as f:
for line in f:
if line.rstrip('\n') == 'ABCD':
continue
But the continue only advances the for loop by 1 iteration. So, how can I make it to advance one more iteration to get the line I actually need?
You could explicitly call next on f* (which the for loop usually does for you) and advance the iterator and then call continue:
for line in f:
if line.rstrip('\n') == 'ABCD':
next(f)
continue
print(line)
This will now print:
....
unknown number of lines
....
a number I want to read
....
....
Thereby skipping 'ABCD' and 'some random stuff'.
In the general case where you are certain ABCD is not the final element, this should not cause issues. If you want to be on the safe side, though, you could wrap it in a try - except to catch the StopIteration exception.
* In this case, this works because f is it's own iterator i.e iter(f) is f. In general, this is not the case, for lists the iterator is it's own distinct object list_iterator so advancing it like this will not work.
If you want to stick with this approach then do this:
f = open(filename,'r'):
while f.readline().rstrip('\n') != 'ABCD': # this will advanced the pointer to the ABCD line
continue
f.next() # to skip over the unnecessary stuff
desiredNumber = f.readline() # desired line
I think regex would look a lot better, but if you want something to get the work done, here it is.
If you don't need any information at all from the skipped line, you can advance the file manually by a line before continueing:
with open(filename,'r') as f:
for line in f:
if line.rstrip('\n') == 'ABCD':
next(f) # The next iteration of the for loop will skip a line
continue
If the only thing you need from this file is that one line, there's no need to continue at all. Just skip a line, grab the next line, do whatever you need to do with it, and break out of the for loop, all from within that if block.
I prefer #Jim's use of next(), but another option is to just use a flag:
with open(filename,'r') as f:
skip_line = False
for line in f:
if line.rstrip('\n') == 'ABCD':
skip_line = True
continue
if skip_line == True:
skip_line = False
else:
print(line)
First i need to get the number of lines and so i do :
for line in sys.stdin:
c = c + 1
print("Number of lines:" + str(c))
A = [[] for x in range(0,c)]
print(A)
But then I need to enter again a for line in sys.stdin: because I need to read the input.
It does not work and the second time it is almost as the input was consumed and now is empty.
Save the stdin input in a variable:
lines = sys.stdin.readlines()
Now you can loop over the lines variable as many times as you like.
If you're just counting the lines you don't need a loop at all; you can just say c = len(lines).
You must the save the input if you want to access it multiple times. The first for loop consumes the stream, which is not seekable.
lines = sys.stdin.readlines()
If you're processing each line, you might prefer something like:
results = [foo(i) for i in sys.stdin]
print("Have {} results".format(len(results))
You can also use enumerate to keep a count:
for cnt, line in enumerate(sys.stdin, start=1):
foo(line)
print('Saw {} lines'.format(cnt))
I was just wondering if I can make a simple script that searches for different strings on user input. Let's say I want to search first time for word "apple" and the second time "orange" and to display all the lines where apples and oranges exist. I want first to be indipendent from the second search.
`string = "start"
while string != "end":
string = input('Enter fruit: ')
print("looking for ",string )
for line in f:
if "Started" and string in line:
print("debug")
print(line)`
What this does is works first time and doesn't the second time. I am prompted after the output to enter another fruit but instead of presenting all the lines where the fruit is found it just prompts with another request to enter a fruit.
Assuming you have some line like f = open('BigTextFileFullOfFruit.txt', 'r') above the snippet you posted:
You can only iterate once over a file. You have to call f.seek(0) to go over it again.
This is because f is an iterator and it cannot be consumed more than once. After that it is exhausted and will not yield anymore.
To go around this, you may seek to the beginning to re-iterate or save the contents in a list for reuse.
# Put this inside your outermost loop
string = raw_input("Enter string: ")
f = fp.readline()
while f:
if f.find(string) >= 0 and "Started":
print(f, end=' ')
f = fp.readline()