Home > Software engineering >  How to use a class to store variables that are updated in different functions, and then call these u
How to use a class to store variables that are updated in different functions, and then call these u

Time:12-22

I am solving a problem which involves traversing a n x m matrix in a zigzag fashion, where n and m can be same number or different numbers, i.e. we will have a square or rectangular matrix.

To solve this problem, I have a main method which will traverse the matrix; and within this main method, I create and call on moveDiagonallyUpwards and moveDiagonallyDownwards methods to move in the zigzag way.

The problem I am having is that when I pass row and col as arguments from the main method into these two other methods, and inside these methods I update row and col, e.g. =1 or -= 1. These changes DO NOT reflect in the main method, when I return to the main method. And I do understand why this is the case.

So my challenge is, how can I pass back the updated row and col to the main method? I thought of using a global class to achieve the above. My idea is to create a separate class to hold these variables like the below, but I am having problems with calling and using these global row and col in my main method.

Any ideas how to adjust the row and col in main method to achieve the above? Thanks!

array = [
    [1, 3, 4, 10],
    [2, 5, 9, 11],
    [6, 8, 12, 15],
    [7, 13, 14, 16]
  ]

class matrixMovement: 
    def __init__(self,row=0,col=0,output=[]): 
        self.row = row
        self.col = col
        self.output = output
#Main Method
def zigzagTraverse(array):
    output.append(array[row][col])
    while array.row<= len(array)-1 or array.col<= len(array[0])-1: 
        if array.row< len(array)-1: 
            array.row  = 1
            output.append(array[row][col])
            diagonalUp(row,col,array,output)
        if col < len(array[0])-1: 
            col  = 1
            output.append(array[row][col])
            diagonalDown(row,col,array,output)
    return output
            
def diagonalUp(row,col,array,output): 
    while row > 0 and col< len(array[0])-1: 
        row -= 1
        col  = 1
        output.append(array[row][col])
    return matrixMovemenet(row,col,output)
    
def diagonalDown(row,col,array,output): 
    while row<len(array)-1 and col > 0: 
        col-= 1
        row  = 1
        output.append(array[row][col])
    return matrixMovemenet(row,col,output)

CodePudding user response:

You have a few problems. One is local scope. Another is using the return statement but doing nothing with the object returned.

There are a few ways to solve this. One is to ignore the local variables and just create an object from matrixMovement and utilize the fact that it's mutable.

class MatrixMovement: 
    def __init__(self, row=0, col=0, output=None):
        # I modified this to avoid the mutable default
        if output is None:
            output = []
        self.row = row
        self.col = col
        self.output = output


# Main Method
def zigzag_traverse(array):
    # this is the object we will be mutating
    obj = MatrixMovement()
    obj.output.append(array[obj.row][obj.col])
    while obj.row <= len(array) - 1 or obj.col <= len(array[0]) - 1: 
        if obj.row < len(array) - 1: 
            obj.row  = 1
            obj.output.append(array[obj.row][obj.col])
            diagonal_up(obj, array)
        if obj.col < len(array[0]) - 1: 
            obj.col  = 1
            obj.output.append(array[obj.row][obj.col])
            diagonal_down(obj, array)
        # without this condition the loop will never break
        if obj.row == len(array) - 1 and obj.col == len(array[0]) - 1:
            break
    return obj.output


def diagonal_up(obj, array):
    # since we are passing in a mutable object
    # anything attribute we change on it
    # will be reflected on the object from the call site
    while obj.row > 0 and obj.col < len(array[0]) - 1: 
        obj.row -= 1
        obj.col  = 1
        obj.output.append(array[obj.row][obj.col])


def diagonal_down(obj, array):
    # the same rules as diagonal_up
    while obj.row < len(array) - 1 and obj.col > 0: 
        obj.col -= 1
        obj.row  = 1
        obj.output.append(array[obj.row][obj.col])
  • Related