Python Project: A CLI Tool With argparse
A command line tool is a program that people run by typing its name plus some extra words. argparse turns arguments into values a program can use.
What the program receives
Run this file as python3 argv_demo.py cat dog. sys.argv[1:] holds the words typed after the file name.
import sys
print(sys.argv[1:])One positional argument
Run this file as python3 hello_arg.py Ada. argparse saves the word in args.name.
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("name")
args = parser.parse_args()
print("Hello,", args.name)An optional argument with a type
Run this file as python3 times_arg.py --times 3. With no flag at all, args.times would hold the default value 1.
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--times", type=int, default=1)
args = parser.parse_args()
print(args.times)Counting words in a dict
counts.get(word, 0) reads the old count for a word. A brand new word starts at zero.
counts = {}
for word in "the cat the".split():
counts[word] = counts.get(word, 0) + 1
print(counts)Help text writes itself
Run the finished tool with --help and Python builds the help page from these texts. Help text wraps to fit the terminal window, so this lesson describes it instead of quoting it.
import argparse
parser = argparse.ArgumentParser(description="Count words in text files.")
parser.add_argument("files", nargs="+", help="the files to count")Example
# wordcount.py
import argparse
def main():
parser = argparse.ArgumentParser(description="Count words in text files.")
parser.add_argument("files", nargs="+", help="the files to count")
parser.add_argument("--top", type=int, default=5,
help="how many words to show")
args = parser.parse_args()
counts = {}
for name in args.files:
with open(name) as file:
for word in file.read().lower().split():
counts[word] = counts.get(word, 0) + 1
ranked = sorted(counts.items(), key=lambda item: (-item[1], item[0]))
for word, count in ranked[:args.top]:
print(f"{word}: {count}")
if __name__ == "__main__":
main()
# notes.txt
# the cat sat
# the dog sat
# poem.txt
# the sun and the moonKey points
- Argument: one word or value typed after the program name
- Argument parsing: reading those words and turning them into values your code can use.
- The argparse module does this job for you
- Positional argument: its meaning comes from its place in the line
- Optional argument: it starts with dashes, like --top.
- Its place in the line does not matter
- Use type=int to ask argparse for a whole number.
- A word that is not a number is refused with an error message
- Use default to set the value an optional argument gets when the user skips it
- Use nargs="+" for a positional argument that takes one or more values
- Run the tool with --help to print a summary built from your help texts
- A command line tool runs when a person types its name plus extra words.
In this example, one folder holds three files: wordcount.py, notes.txt, and poem.txt. The two text files hold exactly the lines shown under their names in the code. The command is python3 wordcount.py notes.txt poem.txt --top 3, run inside that folder. argparse reads the two file names as one list, thanks to nargs="+". It also reads --top as the number 3. The tool lowercases every word, so The and the would count as one word. Words are ranked by count first, then by the word itself. That tie break makes the output the same on every run. the wins with 4, sat follows with 2, and and takes third place among the words counted once.
Note
argparse reads sys.argv for you.
Reading sys.argv yourself works, but then you must check every word by hand.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Python Playground
Exercise
You want a flag like --top that must hold a whole number. Which setting does that job?