9

I am new to python and trying some coding problems online. i come across sys.sdnin a lot for accepting input. I would like to know how input() and sys.stdin differs in action?

raj
  • 5,989
  • 7
  • 30
  • 62
  • 4
    What's unclear in the documentation? – BartoszKP Apr 08 '15 at 23:23
  • 3
    difference between sys.stdin and input() – raj Apr 10 '15 at 15:30
  • Clearly there are lots of differences, because they are two completely different things, you can see that with just a glance at the docs, not saying anything about actually reading it. So, instead of repeating your extremely vague question (yes, we can read), please explain more precisely what do you find confusing. – BartoszKP Apr 10 '15 at 15:36
  • 3
    This question is interesting. It aims at understanding the full difference between `input()` and `sys.stdin`, how they differ, and why the one or the other are used for exactly the same thing (reading data) in different programming competitions such as Codingame, HackerRank, Battle Dev. This is something that is definitely not mentioned in the documentation, and that I too would like to see clarified. – kotchwane Nov 28 '20 at 08:29

2 Answers2

4

Clarification through Code Examples

I've been asking myself the same question, so I came up with these two snippets, which clarify how sys.stdin and input() differ by emulating the latter with the former:

import sys

def my_input(prompt=''):
  print(prompt, end='') # prompt with no newline
  for line in sys.stdin:
    if '\n' in line: # We want to read only the first line and stop there
      break
  return line.rstrip('\n')

Here is a more condensed version:

import sys

def my_input(prompt=''):
  print(prompt, end='')
  return sys.stdin.readline().rstrip('\n')

Both these snippets differ from the input() function in that they do not detect the End Of File (see below).

Clarification through Documentation

This is how the official documentation describes the function input():

input([prompt])

If the prompt argument is present, it is written to standard output without a trailing newline. The function then reads a line from input, converts it to a string (stripping a trailing newline), and returns that. When EOF is read, EOFError is raised.

And here's how sys.stdin is described:

sys.stdin

File object used by the interpreter for standard input.
stdin is used for all interactive input (including calls to input());
These streams (sys.stdin, sys.stdout and sys.stderr) are regular text files like those returned by the open() function. [...]

So whereas input() is a function, sys.stdin is an object (a File object). As such, it has a number of attributes, which you can explore in the interpreter, with:

> dir(sys.stdin)

['_CHUNK_SIZE',
 '__class__',
 '__del__',
 '__delattr__',
 '__dict__',
 '__dir__',

  ...

 'truncate',
 'writable',
 'write',
 'write_through',
 'writelines']

and which you can display individually, for instance:

> sys.stdin.mode
r

It also has methods, such as readline(), which "reads a single line from the file; a newline character (\n) is left at the end of the string, and is only omitted on the last line of the file if the file doesn’t end in a newline. This makes the return value unambiguous; if f.readline() returns an empty string, the end of the file has been reached, while a blank line is represented by '\n', a string containing only a single newline." (1)

Full implementation

This last method allows us to fully emulate the input() function, including its EOF Exception error:

def my_input(prompt=''):
  print(prompt, end='')
  line = sys.stdin.readline()
  if line == '': # readline() returns an empty string only if EOF has been reached
    raise EOFError('EOF when reading a line')
  else:
    return line.rstrip('\n')
kotchwane
  • 2,082
  • 1
  • 19
  • 24
1

Here's something to get you started:

The builtin function input reads a line of input from the standard input stream, optionally with a message prompt. Be careful with the prompt, though, because the result of:

result = input('Do you want to do whatever? ')  ## doesn't work how you'd expect
if result.lower() in ('y', 'ye', 'yes', 'yup', 'ya'):
    do_whatever()
    ...
else:
    do_something_else()
    ...

..will include the prompt string as well (and so will never be equal to 'y'/'yes'/etc). In my opinion, it is better to print the prompt string first and then call input with no args, like so:

print('Do you want to do whatever?')
result = input()  ## notice that there is no prompt string passed to input()
if result.lower() in ('y', 'ye', 'yes', 'yup', 'ya'):
    do_whatever()
    ...
else:
    do_something_else()
    ...

So, to recap, the builtin function input reads input from the standard input stream (sys.stdin), and the builtin function print prints output to the standard output stream (sys.stdout). There's a third one as well, the standard error stream (sys.stderr), to which unhandled exceptions get printed.

Usually, you don't have to worry about it too much. It's just when building IDEs and frameworks and such.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Inversus
  • 3,125
  • 4
  • 32
  • 37
  • 6
    "*will include the prompt string as well*" <- I'm not sure what you mean here, if I test this with something like `x = input('here');print(x)` I don't get 'here' output to the interpreter unless that's what I enter at the prompt. Whereas the way I'm reading what you've written I should infact get the output of 'here' as well as whatever I enter... cheers – baxx Nov 07 '15 at 16:19
  • 1
    -1. This is not a barrage of downvotes on your answer. It's just the fact that this answer is **not** correct. The prompt never gets included into what the function `input()` returns. – kotchwane Nov 28 '20 at 08:15
  • if I test this with something like x = input('here');print(x) I don't get 'here' output to the interpreter unless that's what I enter at the prompt. Whereas the way I'm reading what you've written I should infact get the output of 'here' as well as whatever I enter... cheers – pippo1980 Aug 21 '21 at 15:09