1

The Objective

I need to take an array with data that can be displayed in 2 dimensions, and paste it over any part of a 2D array as if it were an image. This function would be similar to the Python library Pillow's paste function.

Example

Say I have a 2D array with a size of 5x5, with a default value of 0.

[
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0]
]

And I have an average array with the length of 4, which can be assembled into 2x2 form.

[0, 1, 
 1, 1]

With this, I need a function to, as if these arrays were images, 'paste' the second over the first. With a position (anchored from the top left) of (1,2), it would result in this 2D array.

[
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 1, 0, 0],
 [0, 1, 1, 0, 0],
 [0, 0, 0, 0, 0]
]

My Attempt

Here is my attempt at creating the Python code.

class Indexed:
    def __init__(self, x, y):
        self.array = [[0]*x]*y
        self.dimensions = (x, y)

    def writeImage(self, indexed, x, y, width, height):
        index = 0
        for ArrayY in range(height):
            self.array[ArrayY] = [0]*self.dimensions[0]
            for ArrayX in range(width):
                self.array[1 + ArrayY][x + ArrayX] = indexed[index]
                index+=1
                
Test = Indexed(12,12)
Test.writeImage(
        [
            0,0,7,0,0,7,0,0,
            0,0,7,0,0,7,0,0,
            0,0,7,0,0,7,0,0,
            7,0,0,0,0,0,0,7,
            7,7,7,7,7,7,7,7
        ],
        0,0, 8,5
    )
print(Test.array)

The Problem

If you attempt to run the code above, you will see that it outputs this result.

[
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
 [7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0], 
 [7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0], 
 [7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0], 
 [7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0], 
 [7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0], 
 [7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0], 
 [7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0]
]

This is the intended result.

[
 [0, 0, 7, 0, 0, 7, 0, 0, 0, 0, 0, 0], 
 [0, 0, 7, 0, 0, 7, 0, 0, 0, 0, 0, 0], 
 [0, 0, 7, 0, 0, 7, 0, 0, 0, 0, 0, 0], 
 [7, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0], 
 [7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0], 
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]

I've tinkered with it a lot and haven't found any answers online for why these arrays work the way they do here.

Any help is greatly appreciated.

Bobbo-Cat
  • 13
  • 3
  • 1
    What do you mean by ***array***? In *NumPy* this can be done via a single (assignment + slicing) statement. Also *writeImage*'s last 2 arguments could (**should**) be inferred from *indexed*. – CristiFati Apr 23 '22 at 09:34
  • @CristiFati writeImage's last two arguments are meant to specify the width and height of the array you are passing in. The input **array** I pass through with the width and height could be a 2D array as well, however with how I receive the data I believe it would be too much of a hassle to paste onto a 2D array using a 2D array. The best way I can describe this process is like pasting one smaller picture (Input array) over a larger one (Indexed.array). – Bobbo-Cat Apr 23 '22 at 09:51
  • By *array* I meant it's a list, a tuple an *NumPy* array? Because some already have this functionality built-in. I now see the input array is a *1D* one. https://stackoverflow.com/questions/12791501/why-does-this-code-for-initializing-a-list-of-lists-apparently-link-the-lists-to. – CristiFati Apr 23 '22 at 12:50

1 Answers1

0

When you initialise self.array [[0]*x]*y. The [0]*x is only shallow copied (reference only) y times, which means all of the row is basically the same array.

Since it is the same array, it's final value would be the last row, i.e. 7,7,7,7,7,7,7,7. Thats why the one updated is such value.

Also noted the index is incorrect in the writeImage

from pprint import pprint

class Indexed:
    def __init__(self, x, y):
        self.array = [0]*y
        for i in range(y):
            self.array[i] = [0]*x
        self.dimensions = (x, y)

    def writeImage(self, indexed, x, y, width, height):
        for ArrayY in range(height):
            for ArrayX in range(width):
                index = (ArrayY * width) + ArrayX
                self.array[y + ArrayY][x + ArrayX] = indexed[index]
                
Test = Indexed(12,12)
Test.writeImage(
        [
            0,0,7,0,0,7,0,0,
            0,0,7,0,0,7,0,0,
            0,0,7,0,0,7,0,0,
            7,0,0,0,0,0,0,7,
            7,7,7,7,7,7,7,7
        ],
        0,0, 8,5
    )
pprint(Test.array)
Leo
  • 16
  • 1