Python Forum

Full Version: range as a command
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
i tried this on Ubuntu Linux. i hope it works in other places you can have commands in Python like Windows.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from sys import argv,stderr
"""The range command outputs a range of decimal numbers from 1 to 3 arguments."""

def help():
    print('The range command outputs a range of decimal numbers from 1 to 3 arguments.',file=stderr)
def version():
    print('version 0.0.1',file=stderr)
if argv[1:2][0][:2]=='--':
    if '--help' in argv:help()
    if '--version' in argv:version()
    exit(3)

for n in range(*[int(x)for x in argv[1:4]]):
    print(n,flush=True)
Why wouldn't you just use seq on Linux? Also, are there bugs? There's nowhere you check for valid indices in argv before slicing.
maybe you would use seq. nothing wrong with that unless you want to have something that works just like range() does.

i don't know if there are bugs. did you find any?

i don't need to check for errors, the Python engine does that. this is for new coders to play with. they might change it around. they can add the error checks appropriate for their target user base.
You release software to users without tests?!
i tested it. it works as is. users might change it. that could break it. they find out if they test the changed version.

what i meant by "i don't need to check for errors" is "i don't need to add code to check for user errors". the error report is the stack dump.
I suppose it's strange to me not having a test suite that makes sure the software works and continues to work after any changes. Showing a stack trace to the user seems quite unfriendly. Each to their own though!
I'm inclined to think that Python's stack trace is one of the most friendly error reports. Why put much effort in writing pretty error reports only to discover that their main effect is to hide the actual cause of the error?

The biggest flaw that I see in the above code is the summary treatment of the command line arguments. I think using a specialized module such as argparse is almost mandatory. This is discussed regularly in this forum
  • Argparse is in the standard lib, a great advantage
  • Click has many supporters
  • Plumbum.cli is my favorite one
  • ... many others
for years, commands i create have arguments pattern that goes beyond what usual arg parsing tools handle. often args are just plain simple and an arg parsing tool is overkill. in other cases, it can't handle the arguments, like mixed + and - prefixes.

whether i let the stack trace be the error message or not depends on the audience. if that audience is myself or other python coders, i do use them. for users that would never understand code at all, i try to make an error message that explains to their level. sometimes i've found that arguments tell the error explanation the context to explain in. errors may, or may not, be the result of the user's doings. i sometimes try to tell them what they need to do.
As a comparison, here is a version with arguments parsed by plumbum.cli

from plumbum import cli

def valid_step(step):
    if step is None:
        return 1
    elif int(step) == 0:
        raise TypeError('Expected non-zero step argument, got', step)
    else:
        return int(step)
    
class App(cli.Application):
    """Print a sequence of integers similarly to Python's range function
    
    To allow negative arguments on the command line, use -- before the argument list.
    """
    VERSION = '2020.08.08'
    
    @cli.positional(int, int, valid_step)
    def main(self, start, stop=None, step=None):
        args = (start,) if stop is None else (start, stop, step or 1)
        for n in range(*args):
            print(n, flush=True)
        
if __name__ == '__main__':
    App().run()