Wednesday, April 21, 2021

Python3 generator with recursion

Requirement:

Generate sequential MAC addresses without any duplicates

Input:
integer
Output:
MAC Address

Problem:
Python2 does not support yield from keyword. So .. Python3

Solution:

mac = [000000]
def generateMAC(index):
    if index < 0:
        return
    else:
        generateMAC(index - 1)
    while mac[index] < 255:
        #print(':'.join(map(lambda x: "%02x" % x, mac)))
        mac[index] = mac[index] + 1
        yield ':'.join(map(lambda x"%02x" % x, mac))
        yield from generateMAC(index - 1)
    mac[index] = 0

Rambling:

Maximum possible number of MAC Addresses are 255*255*255*255*255*255 = 274941996890625

So, 255*255=65025 combinations from first two octets are enough for my requirement. Hence this mess. But It works!

mac = [000000]
macs = []
def o_f_generateMAC(index):
    while mac[5] <= 255:
        macs.append(':'.join(map(lambda x"%02x" % x, mac)))
        while mac[4] <= 255:
            macs.append(':'.join(map(lambda x"%02x" % x, mac)))
            mac[4] = mac[4] + 1
        mac[4] = 0
        mac[5] = mac[5] + 1
    mac[5] = 0
    return macs

However when just multiplied the combinations by another 255 (ie., 255*255*255). Python interpretor took its own time. Anyway I just said enough.

mac = [000000]
macs = []
def o_f_generateMAC():
    while mac[5] <= 255:
        macs.append(':'.join(map(lambda x"%02x" % x, mac)))
        while mac[4] <= 255:
            macs.append(':'.join(map(lambda x"%02x" % x, mac)))
            while mac[3] <= 255:
                macs.append(':'.join(map(lambda x"%02x" % x, mac)))
                mac[3] = mac[3] + 1
            mac[3] = 0
            mac[4] = mac[4] + 1
        mac[3] = 0
        mac[4] = 0
        mac[5] = mac[5] + 1
    mac[5] = 0
    return macs

When converting the same with better logic (of course! recursion), this arrived.

def f_generateMAC(index):
    if index < 0:
        return
    else:
        generateMAC(index - 1)
    while mac[index] < 255:
        macs.append(':'.join(map(lambda x"%02x" % x, mac)))
        mac[index] = mac[index] + 1
        generateMAC(index - 1)
    mac[index] = 0
    return macs

The above function looks definitely better. Still memory inefficient. Why should the list "macs" be created at all?!. Thus, the need for the generator.

mac = [000000]
def generateMAC(index):
    if index < 0:
        return
    else:
        generateMAC(index - 1)
    while mac[index] < 255:
        mac[index] = mac[index] + 1
        yield ':'.join(map(lambda x"%02x" % x, mac))
        generateMAC(index - 1)
    mac[index] = 0

Still, the above generator did not work as expected on Python2. Then, Python3 helped to achieve "generator delegating part of computing to another generator" with "yield from" keyword. Finally, arrived at the solution shown on the top.

Thanks!

No comments:

Post a Comment

Python3 generator with recursion

Requirement: Generate sequential MAC addresses without any duplicates Input: integer Output: MAC Address Problem: Python2 does not support y...