Can't use `print` to debug in python

Although the starter template claims that “[we] can use print statements as follows for debugging”, it does not work currently, because it interferes with the output of our shell.

# You can use print statements as follows for debugging, they'll be visible when running tests.
print("Logs from your program will appear here!")

I’ve tried to redirect to sys.stderr (as Google Code Jam did to differentiate between normal output and debugging). But the tester did not seem to make the distinction between sys.stdout and sys.stderr:

print("Logs from your program will appear here!", file=sys.stderr)

EDIT: Somehow sys.stderr works for some of the later stages, but not for some of the others:

:white_check_mark: #CZ2 (Handle missing commands)
:white_check_mark: #FF0 (REPL)
:x: #PN5 (The exit builtin)
:white_check_mark: #IZ3 (The echo builtin)
:white_check_mark: #EZ5 (The type builtin: builtins)
:x: #MG5 (The type builtin: executable files)
:question:Haven’t advanced to #IP1 (Run a program) yet

print("debug", file=sys.stderr)

Ah, this is a bit of a tricky one.

Printing to stderr works for most other challenges because we’re only checking stdout. For testing a shell, we had to use a pseudoterminal (pty), and the way a pseudoterminal works it that stdout and stderr are seen as a single stream.

I’m guessing the reason print works in some stages is that our assertions aren’t strict enough there. We’ll fix those cases. In the meantime if anyone has ideas on how to make debug logs work here, open to ideas!

For context, things we briefly considered:

  • Write to an external file (/tmp/debug for example) and surface that as output
  • Hand the program another file descriptor (stdin, stdout & stderr are the defaults , we could provide fd #4) and surface that as output
  • Add a special debug syntax, something like (“::debug::”) which’ll get filtered from all checks

None of these felt very user-friendly or straightforward :confused:

1 Like

You could also implement (or co-opt) a logging library, like python’s logging module or the like. Most modern languages have them, and most “production” projects I’ve been on in the RealWorld[TM] use them exclusively (to allow for analytics, or logging levels to be changed at runtime, etc).

That would make it a lot easier for you to distinguish what output is intended to go where.

It’s not a bad habit to teach your students to get into, either.

-Carl [from youtube/{at}InternetOfBugs]

1 Like

Good idea! Bit worried about the educational aspect of this - everyone’s familiar with printf debugging so that feels natural. I like the fact that this’ll allow log-level to be controlled, so you can keep the debug logs and have them only print when debug mode is turned on.