I have written the following cli tool.
import sys
import argparse
parser = argparse.ArgumentParser(prog='remove-duplicate-lines-except-blank-lines',
usage='%(prog)s [options] [files...]',
description='Remove duplicate line except white space')
args = parser.parse_known_args()
command_line_arguments = sys.argv[1:]
lines_seen = set() # holds lines already seen
if sys.stdin.isatty() and (len(command_line_arguments) == 0): # has neither stdin nor file as input. Show help and exit.
parser.print_help()
sys.exit("Please give some input")
if len(command_line_arguments) > 1: # 2 or more arguments, so read from file, write to file
try:
infile = open(sys.argv[1], "r")
except FileNotFoundError:
sys.exit("Input File Not Found")
outfile = open(sys.argv[2], "w")
elif len(command_line_arguments) > 0: # one argument
if sys.stdin.isatty(): # one argument and stdin does not have value, so read from file and write to stdout
try:
infile = open(sys.argv[1], "r")
except FileNotFoundError:
sys.exit("Input File Not Found")
outfile = sys.stdout
else: # one argument and stdin has value, so read from stdin and write to file
infile = sys.stdin
outfile = open(sys.argv[1], "w")
else: # no arguments, so read from stdin and write to stdout
infile = sys.stdin
outfile = sys.stdout
for line in infile:
if line not in lines_seen:
outfile.write(line)
if line != "\n":
lines_seen.add(line)
if infile is not sys.stdin:
infile.close()
if outfile is not sys.stdin:
outfile.close()
The purpose of this tool is to remove duplicate lines (except blank lines). It ignores blank lines.
It has --help
and -h
to get help.
The logic here is, it takes input from stdin or input-file. It gives output to stdout
or output-file. So, total four combinations.
- input from stdin and output to stdout
- input from stdin and output to output-file
- input from input-file and output to stdout
- input from input-file and output to output-file
There is a special case where there is no input (neither from stdin nor from input-file). Which is covered using:
if sys.stdin.isatty() and (len(command_line_arguments) == 0): # has neither stdin nor input file
parser.print_help()
sys.exit("Please give some input")
The problem with this code is, the logic seems over complicated. too many conditions giving me the sense that something is wrong here. However, because of these conditions, it has become very hard to test the code.
Another problem with the code is the help, which looks like:
usage: remove-duplicate-lines-except-blank-lines [options] [files...]
Remove duplicate line except white space
optional arguments:
-h, --help show this help message and exit
I am also looking for feedback on how to make the help option better. Given few things are not clear (mentioned bellow in bullet point) just by looking at usage: remove-duplicate-lines-except-blank-lines [options] [files...]
. I am also not clear on how to write the usage properly.
- When there is stdin and one file as argument, the file is considered as output-file.
- When there is no stdin and one file as argument, the file is considered as input-file, and the output goes to the stdout.
I want to keep this piece of code as a template for future cli apps written in python. So, your critique is very important for me.