#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2012
    Posts
    2
    Rep Power
    0

    Parsing command line arguments


    Hi !

    I am a new born in Python, and would need some help please !

    I try to parse arguments for a command-line.

    usage: myprog.py [-h] [-i input.txt] [-o output] [-n|l]

    . The input file has to be in .txt format. If not, returns an error message.
    . If input file contains only numbers I need to specify the option -n and to perform <action1> then <action2>.
    . If input file contains only letters I need to specify option -l and to perform the same <action2> as previously only (i.e. to skip <action1>).
    (Note: action1 and action2 are big pieces of code)

    My questions are:
    1) how could I check that input contains only numbers and return an error massage if not, and where do I have to incorporate it?
    2) same for letters?
    3) tell the program to go directly to <action2> if input contains letters only?


    my beginning of attempt:
    Code:
    import argparse
    
    parser = argparse.ArgumentParser(description="Treat numbers and letters differently")
    group = parser.add_mutually_exclusive_group()
    group.add_argument("-n", "--number", help="input file contains number(s)", action="store_true")
    group.add_argument("-l", "--letter", help="input file contains letter(s)", action="store_true")
    parser.add_argument("i", "--input", type=str, help="input in .txt format only")
    parser.add_argument("o", "--output", type=str, help="output")
    args = parser.parse_args()
    
    if args.number:
         <action1>
         <action2>
    elif args.letter:
         <action2>   #skip <action1>

    Thanks for your help !
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,996
    Rep Power
    481
    Let's ignore all your options. Practically this means I'm discarding your -h option because I handle the other cases. The command line use is
    $ python3 p.py < input_file > output_file
    When your long actions1 and 2 write they should write to sys.stdout
    (in other words, use print)


    $ python -c 'import p;p.main()'
    text file
    here
    
    another long code action 2
    $ python -c 'import p;p.main()'
    1 2 3
    3.1416D0

    
    LONG CODE FOR ACTION 1
    another long code action 2
    $ python -c 'import p;p.main()' < p.pyc
    Traceback (most recent call last):
    File "<string>", line 1, in <module>
    File "p.py", line 42, in main
    raise ValueError('file failed the ".txt" format test')
    ValueError: file failed the ".txt" format test
    $
    Code:
    import sys
    import string
    
    def istxt(A,additional_text_characters = ''):
        '''
            This is our "test for .txt format" function.
            It returns true if the set of characters in the input string is a subset of valid ".txt" format characters.
            Doctest use:
            $ python3 -m doctest thisfile.py
    
            >>> istxt('%c%c'%(2,234))
            False
            >>> istxt('%c'%(234))
            False
            >>> istxt('reasonable 1 2 _3.4e-8\ttext')
            True
            >>> istxt('%c'%234,'%c%c'%(2,234))  # addtional_text_characters is a string, default empty string
            True
        '''
        return set(A).issubset(set(string.printable+additional_text_characters))
    
    def onlynums(A,additional_characters = ''):
        '''
            >>> onlynums('+1243.32e-8%c\t'%(13))
            True
            >>> onlynums('one')
            False
            >>> onlynums('reasonable 1 2 _3.4e-8\ttext')
            False
        '''
        return set(A).issubset(set(string.digits+'-+.eEdD \t\n\r\x0b\x0c'+additional_characters))
    
    def action1(A):
        print('LONG CODE FOR ACTION 1')
    
    def action2(A):
        print('another long code action 2')
    
    def main():
        data = sys.stdin.read()
        if not istxt(data):
            raise ValueError('file failed the ".txt" format test')
        if onlynums(data):
            action1(data)
        action2(data)
    
    if '__main__' == __name__:
        main()#
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2012
    Posts
    2
    Rep Power
    0
    thanks for your help b49P23TIvg !

    it's gonna take me some time before understanding everything you mentioned.

    thanks anyway
  6. #4
  7. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,996
    Rep Power
    481
    If you ignore the tests, there's not much to digest!!!!


    mathworld.com
    "A set is a finite or infinite collection of objects in which order has no significance, and multiplicity is generally also ignored (unlike a list or multiset)."


    istxt Since you didn't define ".txt" I defined it for you. I decided that if the data is a subset of printable characters then it's a text file. If you're working in Norwegian this is probably a poor choice.


    onlynums Again, I decided for you that numbers could have standard white space characters, digits, signs, as well as eEdD. FORTRAN uses D I forget why---probably for real*8 scientific notation. The function returns True if the data consists of only these characters.


    actions 1 and 2--- You supply them. I assumed the data should be an argument to these functions. I carelessly disregarded the good chance that they return a value.




    Code:
    def main():
        data = sys.stdin.read()    # read from stdin.  That's the redirection command line operator I indicated.
        if not istxt(data):   # your rule.  if it's not text, report an error and quit.
            raise ValueError('file failed the ".txt" format test')
        if onlynums(data):    # your rule.  do action 1 if the file contains only numbers.
            action1(data)
        action2(data)         # your rule.  Always do action2.
    
    if '__main__' == __name__:
        main()
    [code]Code tags[/code] are essential for python code and Makefiles!

IMN logo majestic logo threadwatch logo seochat tools logo