1

I have this code. If you run it everything works fine if you follow the instructions. However I want to dummyproof it but when you enter too make troops and then you fix your mistake you get an error after fixing the mistake when functions restarts itself.

Please take a look and help me fix it.

import time
warriors = 100
def deploy(): #Calls fighters to front lines
    amount = input('How many warriors would you like to send to the front lines?  Your limit is %i warriors. Keep in mind that enemy invaders have been spotted inside your base. You must keep 10 warriors in base at all times. ' %(warriors))
    try:
        amount = int(amount)
    except ValueError:
        print('Please use numbers.')
        time.sleep(1.5)
        deploy()
    if amount <= warriors:
        print (type(amount))
    elif amount > warriors:
        print("You can't send that many warriors. You only have %i warriors." %(warriors))
        time.sleep(1.5)
        amount=0
        deploy()
    else:
        print("You did something wrong. Try again.")
        time.sleep(1.5)
        deploy()
fighters = deploy()
warriors = warriors - fighters
Adam Smith
  • 52,157
  • 12
  • 73
  • 112
HAMZAH AHMED
  • 159
  • 5

1 Answers1

1

You shouldn't use recursion (e.g. a function calling itself repeatedly) to try and do validation. For some general examples of good patterns for this, the canonical question is a good start. In your case I might refactor slightly.

import time

warriors = 100


def deploy():
    while True:
        amount = input("...")  # your text here
        try:
            amount = int(amount)
        except ValueError:
            print("Please use numbers.")
            # move the time.sleep to the end
        else:  # only execute if the try block succeeds
            if amount > warriors:
                print("You can't send that many warriors. "
                      "You only have %i warriors." % warriors)
            else:
                # everything went right!
                print(type(amount))  # why are you doing this...?
                return amount  # did you forget this in your sample code?
        # if you get here: something broke
        time.sleep(1.5)

That said, this is kind of ugly since it's so deeply nested. Remember the Zen: "Flat is better than nested." Let's refactor a bit to make a new function that does the validation for us.

import time

warriors = 100


def int_less_than(prompt, ceil, type_error_msg=None,
                  value_error_msg=None, callback=None):
    """Returns a validated integer

    input(prompt) must be less than ceil. Print to console a std error msg
    if none is specified. If you specify a callback: run the callback if any
    errors are detected.
    """

    while True:
        user_in = input(prompt)
        try:
            user_in = int(user_in)
        except ValueError:
            print(type_error_msg or "You must enter a number")
        else:
            if user_in > ceil:
                print(value_error_msg or "You must enter a number "
                                         "less than {}".format(ceil))
            else:
                return user_in
        if callback is not None:
            callback()  # lets us insert a time.sleep call

def deploy():
    amount = int_less_than("How many warriors would you like to...",
                           warriors,
                           callback=lambda: time.sleep(1.5))
    return amount
Community
  • 1
  • 1
Adam Smith
  • 52,157
  • 12
  • 73
  • 112