Curses: Understanding Terminal Functions

Are you ready to learn how to create awesome text-mode programs with Python and curses? This tutorial will give you the basics of using this powerful library to make your terminal screens look like modern masterpieces.

Curses is a set of functions that allow us to manipulate text on a terminal screen without worrying about specifics for each individual terminal type. That means our programs will work great no matter if they’re running on fancy Linux consoles or old-school VT100 terminals!

Let’s start with the classic “Hello World” program:

# Import the curses library, which allows us to manipulate text on a terminal screen
import curses

# Define the main function, which takes in the standard screen as a parameter
def main(stdscr):
    # Clear the screen using the clear() method
    stdscr.clear()
    # Add the string "Hello, world!" to the screen using the addstr() method
    stdscr.addstr("Hello, world!")
    # Update the display using the refresh() method
    stdscr.refresh()

# Run our program with curses handling input and output using the wrapper() method
curses.wrapper(main)

As you can see, this code is pretty straightforward we’re using the `stdscr` object (which stands for “standard screen”) to clear the screen, add some text, and then update the display. But what if we want something a little more complex? Let’s say we want to create a simple calculator that can perform basic arithmetic operations:

# Import the necessary modules
import curses # Module for creating text-based user interfaces
from operator import add, sub, mul, truediv # Module for performing basic arithmetic operations

# Define the main function that takes in the `stdscr` object as a parameter
def main(stdscr):
    stdscr.clear() # Clear the screen
    stdscr.addstr("Welcome to Curses Calculator!") # Add some text to the screen
    stdscr.refresh() # Update the display

    # Create a loop to continuously ask for user input and perform calculations
    while True:
        # Get the first number from the user
        num1 = input_number(stdscr)
        # Get the operator from the user
        op = get_operator(stdscr)
        # If the user does not enter an operator, break out of the loop
        if not op: break
        # Get the second number from the user
        num2 = input_number(stdscr)
        # Use Python's built-in `eval` function to perform the operation
        result = eval("num1 {} num2".format(op))
        stdscr.clear() # Clear the screen again for a fresh start
        # Add some text with the result and wait for input before exiting
        stdscr.addstr("Result: {}\n\nPress any key to exit...".format(result))
        stdscr.refresh() # Update the display

# Function to get the operator from the user
def get_operator(stdscr):
    while True:
        # Get the user's input
        c = stdscr.getch()
        # Check if the input is one of the four basic arithmetic operators
        if c == ord('+'): return add
        elif c == ord('-'): return sub
        elif c == ord('*'): return mul
        elif c == ord('/'): return truediv
        else: continue # Ignore any other input for now

# Function to get a number from the user
def input_number(stdscr):
    while True:
        # Ask the user to enter a number
        stdscr.addstr("Enter a number: ")
        # Get the user's input and limit it to 10 characters (or until they press enter)
        num = stdscr.getnstr(10)
        try:
            # Convert the input to an integer and return it
            return int(num)
        except ValueError:
            continue # Ignore any non-numeric input for now

# Call the main function and pass in the `stdscr` object
curses.wrapper(main)

As you can see, this code is a bit more complex we’re using nested loops and functions to create a calculator that can perform basic arithmetic operations. But with curses handling the input/output, it still looks great on any terminal!

With this library, your boring old terminal programs will become works of art and who knows, maybe even make you some money as a professional designer!

SICORPS