0

Please help me fix this recursive function so that I can successfully prompt the user at each stage. I am trying to make a program that allows users mix, change the playback speed and filter the signal of a wav file. To do that I need create a recursive question that continually prompts the user to use different tools in this program.

def c_function():
    print("you have successfully called c_function")# These print statements are just place holders for the actual functions
    return
def m_function():
    print("you have successfully called m_function")
    return
def f_function():
    print("you have successfully called f_function")
    return
def s_function():
    print("you have successfully called s_function")
    return
"use these functions as selection tools in the recursive function bellow"

user_question1 = input("Select one of the following four options:\n s see the sample rate of the file\n c change the playback speed\n m mix two signals together\n f filter the signal or\n q quit \n : ")

def recursive_main_function():
    if user_question1 == ('c'):
        c_function()
     recursive_main_function()

    if user_question1 == ('m'):
        m_function()
    recursive_main_function()

    if user_question1 == ('f'):
        f_function()
    recursive_main_function()

    else:
        print("Invalid response. Please try again" + user_question1)

        return
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
Josh
  • 11
  • 3
  • 1
    is a recursive function necessary? You can use loop for that as well. – sittsering Aug 28 '21 at 09:20
  • The biggest error in this code is the wrong indentation of the recursive calls; every `recursive_main_function()` should be indented to be inside its `if` statement. – Stef Aug 28 '21 at 10:22
  • Similar question: [while loop function as a list tracker? and mix with FileI/O?](https://stackoverflow.com/a/64169647/3080723) – Stef Aug 28 '21 at 10:36
  • If your user prompts enough times, recursion will blow the call stack. Use a loop. – ggorlen Aug 28 '21 at 19:11

2 Answers2

0

It looks like you'd want to use an infinite while loop. Using if statements with else ifs is good too because if the user input somehow fulfils more than one of the cases, the program won't call several functions at once. Let me know if you have any questions.

def recursive_main_function():
    # Infinitely loops unless user presses 'q'
    while(True):
        # Waits for the question's input
        user_question1 = input("Select one of the following four options:\n s see the sample rate of the file\n c change the playback speed\n m mix two signals together\n f filter the signal or\n q quit \n : ")
        # Respond based on input provided

        if user_question1 == "s":
            s_function()
        elif user_question1 == "c":
            c_function()
        elif user_question1 == "m":
            m_function()
        elif user_question1 == "f":
            f_function()
        elif user_question1 == "q":
            # Breaks the user out of the while loop
            break
        else:
            print("Invalid response. Please try again" + user_question1)
    # End of function, exits script
    return

# To initiate script
recursive_main_function()
curiousCoder
  • 41
  • 1
  • 8
  • Did you actually test this? I think `user_question1` can never be equal to `"s"`, `"c"` or any other single-letter string, if the user input is given via a terminal which always add a `\n` character at the end. You probably need to use `.strip()`, or compare with `user_question1[0]` instead. – Stef Aug 28 '21 at 10:20
  • 1
    @Stef It worked when I tried it. But sure, I can see why retrieving the first char of the given string would be better. By no means is the method I've outlined above the most efficient but it works – curiousCoder Aug 28 '21 at 11:09
0

This is a shorter version of my answer to a related question.

Rather than a forest of ifs, you could use a dictionary to match user input to a function.

def c_function(argv):
    print("you have successfully called c_function")# These print statements are just place holders for the actual functions
    return 0
def m_function(argv):
    print("you have successfully called m_function")
    return 0
def f_function(argv):
    print("you have successfully called f_function")
    return 0
def s_function(argv):
    print("you have successfully called s_function")
    return 0

def help_function(argv):
    print('available commands:')
    print('  s      see the sample rate of the file')
    print('  c      change the playback speed')
    print('  m      mix two signals together')
    print('  f      filter the signal')
    print('  help   print the list of commands')
    print('  quit   quit')
    return 0
    
def quit_function(argv):
    env['didntQuit'] = False
    return 0

def notfound_function(argv):
    print('{}: {}: command not found'.format(env['replname'], argv[0]))
    return -1

def print_return_value(ret, argv):
    if ret != 0:
        print('{}: command {} failed with return value {}'.format(env['replname'], argv[0], ret))
env = { 'replname': 'wav-processor-repl', 'prompt': '$ ',  'didntQuit': True }

command_dict = {'c': c_function, 'm': m_function, 'f': f_function, 'h': help_function, 'help': help_function, 'q': quit_function, 'quit': quit_function}

while env['didntQuit']:
    argv = input(env['prompt']).strip().split()            # read
    command = command_dict.get(argv[0], notfound_function) # identify command
    ret = command(argv)                                    # execute command
    print_return_value(ret, argv)                          # error message if command failed

Output:

$ c
you have successfully called c_function
$ f
you have successfully called f_function
$ g
waf-processor-repl: g: command not found
waf-processor-repl: command g failed with return value -1
$ f
you have successfully called f_function
$ h
available commands:
  s      see the sample rate of the file
  c      change the playback speed
  m      mix two signals together
  f      filter the signal
  help   print the list of commands
  quit   quit
$ m
you have successfully called m_function
$ q
Stef
  • 13,242
  • 2
  • 17
  • 28