ldg
ldg

Reputation: 451

Alternative to recursion - Python

I've a little question to make because I really can't find a way out. Is is more a logic question than a Python one. What I am doing is calling again the method when the result is not accurate or wrong. I am using recursion to do this, but obviously, it returns as many values as the recursive method called.

What I am doing is using the method to find 'z' of a robotic arm through an ultrasonic sensor, when this result from the sensor is not accurate I want the method to be called again to re-start the process again.

def get_z_from_ultrasonic_sensor(self, uarm, x, y):

    # clear all IO data
    self.serial_port.reset_input_buffer()
    self.serial_port.reset_output_buffer()

    count = 0
    z = 110
    uarm.set_position(x, y, z, 1)
    time.sleep(2)
    global input
    # if self.count is 1:
    #     while True:
    #         print(self.serial_port.readline())
    while True:
        # if z is to small, means that has not been detected well, recursive call
        if z < 70:
            self.get_z_from_ultrasonic_sensor(uarm, x, y)

        # check if input is an integer else, recursive call
        try:
            input = int(self.serial_port.readline())

            if input > 160:
                break
        except:
            break

        if input <= 116:
            # print("Distance:", int(input))
            break
        else:
            count = count + 1
            # print("Distance:", int(input))
            # print("Z", z)
            if count is 5:
                z = z - 1
                count = 0
                print("US Distance:", int(input))
                print("Z Robot", z)
        uarm.set_position(x, y, z, 1)

    if z is 110:
        pass
    print("Z to Write:", z)
    # self.count += 1
    return z-6

What I want is to get just one value returned, and not as many values as the recursive call (right now return as first value the good 'z' and then as many z = 110 - see declaration of local variable - as the recursive call). I can't really find a solution of this, I can't use Iteration I suppose because it is based on the same principle.

Any suggestion? Thanks in advance

Upvotes: 0

Views: 2414

Answers (2)

nigel222
nigel222

Reputation: 8192

I'm not sure from your code exactly what you are trying to do. But an outline code that avoids recursion might look like this:

while True:
    try:
        value = get_input()
    except ValueError:
        # print an error message about value, if not already done
        continue # have another go at getting valid input
    except EOFError:
        break # get out of the infinite loop

    # do something with value

get_input will raise ValueError when it is supplied with bad input, and raise EOFError (if necessary) when it detects end of data or "quit" or whatever.

Key point: use exceptions to deal with exceptional cases in the most convenient place (here, "above" the code which detects and raises the condition).

Upvotes: 1

Mateusz Korycinski
Mateusz Korycinski

Reputation: 1057

I'll take a stab. Maybe it is what you are looking for.

def function(x, y):

    count = 0
    z = 110
    global input

    try:
        input = int(serial_port.readline())
    except:
        return function(x,y)


    if z < 70 or input <= 116:
        return function(x, y)

    else:
        count = count + 1
        if count == 5:
            z = z - 1
            count = 0
            # do something

    return z

Upvotes: 1

Related Questions