0

Just a warning that this is a college assignment, and therefore I am not allowed to use python functions other than len(). I don't mind if anyone wants to answer with functions or not, just know that's why my code looks terrible.

The assignment is for me to create a 10x10 matrix and with multiple functions add elements to it depending on the x or y position, checking if the space is available or not. The original instruction is to create a 10x10 with '.' instead of zeroes, so that it would look better in the terminal. I decided to keep using 0 and only change to '.' in the printing process. I print the matrix every time I make a change. I use this function:

def printMatrixF(M):
    fM = M
    for i in range(10):
        for j in range(10):
            if fM[i][j] == 0:
                fM[i][j] = '.'
            print(fM[i][j],end=" ")
        print()

But this function is somehow changing the M value, even though I'm pretty sure it shouldn't. Here is a smaller portion of the code that shows my exact problem:

def createMatrix():
    a = [0]*10
    for i in range(10):
        a[i] = [0]*10
    return a

def printMatrix(M):
    for i in range(len(M)):
        print(M[i])

def printMatrixF(M):
    fM = M
    for i in range(10):
        for j in range(10):
            if fM[i][j] == 0:
                fM[i][j] = '.'
            print(fM[i][j],end=" ")
        print()

M = createMatrix()
printMatrix(M)
printMatrixF(M)
printMatrix(M)

The printMatrix() function only prints the matrix, and the printMatrixF() has the added change from 0 to '.' in it. This feels so dumb but I have no idea what's causing this.

(Edit: I'm using the same function but using if to revert back the '.'s to 0s (and it works I guess).

martineau
  • 119,623
  • 25
  • 170
  • 301
  • https://www.dataquest.io/blog/tutorial-functions-modify-lists-dictionaries-python/ – Pranav Hosangadi May 04 '22 at 18:41
  • 4
    `fM = M` doesn't make a copy of anything; you now just have a second name that refers to the matrix. There's no need to modify anything while printing, anyway: set a local variable to the element of matrix, then print either that or a dot. – jasonharper May 04 '22 at 18:42
  • @PranavHosangadi Oof, I'm toast. Can't use .copy() – propelledaviator May 04 '22 at 18:44
  • @jasonharper so I make a local variable for all the elements and print them? Would that just cause the same problem – propelledaviator May 04 '22 at 18:47
  • 3
    No, for each individual element as you loop through the matrix. `x = fM[i][j]` / `if x==0: print('.')` / `else: print(x)` for example. – jasonharper May 04 '22 at 19:25
  • 1
    Instead of changing a value in `M` or `fM` or anything else, just use conditional logic on the original value *to decide what to `print`*. – Karl Knechtel May 04 '22 at 19:51
  • `print` is a function in Python 3 and a statement in Python 2. – Nathan Mills May 05 '22 at 00:35
  • Does this answer your question? [How do I clone a list so that it doesn't change unexpectedly after assignment?](https://stackoverflow.com/questions/2612802/how-do-i-clone-a-list-so-that-it-doesnt-change-unexpectedly-after-assignment) – Nathan Mills May 05 '22 at 00:41

1 Answers1

1

The problem is that fM = M only assigns another name to object M refers to — so you need to make a copy of it. This could be done using the copy module, but since you can't use that, you can do it manually by making use of the copy() method that all list objects have.

In the code below I've created a copyMatrix(M) function to illustrate how to use it:

def createMatrix():
    a = [0]*10
    for i in range(10):
        a[i] = [0]*10
    return a

def printMatrix(M):
    for i in range(len(M)):
        print(M[i])

def copyMatrix(M):
    """Return a copy of matrix M."""
    mcopy = []
    for i in range(len(M)):
        # Append copy of sublist.
        mcopy.append(M[i].copy())  # Could also use M[i][:]
    return mcopy

def printMatrixF(M):
    fM = copyMatrix(M)
    for i in range(10):
        for j in range(10):
            if fM[i][j] == 0:
                fM[i][j] = '.'
            print(fM[i][j],end=" ")
        print()

M = createMatrix()
printMatrix(M)
print()
printMatrixF(M)
print()
printMatrix(M)

martineau
  • 119,623
  • 25
  • 170
  • 301