0

I am currently iterating over data, placing the data within columns based on certain criteria. Please know that I want to avoid Global variables altogether. This is what I am working with:

def query_alarm(device):
    """
    Requests data from the device,
    saving each oid and value from the device's
    specified alarm table into a Breadcrumb object.
    """
    column = []
    oid_check = ''
    for (errorIndication, errorStatus, errorIndex, response) in nextCmd(
        SnmpEngine(),
        CommunityData("public"),
        UdpTransportTarget((device.ip_address, device.snmp_port_number)),
        ContextData(),
        ObjectType(ObjectIdentity(manufacturer_alarm_table_oid(device))),
        lexicographicMode=False,
    ):
        if nextcmd_error(errorIndex, errorIndication, errorStatus):
            handle_nextcmd_error()
            continue


        for oid, value in response:
            column_oid = split_column_oid(oid)
            if column_oid != oid_check:
                if len(column) > 0:
                    device.alarm_count = len(column)
                    device.date_checked = timezone.now()
                    device.save()
                column = []
                oid_check = column_oid
            column.append({str(oid): str(value)})
            try:
                Breadcrumb(oid=oid, value=value).save()
            except ValueError as e:
                print(e)
                Breadcrumb(oid=oid, value='*** FIX DateAndTime Value ***').save()


    return True

As I refactor this, I'd like to place the for oid, value in response iteration and everything under it within its own functions. What is tricking me up, is what to do with the column and oid_check variables that are declared at the beginning of the query_alarm function.

Barmar
  • 741,623
  • 53
  • 500
  • 612
Bonteq
  • 777
  • 7
  • 24
  • Try reading this on [passing by reference](https://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference). I'm not sure if there is a cleaner way though. – Jeppe Feb 11 '19 at 21:22

2 Answers2

3

Pass the variables to the function and return them from the function.

def func(oid, value, oid_check, column):
    column_oid = split_column_oid(oid)
    if column_oid != oid_check:
        if len(column) > 0:
            device.alarm_count = len(column)
            device.date_checked = timezone.now()
            device.save()
        column = []
        oid_check = column_oid
    column.append({str(oid): str(value)})
    try:
        Breadcrumb(oid=oid, value=value).save()
    except ValueError as e:
        print(e)
        Breadcrumb(oid=oid, value='*** FIX DateAndTime Value ***').save()

    return oid_check, column

Then call it in a loop like:

for oid, value in response:
    oid_check, column = func(oid, value, oid_check, column)
Barmar
  • 741,623
  • 53
  • 500
  • 612
1

You can pass in the variables you need into the function.

You can refactor it this way:

def query_alarm(device):
    """
    Requests data from the device,
    saving each oid and value from the device's
    specified alarm table into a Breadcrumb object.
    """
    column = []
    oid_check = ''
    for (errorIndication, errorStatus, errorIndex, response) in nextCmd(
        SnmpEngine(),
        CommunityData("public"),
        UdpTransportTarget((device.ip_address, device.snmp_port_number)),
        ContextData(),
        ObjectType(ObjectIdentity(manufacturer_alarm_table_oid(device))),
        lexicographicMode=False,
    ):
        if nextcmd_error(errorIndex, errorIndication, errorStatus):
            handle_nextcmd_error()
            continue   

        column, oid_check = func1(response, column, oid_check)

    return True

def func1( response, column, oid_check ):
    for oid, value in response:
        column_oid = split_column_oid(oid)
        if column_oid != oid_check:
            if len(column) > 0:
                device.alarm_count = len(column)
                device.date_checked = timezone.now()
                device.save()
            column = []
            oid_check = column_oid
        column.append({str(oid): str(value)})
        try:
            Breadcrumb(oid=oid, value=value).save()
        except ValueError as e:
            print(e)
            Breadcrumb(oid=oid, value='*** FIX DateAndTime Value ***').save()
    return column, oid_check
Niharika Bitra
  • 477
  • 2
  • 9