I don't understand the point of this test:
if sys.stdin.isatty() and args.infile.name == "<stdin>":
sys.exit("Please give some input")
We want to disallow a particular file name, but only if we're connected to a tty? If you want to prompt when input is coming from stdin, then we shouldn't be testing the file name, but instead its properties. And I don't see why we should exit in this case (e.g. we might want to type directly, or copy-paste input). I suggest:
if args.infile.isatty():
print("Please enter your data:")
We might want to add a hint such as Finish with control-D - I'll leave it as an exercise to discover the terminal's control bindings and print the correct keystroke.
We don't need to read one row at a time. prettytable can do that for us:
table = prettytable.from_csv(args.infile)
However, it requires the stream to be seekable, so if it's not, we'll need to read it into memory and pass that as a stream:
if not args.infile.seekable():
from io import StringIO
args.infile = StringIO(args.infile.read())
table = prettytable.from_csv(args.infile)
It's probably a good idea to print only the message from any exceptions, rather than an entire backtrace (unless the user asks for the extra detail):
try:
if not args.infile.seekable():
from io import StringIO
args.infile = StringIO(args.infile.read())
print(prettytable.from_csv(args.infile))
except Exception as e:
logging.error(e, exc_info=(args.loglevel<=logging.DEBUG))
exit(1)
Modified code
#!/usr/bin/env python3
import sys
import argparse
import logging
import prettytable
import csv
parser = argparse.ArgumentParser()
parser.add_argument(
"infile", nargs="?",
type=argparse.FileType("r"),
default=sys.stdin
)
parser.add_argument(
'-d', '--debug',
help="Print lots of debugging statements",
action="store_const", dest="loglevel", const=logging.DEBUG,
default=logging.WARNING,
)
parser.add_argument(
'-v', '--verbose',
help="Be verbose",
action="store_const", dest="loglevel", const=logging.INFO,
)
args = parser.parse_args()
logging.basicConfig(level=args.loglevel)
if args.infile.isatty():
print("Please enter your data:")
try:
if not args.infile.seekable():
from io import StringIO
args.infile = StringIO(args.infile.read())
table = prettytable.from_csv(args.infile)
print(table)
except Exception as e:
logging.error(e, exc_info=(args.loglevel<=logging.INFO))
exit(1)
chr. ASCII is codepoints [0, 255], in Python:range(256). Use a list comprehension to get the characters:[chr(i) for i in range(256)]. If you want a square:[[chr(16*i+j) for j in range(16)] for i in range(16)]\$\endgroup\$-,|and+), rather than making a table of the ASCII characters. \$\endgroup\$