I came across this problem in UVa OJ. 272-Text Quotes
Well, the problem is quite trivial. But the thing is I am not able to read the input. The input is provided in the form of text lines and end of input is indicated by EOF.
In C/C++ this can be done by running a while loop:
while( scanf("%s",&s)!=EOF ) { //do something }
How can this be done in python .?
I have searched the web but I did not find any satisfactory answer.
Note that the input must be read from the console and not from a file.
You can use sys module:
import sys
complete_input = sys.stdin.read()
sys.stdin is a file like object that you can treat like a Python File object.
From the documentation:
Help on built-in function read:
read(size=-1, /) method of _io.TextIOWrapper instance
Read at most n characters from stream.
Read from underlying buffer until we have n characters or we hit EOF.
If n is negative or omitted, read until EOF.
You can read input from console till the end of file using sys and os module in python. I have used these methods in online judges like SPOJ several times.
First method (recommened):
from sys import stdin
for line in stdin:
if line == '': # If empty string is read then stop the loop
break
process(line) # perform some operation(s) on given string
Note that there will be an end-line character \n at the end of every line you read. If you want to avoid printing 2 end-line characters while printing line use print(line, end='').
Second method:
import os
# here 0 and 10**6 represents starting point and end point in bytes.
lines = os.read(0, 10**6).strip().splitlines()
for x in lines:
line = x.decode('utf-8') # convert bytes-like object to string
print(line)
This method does not work on all online judges but it is the fastest way to read input from a file or console.
Third method:
while True:
line = input()
if line == '':
break
process(line)
replace input() with raw_input() if you're still using python 2.
For HackerRank and HackerEarth platform below implementation is preferred:
while True:
try :
line = input()
...
except EOFError:
break;
This how you can do it :
while True:
try :
line = input()
...
except EOFError:
pass
If you need to read one character on the keyboard at a time, you can see an implementation of getch in Python: Python read a single character from the user
Related
My Python program uses keyphrase = sys.stdin.readlines() to take user input. Once complete the user must press Command+D to continue with program execution. The particular text that the user will be inputting will be pasted into the terminal. Is it possible to change from Command+D to Enter? If so, how?
fileinput might be the right choice here.
It's a little hacky, but fileinput.input() without any arguments calls sys.stdin.readlines() and gives us a context-manager which we can use to parse the inputs separately.
import fileinput
var = ""
with fileinput.input() as F:
for line in F:
if line == "\n":
F.close()
else:
var += line
print(var)
Inside of the for-loop we are reading the latest input-value, which means that we can parse the given input, and then make a decision for how to proceed.
sys.stdin.readlines() standardizes the newlines that it is given, which means that we can expect that an empty line (enter press) will return '\n'. If that is true, then we close the stream.
This question already has answers here:
How to read user input until EOF?
(4 answers)
Closed 5 years ago.
I am working on a programming assignment, and the directions specify:
"Your program should terminate when it reaches the end of the input file, or the end-of-file on stdin (when control-D is typed from the keyboard under Linux)."
This is what I have so far:
userInput = rawInput()
while userInput != "":
#other stuff the program will do
This is my first time programming in python, and I am using pycharm editor. I am a little confused if this works. Normally in java I would check if userInput is null, but it seems like python doesnt have null objects? Also, does this account for the part in the instructions that says "when control-D is typed from the keyboard under Linux)."?
Since I'm using pyCharm to edit and run my file before turning it in, how do I test to simulate when control-D is typed from the keyboard under Linux" ?
For performing operations till EOF , see my example code below. The outer for loop iterates till the last line, or you can say, the End-Of-File.
infile = open('input.txt','r')
lines = infile.readlines()
whitespace_count=0
for data in lines:
#do your stuff here, for example here i'm counting whitespaces in input file
for character in data:
if character.isspace():
whitespace_count +=1
print whitespace_count
And, when you need to do your work directly from STDIN, consider the following code below, here sys.stdin acts just like reading an input file. After you have entered enough input, tap CTRL+D till program exits
import sys
for line in sys.stdin:
for data in line:
for character in data:
if character.isspace():
whitespace_count +=1
print whitespace_count
first terminating the program when it reaches end of file.
open the file using open()
fp=open("sample.txt","r")
read the lines using for loop
for l in fp:
print the lines
fp=open("sample.txt","r")
for l in fp:
print (l,end='')
if you are working with python2.7
fp=open("sample.txt","r")
for l in fp:
print l
Now we can use exception handling to terminate the input when crtl+D is pressed in stdin.here i am specifying the sample program
try:
str1=raw_input("Enter the String :")
print "Given String :",str1
except:
print "User typed ctrl+d"
I get how to open files, and then use Python's pre built in functions with them. But how does sys.stdin work?
for something in sys.stdin:
some stuff here
lines = sys.stdin.readlines()
What's the difference between the above two different uses on sys.stdin? Where is it reading the information from? Is it via keyboard, or do we still have to provide a file?
So you have used Python's "pre built in functions", presumably like this:
file_object = open('filename')
for something in file_object:
some stuff here
This reads the file by invoking an iterator on the file object which happens to return the next line from the file.
You could instead use:
file_object = open('filename')
lines = file_object.readlines()
which reads the lines from the current file position into a list.
Now, sys.stdin is just another file object, which happens to be opened by Python before your program starts. What you do with that file object is up to you, but it is not really any different to any other file object, its just that you don't need an open.
for something in sys.stdin:
some stuff here
will iterate through standard input until end-of-file is reached. And so will this:
lines = sys.stdin.readlines()
Your first question is really about different ways of using a file object.
Second, where is it reading from? It is reading from file descriptor 0 (zero). On Windows it is file handle 0 (zero). File descriptor/handle 0 is connected to the console or tty by default, so in effect it is reading from the keyboard. However it can be redirected, often by a shell (like bash or cmd.exe) using syntax like this:
myprog.py < input_file.txt
That alters file descriptor zero to read a file instead of the keyboard. On UNIX or Linux this uses the underlying call dup2(). Read your shell documentation for more information about redirection (or maybe man dup2 if you are brave).
It is reading from the standard input - and it should be provided by the keyboard in the form of stream data.
It is not required to provide a file, however you can use redirection to use a file as standard input.
In Python, the readlines() method reads the entire stream, and then splits it up at the newline character and creates a list of each line.
lines = sys.stdin.readlines()
The above creates a list called lines, where each element will be a line (as determined by the end of line character).
You can read more about this at the input and output section of the Python tutorial.
If you want to prompt the user for input, use the input() method (in Python 2, use raw_input()):
user_input = input('Please enter something: ')
print('You entered: {}'.format(user_input))
To get a grasp how sys.stdin works do following:
create a simple python script, let's name it "readStdin.py":
import sys
lines = sys.stdin.readlines()
print (lines)
Now open console any type in:
echo "line1 line2 line3" | python readStdin.py
The script outputs:
['"line1 line2 line3" \n']
So, the script has read the input into list (named 'lines'), including the new line character produced by 'echo'. That is.
According to me sys.stdin.read() method accepts a line as the input from the user until a special character like Enter Key and followed by Ctrl + D and then stores the input as the string.
Control + D works as the stop signal.
Example:
import sys
input = sys.stdin.read()
print(input)
tokens = input.split()
a = int(tokens[0])
b = int(tokens[1])
print(a + b)
After running the program enter two numbers delimited by space and after finishing press Control + D once or twice and you will be presented by the sum of the two inputs.
for something in sys.stdin:
some stuff here
The code above does not work as you expect because sys.stdin is a file handle - it is a file handle to the stdin. It will not reach the some stuff here line
lines = sys.stdin.readlines()
When the script above is run in an interactive shell, it will block the execution until a user presses Ctrl-D, which indicates the end of the input.
It will read the source file line by line. It is widely used in Online Judge System.
For example: suppose we have only one number 2 will be used in the file.
import sys
if __name__ == "__main__":
n = int(sys.stdin.readline().strip())
Read the file line by line means read the number 2 (only one line in this case). Using the strip to remove unneeded space or other specified characters. This will result in n = (integer) 2.
If we have a file with two lines like:
1
2
Then, sys.stdin.readline().strip() will transform it to one line (a list, named n) with two elements 1, 2. Then we cannot use int transformer now but we can use int(n[0]) and int(n[1]) instead.
This question already has answers here:
How to read user input until EOF?
(4 answers)
Closed 6 months ago.
To read some text file, in C or Pascal, I always use the following snippets to read the data until EOF:
while not eof do begin
readline(a);
do_something;
end;
Thus, I wonder how can I do this simple and fast in Python?
Loop over the file to read lines:
with open('somefile') as openfileobject:
for line in openfileobject:
do_something()
File objects are iterable and yield lines until EOF. Using the file object as an iterable uses a buffer to ensure performant reads.
You can do the same with the stdin (no need to use raw_input():
import sys
for line in sys.stdin:
do_something()
To complete the picture, binary reads can be done with:
from functools import partial
with open('somefile', 'rb') as openfileobject:
for chunk in iter(partial(openfileobject.read, 1024), b''):
do_something()
where chunk will contain up to 1024 bytes at a time from the file, and iteration stops when openfileobject.read(1024) starts returning empty byte strings.
You can imitate the C idiom in Python.
To read a buffer up to max_size (>0) number of bytes, you can do this:
with open(filename, 'rb') as f:
while True:
buf = f.read(max_size)
if buf == 0:
break
process(buf)
Or, a text file line by line:
# warning -- not idiomatic Python! See below...
with open(filename, 'rb') as f:
while True:
line = f.readline()
if not line:
break
process(line)
You need to use while True / break construct since there is no eof test in Python other than the lack of bytes returned from a read.
In C, you might have:
while ((ch != '\n') && (ch != EOF)) {
// read the next ch and add to a buffer
// ..
}
However, you cannot have this in Python:
while (line = f.readline()):
# syntax error
because assignments are not allowed in expressions in Python (although recent versions of Python can mimic this using assignment expressions, see below).
It is certainly more idiomatic in Python to do this:
# THIS IS IDIOMATIC Python. Do this:
with open('somefile') as f:
for line in f:
process(line)
Update: Since Python 3.8 you may also use assignment expressions:
while line := f.readline():
process(line)
That works even if the line read is blank and continues until EOF.
The Python idiom for opening a file and reading it line-by-line is:
with open('filename') as f:
for line in f:
do_something(line)
The file will be automatically closed at the end of the above code (the with construct takes care of that).
Finally, it is worth noting that line will preserve the trailing newline. This can be easily removed using:
line = line.rstrip()
You can use below code snippet to read line by line, till end of file
line = obj.readline()
while(line != ''):
# Do Something
line = obj.readline()
While there are suggestions above for "doing it the python way", if one wants to really have a logic based on EOF, then I suppose using exception handling is the way to do it --
try:
line = raw_input()
... whatever needs to be done incase of no EOF ...
except EOFError:
... whatever needs to be done incase of EOF ...
Example:
$ echo test | python -c "while True: print raw_input()"
test
Traceback (most recent call last):
File "<string>", line 1, in <module>
EOFError: EOF when reading a line
Or press Ctrl-Z at a raw_input() prompt (Windows, Ctrl-Z Linux)
In addition to #dawg's great answer, the equivalent solution using walrus operator (Python >= 3.8):
with open(filename, 'rb') as f:
while buf := f.read(max_size):
process(buf)
You can use the following code snippet. readlines() reads in the whole file at once and splits it by line.
line = obj.readlines()
How about this! Make it simple!
for line in open('myfile.txt', 'r'):
print(line)
No need to waste extra lines. And no need to use with keyword because the file will be automatically closed when there is no reference of the file object.
I've made a code to read a binary file as follows :
file=open('myfile.chn','rb')
i=0
for x in file:
i=i+1
print(x)
file.close()
and the result as follows (a part of it) : b'\x00\x00\x80?\x00\x00\x00\x005.xx\x00S\xd4\n'
How can i detect the EOF of this binary file? Let say i want to print() after i find the EOF. I tried this, but nothing happened.
if (x=='\n'):
print()
(updated)
#aix: let say that the file have few lines of results,just like the example, each line has '\n' at the end and i want put a space between each line.
b'\x00\x00\x80?\x00\x00\x00\x005.xx\x00S\xd4\n'
b'\x82\x93p\x05\xf6\x8c4S\x00\x00\xaf\x07j\n'
How can i do this?
Once your reach the EOF, the for x in file: loop will terminate.
with open('myfile.chn', 'rb') as f:
i = 0
for x in f:
i += 1
print(x)
print('reached the EOF')
I've renamed the file variable so that it doesn't shadow the built-in.
NPE's answer is correct, but I feel some additional clarification is necessary.
You tried to detect EOF using something like
if (x=='\n'):
...
so probably you are confused the same way I was confused until today.
EOF is NOT a character or byte. It's NOT a value that exists in the end of a file and it's not something which could exist in the middle of some (even binary) file. In C world EOF has some value, but even there it's value is different from the value of any char (and even it's type is not 'char'). But in python world EOF means "end of file reached". Python help to 'read' function says "... reads and returns all data until EOF" and that does not mean "until EOF byte is found". It means "until file is over".
Deeper explanation of what is and what is not a 'EOF' is here:
http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1048865140&id=1043284351