Understanding Command Line Interfaces (CLI)
A Command Line Interface (CLI) is a user interface that allows users to interact with a computer program using commands entered through a text-based interface. In this post, we will explore what a CLI is, why it’s important, and how to create a CLI application using the argparse
library in Python.
What is a Command Line Interface (CLI)?
A CLI is a text-based interface that allows users to interact with a computer program by entering commands / parameters. The user executes the application following by one or more command(s) / argument(s), and the computer performs the corresponding operation. CLI is commonly used in software development, system administration, and data analysis.
When we use our terminal emulator / power shell, we run command line applications and interact with those using command line arguments. For example:
cd /home/user/Downloads # Change Directory and go to the Downloads folder
ls *.csv # List all the files having the extension .csv
Why is a Command Line Application Important?
CLI is essential for running applications on servers without a window manager. In this environment, a user cannot interact with the application through a graphical interface. Instead, they use the command line to interact with the program. CLI is also useful for automating tasks and running scripts. By executing a script from the command line, users can quickly execute complex tasks without the need for a graphical interface.
It is also pretty easy to implement a Command Line Application. When the parameters that affect the application are limited, it makes more sense to configure the execution parameters using command line arguments or a configuration file rather than implementing a user interface with only a couple of options.
The free fall example
Let’s assume that we have been assigned the task to implement a solution to the following problem:
We let metallic spheres fall from various heights in a vacuum tube. Each time we want to predict the duration of the fall, how long would it take the sphere to reach the ground.
In physics the height of the sphere at any given moment is given by the formula:
$$ h = h_0 - \frac{1}{2}\cdot g \cdot t^2 $$ $$ h: \text{height in } m $$ $$ h_0: \text{the initial height in } m $$ $$ g: \text{gravity acceleration in } m/s^2 $$ $$ t: \text{time in } sec $$
We know that $g$ is approximately $9.81 m / s^2$ on the surface of the Earth.
Given that we want the time when the height is $0m$ we want to solve the equation:
$$ t = \sqrt{\frac{2 \cdot h_0}{g}} $$
So, we need an application that can compute $t$ given the acceleration due to gravity ($g$) and the initial height $h_0$.
Implementing Command Line Application in Python
First, let’s create a function that solves the problem:
from math import sqrt
def solveFreeFall(initial_height: float, g_acceleration: float = 9.81) -> float:
return sqrt(2 * initial_height / g_acceleration)
Let’s call this function in a script file, by passing the value $h_0 = 10$ to test if it works:
# freefall.py
from math import sqrt
def solveFreeFall(initial_height: float, g_acceleration: float = 9.81) -> float:
return sqrt(2 * initial_height / g_acceleration)
if __name__ == "__main__":
solution = solveFreeFall(10)
print(f"The fall duration is {solution:.2f} seconds")
By running this script we get:
$ python3 freefall.py
The fall duration is 1.43 seconds
But we need the user to be able to define the initial height $h_0$ and optionally the acceleration $g$, since it is different on other locations, altitudes, planets, …
The argparse
library in Python provides a straightforward way to create command-line interfaces. For more details you can read the Documentation.
Here’s how we will use it for our case:
- Import the library and create the parser object. Here we define the application name, a description of the application and an epilog for the bottom of the help text that will be automatically generated.
import argparse
parser = argparse.ArgumentParser(
prog='example', # This is the application name
description='Define the initial height and optionally the gravity acceleration to get the fall duration',
epilog='This is based on Newtonian physics and ignores air resistance.')
- We define the options to be expected. We set the initial height to be required while the acceleration to be optional and default to 9.81. Both are of type float:
parser.add_argument('-h0', '--height', type=float, required=True,
help='The initial height in meters')
parser.add_argument('-g', '--acceleration', type=float, default=9.81,
help='The acceleration due to gravity (default: 9.81)')
- Finally, we parse the arguments and get the respective data provided:
args = parser.parse_args()
Let’s put it all together and check the results as well as the generated help:
# example.py
import argparse
parser = argparse.ArgumentParser(
prog='example',
description='Define the initial height and optionally the gravity acceleration to get the fall duration',
epilog='This is based on Newtonian physics and ignores air resistance.')
parser.add_argument('-h0', '--height', type=float, required=True,
help='The initial height in meters')
parser.add_argument('-g', '--acceleration', type=float, default=9.81,
help='The acceleration due to gravity (default: 9.81)')
args = parser.parse_args()
print(f"The given options are: h0: {args.height}, g: {args.acceleration}")
To get the application help we use the -h or –help option:
$ python3 example.py --help
Which yields:
usage: example [-h] -h0 HEIGHT [-g ACCELERATION]
Define the initial height and optionally the gravity acceleration to get the fall duration
options:
-h, --help show this help message and exit
-h0 HEIGHT, --height HEIGHT
The initial height in meters
-g ACCELERATION, --acceleration ACCELERATION
The acceleration due to gravity (default: 9.81)
This is based on Newtonian physics and ignores air resistance.
Let’s see if we get the provided data correctly, by calling the application with height = 10:
$ python3 example.py -h0 10
The given options are: h0: 10.0, g: 9.81
Now, it is time to bring it all together and make our solver ready to be delivered:
# freefall.py
import argparse
from math import sqrt
def solveFreeFall(initial_height: float, g_acceleration: float = 9.81) -> float:
return sqrt(2 * initial_height / g_acceleration)
if __name__ == "__main__":
parser = argparse.ArgumentParser(
prog='freefall',
description='Define the initial height and optionally the gravity acceleration to get the fall duration',
epilog='This is based on Newtonian physics and ignores air resistance.')
parser.add_argument('-h0', '--height', type=float, required=True,
help='The initial height in meters')
parser.add_argument('-g', '--acceleration', type=float, default=9.81,
help='The acceleration due to gravity (default: 9.81)')
args = parser.parse_args()
solution = solveFreeFall(args.height, args.acceleration)
print(f"The fall duration is {solution:.2f} seconds")
Testing the help message:
$ python3 freefall.py --help
usage: freefall [-h] -h0 HEIGHT [-g ACCELERATION]
Define the initial height and optionally the gravity acceleration to get the fall duration
options:
-h, --help show this help message and exit
-h0 HEIGHT, --height HEIGHT
The initial height in meters
-g ACCELERATION, --acceleration ACCELERATION
The acceleration due to gravity (default: 9.81)
This is based on Newtonian physics and ignores air resistance.
Testing for $h_0 = 0, 10, 20, 100$:
$ python3 freefall.py -h0 0
The fall duration is 0.00 seconds
$ python3 freefall.py -h0 10
The fall duration is 1.43 seconds
$ python3 freefall.py -h0 20
The fall duration is 2.02 seconds
$ python3 freefall.py -h0 100
The fall duration is 4.52 seconds
Testing for $h_0 = 0, 10, 20, 100$ if $g = 1.62 m/s^2$ (on moon):
$ python3 freefall.py -g 1.62 -h0 0
The fall duration is 0.00 seconds
$ python3 freefall.py -g 1.62 -h0 10
The fall duration is 3.51 seconds
$ python3 freefall.py -g 1.62 -h0 20
The fall duration is 4.97 seconds
$ python3 freefall.py -g 1.62 -h0 100
The fall duration is 11.11 seconds
Conclusion
When we develop a software solution for a potential customer, it has to be flexible both for the customer and our future use cases. By having hardcoded numbers that restrict our solution for only specific case(s), leads to need of customer support and constant updates. By making our application as flexible as possible, we can solve our customer problems by delivering a documentation and use the solution for other cases.
CLI is an essential tool for software development, system administration, and data analysis. It allows developers to build flexible applications and users to interact with those through a text-based interface, making it ideal for running programs on servers without a graphical interface. By using the argparse
library in Python, developers can quickly create command-line interfaces for their applications. The flexibility and power of CLI make it an indispensable tool for any developer.