1

I want to make main() repeat until it can't anymore because of say, a "file not found" on function_one(). When I execute the code, it goes from function_one to function_three and stops there. How do I loop main() so it repeats the function sequence again ?

 def main():
        (f,r) = function_one()
        (x,z) = function_two(f,r)
        function_three(x,z)
xavier
  • 746
  • 2
  • 12
  • 22

3 Answers3

4

Use a while loop:

def main():
    while True:
        try:
            (f, r) = function_one()
            (x, z) = function_two(f, r)
            function_three(x, z)
        except WhateverErrors:
            break
zondo
  • 19,901
  • 8
  • 44
  • 83
2

As already suggested, a while loop with a try/except will work well, but be careful about what you catch. Be as specific as possible. More info in this post.

If your functions don't all end with exceptions, You can also have them return success or failure by manually raising an exception.

def main():
    c = float(1.00)
    # Uncomment the following line to see an unplanned exception / bug.
    # c = float(0.00)
    # That's is why it's important to only catch exceptions you are
    # expexting.
    # If you catch everything you won't see your own mistakes.

    while True:
        c += 2
        print('Main loop')
        try:
            (f, r) = function_one(c)
            (x, z) = function_two(f, r)
            function_three(x, z)
        except IOError:
            print('Controlled end, due to an IOError')
            break
        except ValueError as e:
            print('Intentionally stopped: %s' % e)
            break
    print("Program end")


# Will cause IOERROR if "thestar.txt" does not exist,
# Will continue on if you create the file.
def function_one(c):
    print('function_one')
    with open('thestar.txt', 'r') as bf:
        f = bf.read()
    # Doing work on the data ...
    r = 100 - c
    return (f, r)


# If the file does not contain the text "Cleese",
# this will hand-raise an exception to stop the loop.
def function_two(f, r):
    print('function_two')
    if 'cleese' in f.lower():
        x = 100 / r
        z = 'John ' + f
    else:
        raise ValueError('The parrot is just sleeping')
    return (x, z)


# you need to write "Cleese" to thestar.txt to get this far and keep
# the main loop going.
def function_three(x, z):
    print('function_three')
    # This is what decides when we are finished looping
    if x > 1:
        print('%s:%s' % (x, z))
    else:
        # Another diliberately raised exception to break the loop
        raise ValueError('The parrot is dead!')


if __name__ == '__main__':
    main()

It's perfectly OK to do this with variables instead of exceptions, but it's easier this way and it's considered quite pythonic.

Community
  • 1
  • 1
Mbo42
  • 348
  • 3
  • 12
0

Use a while True: loop. It will automatically exit when an exception is thrown in any of the functions.

xrisk
  • 3,790
  • 22
  • 45
  • Yes it will automatically exit, but not at all gracefully. – zondo Feb 07 '16 at 03:30
  • @zondo huh but whatever is the difference, it's not like there is any cleanup to be done. – xrisk Feb 07 '16 at 03:32
  • 1
    Just because there might be no clean up to be done here, it doesn't mean there won't be in some other future use. Exiting gracefully and exiting after choking, even if up to that point both versions have resulted to the same output, is not the same. – Reti43 Feb 07 '16 at 03:40
  • 1
    Well, we are not discussing the "future" version here. Letting an exception propagate when there is no need for handling it is not a crime. – xrisk Feb 07 '16 at 03:42