Skip to main content
Fold long lines
Source Link
Toby Speight
  • 88.4k
  • 14
  • 104
  • 327
#!/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)
#!/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)
#!/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)
Show whole program
Source Link
Toby Speight
  • 88.4k
  • 14
  • 104
  • 327

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)

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)
Explain why I wouldn't exit when reading stdin; trackback is debug level, not info
Source Link
Toby Speight
  • 88.4k
  • 14
  • 104
  • 327

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 a lineone 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:
    tableif =not prettytableargs.from_csvinfile.seekable():
        from io import StringIO
        args.infile = StringIO(args.infile.read())
    print(tableprettytable.from_csv(args.infile))
except Exception as e:
    logging.error(e, exc_info=(args.loglevel<=logging.INFODEBUG))
    exit(1)

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:

if args.infile.isatty():
    print("Please enter your data:")

We don't need to read a line 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:
    table = prettytable.from_csv(args.infile)
    print(table)
except Exception as e:
    logging.error(e, exc_info=(args.loglevel<=logging.INFO))
    exit(1)

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)
Catch exceptions and log appropriately
Source Link
Toby Speight
  • 88.4k
  • 14
  • 104
  • 327
Loading
Source Link
Toby Speight
  • 88.4k
  • 14
  • 104
  • 327
Loading