How to return to the start of a function while in that function without recursion

Question:

class PlayerAttributes:
        inventory = []
        def __init__(self, name, inventory):
            self.name = name
            self.inventory = inventory # LIST
    class Item:
        def __init__(self, item_name, damage):
            self.item_name = item_name
            self.damage = damage

class Weapons(Item):
    weapon_1 = Item("Me Sword", 100)


Player_1 = PlayerAttributes("Bob", [])

def get_name():
    Player_1.name = input("Enter name here: ").capitalize()
    commands()

def stats():
    print("Name = " + str(Player_1.name), "n",
          "Inventory: ")
    for x in Player_1.inventory:
        print(str(x.item_name))

def commands():
    prompt = None
    prompt_choices = {"stats", "quit", "give"}
    while prompt not in prompt_choices:
        prompt = input("Enter Command: ").lower()
    if prompt == "stats":
        stats()
        commands()
    elif prompt == "quit":
        quit()
    elif prompt == "give":
        Player_1.inventory.append(Weapons.weapon_1)
        commands()

get_name()

PROBLEM

I’m currently getting back to the while loop for "prompt" by calling "commands()" in the if statements but was told that it’s a recursion and that it’s unnecessary as well as it has a side effect of growing the call stack…

QUESTION

What should I do differently??

Extra

How would it grow the call stack?

Asked By: HardlySalty

||

Answers:

You can use an infinite loop. Instead of letting get_name and commands call commands, try putting the following at the end of the code:

get_name()

while True:
    commands()

and remove all other calls commands() from your code.

Answered By: j1-lee

Your while loop is configured for repeating the cycle until it finds a prompt. Then, the loop ends. You are restarting the cycle calling the function again but that leaves the first function running so every time this happens a new function will start and the old one will stay waiting. So as you said, the call stack is growing.

One way to solve this is to change your while loop.

Instead of:

while prompt not in prompt_choices:

You can use:

While True:

This makes the loop repeat over and over again without calling a new function.

Another solution will be to use two whiles:

condition = True
While condition:
    while prompt not in prompt_choices:

This also makes the loop repeat over and over again. But if you want to finish the loop you can set condition = False within your code and that will make the current cycle the last cycle.

Hope this helps.

Answered By: Jose Machado

You can change your commands() func like below

def commands():
    prompt = None
    prompt_choices = {"stats", "quit", "give"}
    while prompt not in prompt_choices:
        prompt = input("Enter Command: ").lower()
        if prompt == "stats":
            stats()
        elif prompt == "quit":
            quit()
        elif prompt == "give":
            Player_1.inventory.append(Weapons.weapon_1)
        prompt=None

get_name()
Answered By: veysel
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.