<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Systems From Scratch]]></title><description><![CDATA[Building real software systems and understanding what happens underneath.]]></description><link>https://systemsfromscratch.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Tue, 15 Sep 2026 23:13:42 GMT</lastBuildDate><atom:link href="https://systemsfromscratch.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How to Build an Online Judge, Part 1: Understanding stdin, stdout, stderr, and Exit Codes]]></title><description><![CDATA[An Online Judge performs code execution and tests it against a series of test cases. A running program may require a input and the output of the program must be communicative with the judge service to]]></description><link>https://systemsfromscratch.hashnode.dev/stdin-stdout-stderr-and-exit-codes</link><guid isPermaLink="true">https://systemsfromscratch.hashnode.dev/stdin-stdout-stderr-and-exit-codes</guid><category><![CDATA[Python]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[linux for beginners]]></category><dc:creator><![CDATA[Siddharth Lalwani]]></dc:creator><pubDate>Thu, 10 Sep 2026 16:48:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6aa18d46b0a572581d63313d/f5d67e2d-5af8-46c8-9913-7646c075bac3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>An Online Judge performs code execution and tests it against a series of test cases. A running program may require a input and the output of the program must be communicative with the judge service to declare result , errors or find bugs in the code. This article speaks about how input and output processes work.</p>
<h3>Outcome: Understand the complete communication cycle of a program from input to exit code</h3>
<p>example of a simple program that sums two numbers.</p>
<pre><code class="language-markdown">         PROGRAM
stdin  ───────────► reads two numbers
         adds them
stdout ◄─────────── prints the result
stderr ◄─────────── prints diagnostics

When the program ends → exit code
</code></pre>
<h2>Input/Output Streams and Exit code:</h2>
<h3><strong>1. stdin</strong> - Standard Input</h3>
<p>This is a stream the program can read from. For example,</p>
<pre><code class="language-markdown">4 7
</code></pre>
<p>you might type that into a terminal after running a program file, but <code>stdin</code> can also come from another file or another program.</p>
<p>One precise correction: <strong>not all data supplied to a program is</strong> <code>stdin</code><strong>.</strong> Command-line arguments, such as the filename in <code>python</code> <a href="http://main.py"><code>main.py</code></a>, are a separate input mechanism.</p>
<h3>2. stdout - Standard Output</h3>
<p>This is the stream used for the program’s normal results:</p>
<pre><code class="language-markdown">11
</code></pre>
<p>In Python, <code>print(11)</code> writes to <code>stdout</code> by default.</p>
<p><code>stdout</code> does not inherently mean that display output on a screen. A terminal usually displays it, but it can also be sent to a file or another program.</p>
<h3>3. stderr - The Standard Error</h3>
<p>This is a separate output stream for diagnostics such as:</p>
<pre><code class="language-markdown">Error: expected two numbers.
</code></pre>
<p>Keeping diagnostics separate lets another program consume the actual result without accidentally treating an error message as data.</p>
<p>Your terminal often displays <strong>both</strong> <code>stdout</code> <strong>and</strong> <code>stderr</code>, so they can look like the same stream. They are still separate.</p>
<h3>4. Exit code : How The program Finished</h3>
<p>An exit code is a status value available to the process that launched the program.</p>
<table>
<thead>
<tr>
<th>Situation</th>
<th><code>stdout</code></th>
<th><code>stderr</code></th>
<th>Exit code</th>
</tr>
</thead>
<tbody><tr>
<td>Valid input: <code>4 7</code></td>
<td><code>11</code></td>
<td>Empty</td>
<td><code>0</code></td>
</tr>
<tr>
<td>Invalid input: <code>4 banana</code></td>
<td>Empty</td>
<td><code>Error: expected two numbers.</code></td>
<td><code>1</code></td>
</tr>
</tbody></table>
<p>by convention, <code>0</code> <strong>means success</strong> and <code>non-zero</code> <strong>means failure</strong> or other condition the caller should handle. The exact meaning of non-zero value depend upon the program.</p>
<p><strong>The result and the exit code are independent.</strong> If the sum is <code>11</code>, the program prints <code>11</code> and can still exit with <code>0</code>. The exit code is not the answer to the calculation.</p>
<p>Also, <strong>writing to</strong> <code>stderr</code> <strong>does not automatically mean failure</strong>. A program can print a warning there and still exit successfully.</p>
<h3>Example with Code:</h3>
<pre><code class="language-python">import sys

try:
    #input reads one line from stdin
    a,b = map(int,input().split())
    if b == 0:
        #write to the stderr
        print("Error: cannot divide by zero", file=sys.stderr)
        sys.exit(1)

    print(a / b) #writes the answer to stdout
    sys.exit(0)

except (ValueError, EOFError):
    print("Error: expected two numbers.", file = sys.stderr)
    sys.exit(1) #end the program with exit code 1
</code></pre>
<p>Running the Code:</p>
<pre><code class="language-python">python divide.py 10 5
</code></pre>
<p>Output:</p>
<pre><code class="language-python">2
</code></pre>
<p><code>echo $?</code> prints the <strong>exit code of the most recently executed command</strong> in the shell.</p>
<p>For example:</p>
<pre><code class="language-plaintext">python divide.py
echo $?
</code></pre>
<p>If <a href="http://divide.py"><code>divide.py</code></a> finishes with:</p>
<pre><code class="language-plaintext">sys.exit(0)
</code></pre>
<p>then:</p>
<pre><code class="language-plaintext">echo $?
</code></pre>
<p>prints:</p>
<pre><code class="language-plaintext">0
</code></pre>
<p>That means the previous command completed successfully.</p>
<p>If the script finishes with:</p>
<pre><code class="language-plaintext">sys.exit(1)
</code></pre>
<p>then:</p>
<pre><code class="language-plaintext">echo $?
</code></pre>
<p>prints:</p>
<pre><code class="language-plaintext">1
</code></pre>
<p>Explanation and Intuition :<br />The program expects the user or another process to provide two integers as input. For example:</p>
<pre><code class="language-plaintext">10 2
</code></pre>
<h3>Reading from stdin</h3>
<p>The following line reads the input:</p>
<pre><code class="language-plaintext">a, b = map(int, input().split())
</code></pre>
<p>Python's <code>input()</code> function reads one line from <strong>standard input</strong>, commonly called <code>stdin</code>.</p>
<p>If the input is:</p>
<pre><code class="language-plaintext">10 2
</code></pre>
<p>then:</p>
<pre><code class="language-plaintext">input()
</code></pre>
<p>initially gives us the string:</p>
<pre><code class="language-plaintext">"10 2"
</code></pre>
<p>Calling <code>.split()</code> separates it into:</p>
<pre><code class="language-plaintext">["10", "2"]
</code></pre>
<p>Finally, <code>map(int, ...)</code> converts both strings into integers:</p>
<pre><code class="language-plaintext">a = 10
b = 2
</code></pre>
<p>This becomes especially important when we later run the program using <code>subprocess</code>. Instead of a human typing into the terminal, the parent process can send data directly to the child program's <code>stdin</code>.</p>
<h3>Writing normal output to stdout</h3>
<p>If the input is valid and <code>b</code> is not zero, the program performs the division:</p>
<pre><code class="language-plaintext">print(a / b)
</code></pre>
<p>By default, Python's <code>print()</code> writes to <strong>standard output</strong>, or <code>stdout</code> which can be seen in the terminal.</p>
<p>For example:</p>
<pre><code class="language-plaintext">Input:
10 2

stdout:
5.0
</code></pre>
<p>When we execute this program through <code>subprocess</code>, we can capture this output and use it elsewhere in our application but until then it appears in the terminal.</p>
<h3>Writing errors to stderr</h3>
<p>Now consider:</p>
<pre><code class="language-plaintext">if b == 0:
    print("Error: cannot divide by zero", file=sys.stderr)
    sys.exit(1)
</code></pre>
<p>Division by zero is not a valid operation, so instead of writing the message to normal output, we explicitly send it to <strong>standard error</strong>, or <code>stderr</code>.</p>
<p>The important part is:</p>
<pre><code class="language-plaintext">file=sys.stderr
</code></pre>
<p>Without it, <code>print()</code> would write to <code>stdout</code>.Despite its name, it doesn’t have to refer to a file on disk; it can be an output stream.</p>
<p>For example:</p>
<pre><code class="language-plaintext">Input:
10 0

stdout:
&lt;empty&gt;

stderr:
Error: cannot divide by zero
</code></pre>
<p>Keeping <code>stdout</code> and <code>stderr</code> separate is extremely useful when building systems such as an online judge.</p>
<p>A contestant's actual program output belongs in <code>stdout</code>, while compilation errors, runtime errors, or diagnostic messages can be captured separately through <code>stderr</code>.</p>
<h3>Exit codes</h3>
<p>Programs also return an <strong>exit code</strong> when they terminate.</p>
<p>By convention:</p>
<pre><code class="language-plaintext">sys.exit(0)
</code></pre>
<p>means:</p>
<pre><code class="language-plaintext">The program completed successfully.
</code></pre>
<p>while:</p>
<pre><code class="language-plaintext">sys.exit(1)
</code></pre>
<p>indicates that something went wrong.</p>
<p>The exact meaning of non-zero exit codes depends on the application, but the general convention is:</p>
<pre><code class="language-plaintext">0       → success
non-zero → failure/error
</code></pre>
<p>This gives the parent process another way of determining whether execution succeeded.</p>
<p>For example, valid input:</p>
<pre><code class="language-plaintext">10 2
</code></pre>
<p>produces:</p>
<pre><code class="language-plaintext">stdout = "5.0"
stderr = ""
exit code = 0
</code></pre>
<p>But division by zero:</p>
<pre><code class="language-plaintext">10 0
</code></pre>
<p>produces:</p>
<pre><code class="language-plaintext">stdout = ""
stderr = "Error: cannot divide by zero"
exit code = 1
</code></pre>
<h3>Handling malformed input</h3>
<p>The entire input-processing logic is wrapped inside:</p>
<pre><code class="language-plaintext">try:
</code></pre>
<p>with:</p>
<pre><code class="language-plaintext">except (ValueError, EOFError):
</code></pre>
<p>This protects the program against invalid input.</p>
<p>A <code>ValueError</code> can occur if the supplied values cannot be converted into integers.</p>
<p>For example:</p>
<pre><code class="language-plaintext">hello 10
</code></pre>
<p>would cause:</p>
<pre><code class="language-plaintext">int("hello")
</code></pre>
<p>to fail.</p>
<p>An <code>EOFError</code> can occur when the program expects input but reaches the end of the input stream without receiving anything.</p>
<p>In either case, the program writes:</p>
<pre><code class="language-plaintext">Error: expected two numbers.
</code></pre>
<p>to <code>stderr</code> and terminates with exit code <code>1</code>.</p>
<h3>Why this example matters for subprocesses</h3>
<p>When one program launches another program, there are four important communication channels to think about:</p>
<pre><code class="language-plaintext">Parent Process
      |
      | stdin
      v
Child Process
      |
      +---- stdout
      |
      +---- stderr
      |
      +---- exit code
</code></pre>
<p><code>stdin</code> carries data <strong>into</strong> the child process.</p>
<p><code>stdout</code> carries the program's normal result <strong>out</strong>.</p>
<p><code>stderr</code> carries error messages and diagnostics <strong>out</strong>.</p>
<p>The exit code tells the parent process whether execution succeeded or failed.</p>
<p>This small division program gives us a simple program to test with <code>subprocess</code>.</p>
<p>Later, we can write another Python program that launches this file, sends input to it, reads its output, captures any errors, and checks whether it exited successfully.</p>
<p>This is similar to what an online judge does when it runs a user's submitted code against test cases.</p>
<p>The next article would be about <strong>subprocesses</strong> in python and how are they used to execute programs in different python files.</p>
]]></content:encoded></item></channel></rss>