Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python algorithm error when trying to find the next largest value

I've written an algorithm that scans through a file of "ID's" and compares that value with the value of an integer i (I've converted the integer to a string for comparison, and i've trimmed the "\n" prefix from the line). The algorithm compares these values for each line in the file (each ID). If they are equal, the algorithm increases i by 1 and uses reccurtion with the new value of i. If the value doesnt equal, it compares it to the next line in the file. It does this until it has a value for i that isn't in the file, then returns that value for use as the ID of the next record.

My issue is i have a file of ID's that list 1,3,2 as i removed a record with ID 2, then created a new record. This shows the algorithm to be working correctly, as it gave the new record the ID of 2 which was previously removed. However, when i then create a new record, the next ID is 3, resulting in my ID list reading: 1,3,2,3 instead of 1,3,2,4. Bellow is my algorithm, with the results of the print() command. I can see where its going wrong but can't work out why. Any ideas?

Algorithm:

def _getAvailableID(iD):
        i = iD
        f = open(IDFileName,"r")
        lines = f.readlines()
        for line in lines:
            print("%s,%s,%s"%("i=" + str(i), "ID=" + line[:-1], (str(i) == line[:-1])))
            if str(i) == line[:-1]:
                i += 1
                f.close()
                _getAvailableID(i)
        return str(i)

Output: (The output for when the algorithm was run for finding an appropriate ID for the record that should have ID of 4):

i=1,ID=1,True
i=2,ID=1,False
i=2,ID=3,False
i=2,ID=2,True
i=3,ID=1,False
i=3,ID=3,True
i=4,ID=1,False
i=4,ID=3,False
i=4,ID=2,False
i=4,ID=2,False
i=2,ID=3,False
i=2,ID=2,True
i=3,ID=1,False
i=3,ID=3,True
i=4,ID=1,False
i=4,ID=3,False
i=4,ID=2,False
i=4,ID=2,False
like image 728
Kris Rice Avatar asked Jun 21 '26 05:06

Kris Rice


2 Answers

I think your program is failing because you need to change:

_getAvailableID(i)

to

 return _getAvailableID(i)

(At the moment the recursive function finds the correct answer which is discarded.)

However, it would probably be better to simply put all the ids you have seen into a set to make the program more efficient.

e.g. in pseudocode:

S = set()
loop over all items and S.add(int(line.rstrip()))
i = 0
while i in S:
   i += 1
return i
like image 169
Peter de Rivaz Avatar answered Jun 22 '26 18:06

Peter de Rivaz


In case you are simply looking for the max ID in the file and then want to return the next available value:

def _getAvailableID(IDFileName):
    iD = '0'
    with open(IDFileName,"r") as f:
        for line in f:
            print("ID=%s, line=%s" % (iD, line))
            if line > iD:
                iD = line

    return str(int(iD)+1)

print(_getAvailableID("IDs.txt"))

with an input file containing

1
3
2

it outputs

ID=1, line=1

ID=1
, line=3

ID=3
, line=2

4

However, we can solve it in a more pythonic way:

def _getAvailableID(IDFileName):
    with open(IDFileName,"r") as f:
        mx_id = max(f, key=int)
    return int(mx_id)+1
like image 20
Pynchia Avatar answered Jun 22 '26 18:06

Pynchia