How to Write Interactive Python Scripts

[This article was first published on Python – Predictive Hacks, and kindly contributed to python-bloggers]. (You can report issue about the content on this page here)
Want to share your content on python-bloggers? click here.

Examples of how you can write scripts taking input from users and/or standard input

Functions With Users Input In Python

Below we show an example of how you can build a function that interacts with users by asking their input. We will build the function which returns the Body Mass Index (BMI) by being able to take as input both metric and imperial system. Let’s do it. The bmi.py file is the following:

def gather_info():
    height = float(input("What is your height? (inches or meters) "))
    weight = float(input("What is your weight? (pounds or kilograms) "))
    system = input("Are your measurements in metric or imperial systems? ").lower().strip()
    return (height, weight, system)
def calculate_bmi(weight, height, system='metric'):
    if system == 'metric':
        bmi = (weight / (height ** 2))
    else:
        bmi = 703 * (weight / (height ** 2))
    return bmi
while True:
    height, weight, system = gather_info()
    if system.startswith('i'):
        bmi = calculate_bmi(weight, system='imperial', height=height)
        print(f"Your BMI is {bmi}")
        break
    elif system.startswith('m'):
        bmi = calculate_bmi(weight, height)
        print(f"Your BMI is {bmi}")
        break
    else:
        print("Error: Unknown measurement system. Please use imperial or metric.")

We will give as input:

  • Height: 1.72m
  • Weight: 64kg
  • Measurement: metric

And we get BMI 21.63

How to Write Interactive Python Scripts 1

Working With Environment Variables In Python

Instead of asking users from passwords etc, a common way to configure scripts is to use environment variables, like the credentials and so on. The os package enables us to interact with the environment variables.

How you can get all the environment variables

import os
os.environ

How we can create a new environment variable

os.environ['MyBlogPassword'] = 'MyPassword'

How to get an environment variable

os.environ.get('MyBlogPassword', 'give_your_default_value')

How to remove an environment variable

# using pop
os.environ.pop("MyBlogPassword")
# using del
del os.environ["MyBlogPassword"]

Parsing Command Line Parameters

We will show how we can pass arguments in the script via the command line instead of having to get user input. The simplest way to do that is by working with the sys module and the sys.argv attribute and a more advanced way is to work with the argparse module and the argparse.ArgumentParser class

sys.argv example

The list of command-line arguments passed to a Python script. argv[0] is the script name (it is operating system dependent on whether this is a full pathname or not). If the command was executed using the -c command line option to the interpreter, argv[0] is set to the string '-c'. If no script name was passed to the Python interpreter, argv[0] is the empty string. Let’s provide an example of the myargv.py script. Note that the input arguments start from index 1 and not 0

import sys
print(f"Positional arguments: {sys.argv[1:]}")
print(f"First argument: {sys.argv[1]}")

Now, we will run the script three times. The first time we will give one argument “predictive”, the second time we will give two arguments, “predictive hacks” and the third time we not give any argument.

How to Write Interactive Python Scripts 2

As we can see it worked as we expected for the first two cases, but for the third case, we received an error (IndexError) when we asked to get the first argument, however, when we asked for the positional argument, we received an empty list []. Finally, keep in mind that the positional arguments are based on spaces unless we explicitly wrap the argument in quotes.

argparse example

The add_argument() method

ArgumentParser.add_argument(name or flags…[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])

Define how a single command-line argument should be parsed. Each parameter has its own more detailed description below, but in short, they are:

  • name or flags — Either a name or a list of option strings, e.g. foo or -f, --foo.
  • action — The basic type of action to be taken when this argument is encountered at the command line.
  • nargs — The number of command-line arguments that should be consumed.
  • const — A constant value required by some action and nargs selections.
  • default — The value produced if the argument is absent from the command line and if it is absent from the namespace object.
  • type — The type to which the command-line argument should be converted.
  • choices — A container of the allowable values for the argument.
  • required — Whether or not the command-line option may be omitted (optionals only).
  • help — A brief description of what the argument does.
  • metavar — A name for the argument in usage messages.
  • dest — The name of the attribute to be added to the object returned by parse_args().

name or flags

The add_argument() method must know whether an optional argument, like -f or --foo, or a positional argument, like a list of filenames, is expected. The first arguments passed to add_argument() must therefore be either a series of flags, or a simple argument name

We will provide an example of argparse where the script will take as input the file name and the number of printed lines and it will return the lines in reverse order.

The myfile.txt is the following:

1.George
2.Jim
3.Maria
4.Joe
5.Steve
6.Stella

and the myargparse.py script is the following.

import argparse
parser = argparse.ArgumentParser(description='Read a file in reverse')
parser.add_argument('filename', help='the file to read')
parser.add_argument('--limit', '-l', type=int, help='the number of lines to read')

args = parser.parse_args()
with open(args.filename) as f:
    lines = f.readlines()
    lines.reverse()
if args.limit:
    lines = lines[:args.limit]
for l in lines:
    print(l.strip())

We will give as arguments the myfile.txt and limit 3.

How to Write Interactive Python Scripts 3

Standard Input And Standard Output In Python

We will provide an example of how you read a file with the standard input and how to write the file with the standard output in Python. We could provide the following descriptions for the standard input and output:

  • Standard input — Is the “I/O stream” that reads and input.
  • Standard output — It writes the output to the ‘I/O stream”

The next graph provides some examples about redirections:

How to Write Interactive Python Scripts 4
Stackoverflow

Let’s provide an example of how we can get an input from a file with the standard input and write a file with the standard output. The task is the following:

  • Write a Python script that takes file as standard input
  • It reverses the text of each line
  • It saves the standard output to a new file called output.txt

My stdinout.py is the one below:

import sys
stdin = sys.stdin
# Redirect sys.stdout to the file
sys.stdout = open('output.txt', 'w')
for line in stdin:
    if len(line)>0:
        print(line.strip()[::-1])
    
sys.stdout.close()

Assume that the example input called myfile.txt is the following:

1.George
2.Jim
3.Maria
4.Joe
5.Steve
6.Stella

Now we can run our script with the following command:

python stdinout.py < myfile.txt

Note the < which means that we redirected the standard input. Finally, we get the following output called output.txt:

egroeG.1
miJ.2
airaM.3
eoJ.4
evetS.5
alletS.6

As we can we, it reversed each line as expected!

How to Write Interactive Python Scripts 5
To leave a comment for the author, please follow the link and comment on their blog: Python – Predictive Hacks.

Want to share your content on python-bloggers? click here.