Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Arrays de dos dimensiones

8/23
Recursos

Aportes 38

Preguntas 5

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Solucion al reto 2 sin aplicar la clase Grid:

clase Cube:

main:

Mi soluciones al reto.

1ra Parte - Incorpora un método para poblar sus slots

from array_clase import Array
import random


class Grid():
    def __init__(self, rows, columns, fill_value=None):
        self.data = Array(rows)
        for row in range(rows):
            self.data[row] = Array(columns, fill_value=fill_value)

    def get_height(self):
        return len(self.data)

    def get_width(self):
        return len(self.data[0])

    def __getitem__(self, index):
        return self.data[index]

    def __str__(self):
        result = ""

        for row in range(self.get_height()):
            for col in range(self.get_width()):
                result += str(self.data[row][col]) + " "

            result += "\n"

        return str(result)

    def random_fill(self, min, max):
        for i in range(self.get_height()):
            for j in range(self.get_width()):
                self[i][j] = random.randint(min, max)

Prueba del reto

from array2D import Grid
matrix = Grid(3,3)
matrix.random_fill(1,100)
print(matrix)

Salida

72 97 45 
33 97 65
18 11 100

2° parte del reto
Array 3D

from array2D import Grid
from array_clase import Array
import random


class Array3D():
    def __init__(self,depth, rows, columns,fill_value=None):
        self.data = Grid(rows, columns)
        for row in range(rows):
            for column in range(columns):
                self.data[row][column] = Array(depth, fill_value=fill_value)

    def get_rows(self):
        return self.data.get_height()

    def get_columns(self):
        return self.data.get_width()

    def get_depth(self):
        return len(self.data[0][0])
    
    def __getitem__(self, index):
        return self.data[index]

    def __str__(self):
        result = ""

        for depth in range(self.get_depth()):
            result += f'index depth: [{depth}] \n'
            for row in range(self.get_rows()):
                for column in range(self.get_columns()):
                    result += f'   {self.data[row][column][depth]} '
                result += "\n"
            result += "\n"
        return str(result)

    def random_fill3D(self, min, max):
        for i in range(self.get_rows()):
            for j in range(self.get_columns()):
                for x in range(self.get_depth()):
                    self[i][j][x] = random.randint(min, max)


Prueba de la clase

from array3D import Array3D

tensor3D =  Array3D(depth=2,rows=4,columns=3)
print(tensor3D.get_rows())
print(tensor3D.get_columns())
print(tensor3D.get_depth())
print()
print(tensor3D)

tensor3D.random_fill3D(0,9)
print(tensor3D)

Salida

4
3
2

index depth: [0]
   None    None    None
   None    None    None
   None    None    None
   None    None    None

index depth: [1]
   None    None    None
   None    None    None
   None    None    None
   None    None    None


index depth: [0]
   7    0    7
   9    0    5
   9    4    6
   1    5    0

index depth: [1]
   4    2    2
   6    4    5
   7    7    2
   5    5    4

Primer profesor desde que estoy en Platzi que explica medio pelo…

Este es mi aporte:

Salida:

Me parece curioso que el método str de laguna manera es el método que se ejecuta cuando se usa la función print()
Si se fijan cualquier modificación que le hagan a este método se verá reflejada en el print() que le hagan al objeto de la clase Grid.

Pruébenlo y verán lo que suede. Metan algún print(“hola mundo”) en el str y se darán cuenta.

Reto 2:
Archivo MiCubo

from MiGrid import Grid
from MiArray import Array

class Cubo():

    def __init__(self, depth, rows, cols, value=None):
        self.__depth__ = depth
        self.__rows__ = rows
        self.__cols__ = cols

        self.cube = Array(depth, value)

        for depth in range(depth):
            self.cube.__setitem__(depth, Grid(rows, cols, value))
        

    def __getdepth__(self):
        return len(self.cube)

    def __getheight__(self):
        return self.cube.__getitem__(0).__getheight()
    
    def __getwidth__(self):
        return self.cube.__getitem__(0).__getwidth()

    def __getitem__(self, index):
        return self.cube.__getitem__(index)

    def __setitem__(self, deep, row, col, value):
        self.cube.__getitem__(deep).__setitem__(row, col, value)

    def __getvalue__(self, deep, row, col):
        return self.cube.__getitem__(deep).__getvalue__(row, col)
    
    def __populate__(self, random_number_end):
        for depth in range(self.__depth__):
            self.cube.__getitem__(depth).__populate__(random_number_end)

    def __str__(self):
        result = ''
        result += self.cube.__str__() + '\n\r'
        result += '[\n\r'
        for deep in range(self.__depth__):
            result += '\t' + self.cube.__getitem__(deep).__str__() + '\n\r'
        result += ']'
        return result
    


Podemos resolver el reto, utilizando las estructuras anteriores y llamando a sus metodos.

Challenge one:

Return:

Two:

Return:

Qué chévere, me divertí mucho haciendo ambos ejercicios. Comparto mi solución para el array-3D y un screenshot de la impresión formateada. 😋

Mi solución:

from arrays import Array

class Cube():

    def __init__(self, rows, columns, depth, fill_value = None):
        """
        Create tri-dimensional Arrays
        Giving numbers of rows, columns, and depth to get an Array
        """
        self.cube = [Array(columns, Array(depth)) for i in range(rows)]

    def get_height(self):
        return len(self.cube)

    def get_width(self):
        return len(self.cube[0])

    def get_depth(self):
        return len(self.cube[0][0])

    def __getitem__(self, index):
        return self.cube[index]

    def __str__(self):
        """
        Return string values from a tri-dimensional array
        """
        result = ""

        for row in range(self.get_height()):
            for column in range(self.get_width()):
                for depth in range(self.get_depth()):
                    result += str(self.cube[row][column][depth]) + " "
            
            result += "\n"
        
        return str(result)

Primer Reto: añade algo que pueble los espacios de los arrays, sean random o secuenciales.

def __setitem__(self, row, column, value):
        self.data[row][column] = value

    def __setRandints__(self):
        for i in range(self.get_height()):
            self.data[i] = [randint(0, self.get_width()) for i in range(self.get_width())] 

Hice una pequeña función setitem para que se pueda agregar manualmente.

Array 2D

class Grid():
    
    def __init__(self, rows, columns, fill_value=None):
        
        # Defines the rows of the array
        self.data = Array(rows)
        
        # Defines the columns of the array and set their default values
        for row in range(rows):
            self.data[row] = Array(columns, fill_value=fill_value)

    def get_height(self):
        return len(self.data)

    def get_width(self):
        return len(self.data[0])

    def __getitem__(self, row, column):
        return self.data[row][column]

    def __str__(self):
        string = ""

        for row in range(self.get_height()):
            for col in range(self.get_width()):
                string += str(self.data[row][col]) + " "

            string += "\n"

        return str(string)

    def __populate__(self, min_value, max_value):
        for row in range(self.get_height()):
            for column in range(self.get_width()):
                self.data[row][column] = random.randint(min_value, max_value)
                
        print(self)
from grid import Grid

class Cube:
    def __init__(self, rows, columns, depth, fill_values=None):
        self.data = []

        for cell in range(depth):
            self.data.append(Grid(rows, columns))
        
        print(self.data[0])
    

    def get_depth(self):
        return len(self.data)
    
    def get_height(self):
        return self.data[0].get_height()
    
    def get_width(self):
        return self.data[0].get_width()

    def __str__(self):
        result = ''

        for depth in range(self.get_depth()):
            result += '['
            for row in range(self.get_height()):
                result += '['
                for column in range(self.get_width()):
                    result +=  str(self.data[depth][row][column]) + ','
                result += '],\n'

            
            result += ']'

        return result
    

Mi solución al reto del cubo:

from array import Array
from random import randint

class Cube():
    def __init__(self, rows, columns, deeps, fill_value=None):
        self.data = Array(rows)
        for row in range (rows):
            self.data[row] = Array(columns)
            for col in range(columns):
                self.data[row][col] = Array(deeps, fill_value)
            
    def get_height(self):
        return len(self.data)
    
    def get_width(self):
        return len(self.data[0])
    
    def get_depth(self):
        return len(self.data[0][0])
    
    def __getitem__(self, index):
        return self.data[index]
    
    def __str__(self):
        result = "\n"*2
        for row in range(self.get_height()):
            result += "{ "
            for col in range(self.get_width()):
                for deep in range(self.get_depth()):
                    result += "[" + str(self.data[row][col][deep]) + "],"
                result = result[:-1] + " ; "
            result = result[:-3] + " }" + "\n"*2
        return str(result)
    
    def fill_cube_rand(self):
        for i in range(self.get_height()):
            for j in range(self.get_width()):
                for k in range(self.get_depth()):
                    self[i][j][k] =  randint(10, 100)
    
    def fill_cube_xyz(self):
        for i in range(self.get_height()):
            for j in range(self.get_width()):
                for k in range(self.get_depth()):
                    self[i][j][k]= f'{i},{j},{k}'
    


if __name__ == '__main__':
    hexaedro = Cube(7, 5, 2)
                
    print(f'\n  Height= {hexaedro.get_height()}, Width= {hexaedro.get_width()}, Depth= {hexaedro.get_depth()} \n')
    
    hexaedro_xyz = hexaedro
    hexaedro_xyz.fill_cube_xyz()
    print(hexaedro_xyz.__str__())     

    hexaedro.fill_cube_rand()
    print(hexaedro.__str__())     

Salida en Consola:

![](

Agregue la sumatoria de filas y columnas como totales

#sumando filas y columnas
    def __sumRow__(self):
        suma = 0
        for row  in range(self.get_height()):
            for column in range(self.get_width()):
                n = self[row][column]
                suma += n
            print('Fila ',row, 'Suma ', suma)

    def __sumCol__(self):
        suma = 0
        for column in range(self.get_width()):
            for row  in range(self.get_height()):
                n = self[row][column]
                suma += n
            print('Columna ',column, 'Suma ', suma)

y en el cube le agregue un random

def __randReplace__(self, min, max):
        for row  in range(self.get_height()):
            for column in range(self.get_width()):
                for depth in range(self.get_depth()):
                    self[row][column][depth] = random.randint(min, max)

oyeeee, no mames, eso esta genial profe

Mi reto quedó así:

from array import Array
from grid import Grid
import logging


logging.basicConfig(filename="platzi.log")
log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)


class Cube:

    def __init__(self, rows, columns, slots, fill_value=None):
        log.debug("Cube constructor")
        self.data = Grid(rows, columns)
        for row in range(rows):
            for column in range(columns):
                self.data[row][column] = Array(slots, fill_value)

    def get_height(self):
        log.debug("get_height method")
        return self.data.get_height()

    def get_width(self):
        log.debug("get_width method")
        return self.data.get_width()

    def get_depth(self):
        log.debug("get_depth method")
        return len(self.data[0][0])

    def __getitem__(self, index):
        log.debug("__getitem__ method")
        return self.data[index]

    def __str__(self):
        log.debug("__str__ method")
        result = ""
        for slot in range(self.get_depth()):
            for row in range(self.get_height()):
                for col in range(self.get_width()):
                    result += str(self.data[row][col][slot]) + " "
                result += "\n"
            result += "\n"
        return str(result)

Reto 1:
Archivo MiArray:

import random
from functools import reduce

class Array:

    def __init__(self, capacity, value=None):
        self.items = list()
        self.__capacity = capacity
        for i in range(capacity):
            self.items.append(value)

    def __len__(self):
        return len(self.items)

    def __str__(self):
        return str(self.items)

    def __iter__(self):
        return iter(self.items)

    def __getwidth__(self):
        return len(self.items)

    def __getitem__(self, index):
        return self.items[index]
    
    def __setitem__(self, index, value):
        self.items[index] = value

    def __populate__(self, random_ini, random_end):
        #Realizando pruebas verifico que este puede tirar número duplicados
        #self.items = random.choices(range(random_ini, random_end), k=self.__capacity)
        
        #No duplicamos los números
        self.items = random.sample(range(random_ini, random_end), self.__capacity)

    def __sum__(self):
        #Solo sirve para sumas
        #sum(self.items)
        return reduce(lambda a, b: a+b, self.items)

Archivo MiGrid

import functools
from MiArray import Array
import random
from functools import reduce

class Grid():

    def __init__(self, rows, cols, value=None):

        self.__cols__ = cols
        self.__rows__ = rows

        self.grid = Array(rows, value)
        for row in range(rows):
            self.grid.__setitem__(row, Array(cols, value))

    def __getrow__(self, row):
        return self.grid.__getitem__(row)

    def __setitem__(self, row, col, value):
        self.grid.__getitem__(row).__setitem__(col, value)

    def __getvalue__(self, row, col):
        get_row = self.__getrow__(row)
        return get_row.__getitem__(col)

    def __getheight__(self):
        return len(self.grid)

    def __str__(self):
        result = ''
        for row in range(self.__rows__):
            result += self.grid.__getitem__(row).__str__()
        return result

    def __getwidth__(self):
        return self.__getrow__(0).__getwidth__()

    def __populate__(self, random_number_end):
        for row in range(self.__rows__):
            self.grid.__getitem__(row).__populate__(0, random_number_end)
        return self.grid

    def __sum__(self):
        sum = 0
        for row in range(self.__rows__):
            sum += self.grid[row].__sum__()
        return sum

Me tomó cerca de 24 hs descubrir que debia usar los métodos creados en los otros módulos, y cómo usarlos. Pero creo que ya comprendí como funciona. Solo tengo un par de dudas respecto al doble guión bajo, si lo borro me da error.

from arrays import Array
from grid import Grid
from random import randint
from functools import reduce

class Cubo():
    def __init__(self, y, x, z, fill_value=None):
        self.data = Grid(y, x)
        for i in range(y):
            for j in range(x):
                self.data[i][j] = Array(z,fill_value)

    def get_height(self):
        return self.data.get_height()

    def get_width(self):
        return self.data.get_width()

    def get_deep(self):
        return len(self.data[0][0])

    def __getitem__(self, y, x): #esto creo que devuelve el espacio en memoria
        return self.data[y][x] #y le debo agregar el índice para pedir el elemento

    def __setitem__(self, y, x, z, new_item):
        self.__getitem__(y,x)[z] = new_item

    def __str__(self):
        result = ""

        for row in range(self.get_height()):
            for col in range(self.get_width()):
                result += "|"
                for deep in range(self.get_deep()):
                    result += str(self.__getitem__(row, col)[deep]) + " "
                result += "|"

            result += "\n"
        return str(result)

    def rand_replace(self, min= 0, max=9):
        for row in range(self.get_height()):
            for col in range(self.get_width()):
                for deep in range(self.get_deep()):
                    self.__setitem__(row,col,deep,randint(min, max))

    def order_replace(self, start=0):
        count= 0
        for row in range(self.get_height()):
            for col in range(self.get_width()):
                for deep in range(self.get_deep()):
                    self.__setitem__(row,col,deep,count)
                    count+=1

    def suma(self):
        sumatoria = 0
        for row in range(self.get_height()):
            for col in range(self.get_width()):
                sumatoria += reduce(lambda a, b: a+b, self.__getitem__(row,col))
        return(sumatoria)

![](

Lo logre, pero me ayude bastante de lo ya comentado

from grid_2 import Grid
from array_1D import Array
from random import randint

class Cube:
    def __init__(self, rows, columns, deep, fill_value = None):
        self.data = Grid(rows, columns)
        for row in range(rows):
            for col in range(columns):
                self.data[row][col] = Array(deep)
                
    def get_height(self):
        return (self.data.get_height())
    
    def get_width(self):
        return (self.data.get_width())
    
    def get_depth(self):
        return (len(self.data[0][0]))
    
    def __getitem__ (self, index):
        return (self.data[index])
    
    def __str__(self):
        result = ""
        for row in range(self.get_height()):
            for col in range(self.get_width()):
                for d in range(self.get_depth()):
                    result += str(self.data[row][col][d]) + " "
                
                result += "\n"
                
        return result
    
    def fill_values(self):
        for row in range(self.get_height()):
            for col in range(self.get_width()):
                for d in range(self.get_depth()):
                    self.data[row][col][d] = randint(1,15)

Mi solución al array de 3 dimensiones…

import random
from customArray import Array
from customGrid import Grid

class Cube:

    def __init__(self, rows: int, columns: int, depth: int, fill_value: int = None):
        self.data = Grid(rows , columns)
        for row in range(rows):
            for column in range(columns):
                self.data[row][column] = Array(depth, fill_value)

    def get_height(self):
        "Returns the height of the cube"
        return self.data.get_height()
    
    def get_width(self):
        "Returns the width of the cube"
        return self.data.get_width()
    
    def get_depth(self):
        "Returns the depth of the cube"
        return len(self.data[0][0])

    def get_item(self, index: int):
        "Returns an item of the cube"
        return self.data[index]
    
    def set_item(self, row, column, depth, new_item):
        "Sets an item in a certain position of the 3 dimensional array"
        self.data[row][column][depth]= new_item

    def __str__(self):
        "String representation of the 3 dimensional array"
        result=""
        print("\n")
        for deep in range(self.get_depth()):
            for row in range(self.get_height()):
                for column in range(self.get_width()):
                    result += str(self.data[row][column][deep]) + " "
                result += "\n"
            result += f"Grid {deep+1}\n\n"
        return result

    def randomitems(self, min:int, max: int):
            "Sets random items to the 3 dimensional array"
        for deep in range(self.get_depth()):
            for row in range(self.get_height()):
                for column in range(self.get_width()):
                    self.data[row][column][deep]= random.randint(min, max)

Debo admitirlo, me ayudó Github Copilot. Y es que a mí siempre se me ha hecho muy difícil visualizar (soy una persona EXTREMADAMENTE visual) objetos 3D en pantallas (que son 2D).


pues asi hice el reto

class Matrix:
    def __init__(self,tam_x, tam_y, tam_z, valor = None):
        self.lista = []
        self.RE_dimencionar(tam_x, tam_y, tam_z,valor,False)



    def RE_dimencionar(self, tam_x, tam_y, tam_z, valor = None, MANTENER_VALOR = True):
        nueva_lista = []
        val = valor
        for x in range(tam_x):
            lista_temp_x = []
            nueva_lista.append(lista_temp_x)
            for y in range(tam_y):
                lista_temp_y = []
                lista_temp_x.append(lista_temp_y)
                for z in range(tam_z):
                    if MANTENER_VALOR:
                        val = self.dameValor(x,y,z,ADVERTENCIA = False)
                        if valor != None and val == None:
                            val = valor
                    lista_temp_y.append(val)
        self.lista = nueva_lista
    


    def cambiaValor(self, index = 0, sub_index = 0, hiper_sub_index = 0, valor = None):
        if self.dameValor(index,sub_index,hiper_sub_index) == None:
                return
        self.lista[index][sub_index][hiper_sub_index] = valor



    def dameValor(self, i_x = 0, i_y = None, i_z = None, ADVERTENCIA = True):
        if type(i_x) == int and i_y == None and i_z == None:
            try:
                return self.lista[i_x]
            except IndexError:
                pass
        elif  type(i_x) == int and type(i_y) == int and i_z == None:
            try:
                return self.lista[i_x][i_y]
            except IndexError:
                pass
        elif  type(i_x) == int and type(i_y) == int and type(i_z) == int:
            try:
                return self.lista[i_x][i_y][i_z]
            except IndexError:
                pass

        if ADVERTENCIA:
            print("ERROR al pasar el indice")
        return None



    def imprime(self):
        for x in self.lista:
            print("->",end="")
            for y in x:
                print("|" ,end= " ")
                for z in y:
                    print(f"{z}",end=" ")
                print("|",end= "")
            print("<-",)

    def __iter__(self):
        return iter(self.lista)



if __name__ == "__main__":
    print("\n normal\n")
    matris = Matrix(3,2,3,"hi")
    matris.imprime()
    print("\n Redimencionada\n")
    matris.RE_dimencionar(4,3,3,"XD")
    matris.imprime()
from arrayClass import Array
from gridClass import Grid

class Cube:
  def __init__(self, row,col,deep):
    self.data = Array(row)
    for d in range(deep):
      self.data[d] = Grid(col,deep)

  def get_height(self):
    return len(self.data )

  def get_width(self):
    return len(self.data[0])

  def get_deep(self):
    return len(self.data[0][0])

  def __getitem__(self,index):
    return self.data[index]

Hola, teniendo en cuenta el concepto de herencia, quería compartir la forma en que yo crearía un array de múltiples dimensiones, empleando la clase Array que se creó en la clase anterior:

<class nD_array(Array):

  def __init__(self, dim, capacity, fill=None):
    super().__init__(dim, fill_value=Array(capacity, fill_value=fill))> 

El único inconveniente que encontré es que al momento de hacer un print cuando se crea una instancia de nD_array es que no salen los arrays como tal, sino que indica es a que clase pertenece cada item así:

<two_dim_array = nD_array(2, 5)

print(twi_dim_array)> 

El output es:

[<main.Array object at 0x7fd9583b4bd0>, <main.Array object at 0x7fd9583b4bd0>]

BTW: lo hice antes de ver la clase, XD jajaj

Mi solución a los retos:

grid

from .array import Array

class Grid(object):
    """Two dimensional Array """

    def __init__(self, nrows, ncols, value=None) -> None:
        """Initializes the Arrays with nrows, ncols and optional value"""
        self.data = Array(nrows)
        for nrow in range(nrows):
            self.data[nrow] = Array(ncols, value)

    def __getheight__(self) -> int:
        """Returns the Arrays's height"""
        rows = self.data
        res: int = 0
        for i in rows:
            res += 1
        return res

    def __getwidth__(self) -> int:
        """Returns the Arrays's width"""
        cols = self.data[0]
        res: int = 0 #  Probando nuevos features de python 3.9
        for i in cols:
            res += 1
        return res

    def __getrow__(self, index) -> any:
        """Returns the index-th row"""
        try:
            if index == 0:
                raise IndexError('Index out of range')
            return self.data[index - 1]
        except IndexError as e:
            print(e)

    def __getelement__(self, index_x, index_y) -> any:
        """Returns the value of the index (x,y)"""
        try:
            if index_x == 0 or index_y == 0:
                raise IndexError('Index out of range')
            return self.data[index_x][index_y]
        except IndexError as e:
            print(e)

    def __str__(self) -> str:
        """Returns string representation of the grid"""
        rows = self.data
        res = ""
        for nrow in range(self.__getheight__()):
            for ncol in range(self.__getwidth__()):
                res += str(rows[nrow][ncol]) + " "
            res += "\n"
        return res

    def __fillvalues__(self) -> None:
        """Fills the array with random values"""
        for nrow in range(self.__getheight__()):
            for ncol in range(self.__getwidth__()):
                self.data[nrow][ncol] = nrow * ncol

cube


from .array import Array
from .grid import Grid

class Cube(object):
    """three-dimensional array"""

    def __init__(self, nrows, ncols, deep, value=None) -> None:
        """Initializes the Cube with nrows, ncols, deep and optional value"""
        self.data = Array(deep)
        for i in range(deep):
            self.data[i] = Grid(nrows, ncols, value)

    def __getdeep__(self) -> int:
        """Return the whole cube"""
        return len(self.data)

    def __str__(self) -> str:
        """Return the cube as a string"""
        result = ""
        for array in range(self.__getdeep__()):
            result += self.data[array].__str__()
            result += "\n"
        return str(result)


En mi caso utilicé las demas clases que creamos para hacer más corto el script:
Clase cube:

from grid import Grid
from arrays import Array

class Cube():

    def __init__(self, rows, columns, arrays, fill_value=None):
        self.data = Array(arrays)
        for i in range(arrays):
            self.data[i] = Grid(rows, columns)
        
    def get_arrays(self):
        return len(self.data)
    
    def get_columns(self):
        return self.data[0].get_columns()

    def get_rows(self):
        return self.data[0].get_rows()

    def __str__(self):
        result = ""
        for array in range(self.get_arrays()):
            result += self.data[array].__str__()
            result += "\n"
        return str(result)

    def fill_random_arrays(self, lower_value, upper_value):
        for i in range(self.get_arrays()):
            self.data[i].fill_random(lower_value, upper_value)

clase grid:

from arrays import Array

class Grid():

    def __init__(self, rows, columns, fill_value=None):
        self.data = Array(rows)
        for row in range(rows):
            self.data[row] = Array(columns)

    def get_rows(self):
        return len(self.data)
    
    def get_columns(self):
        return len(self.data[0])

    def get_element(self, row, column):
        return self.data[row][column]

    def __str__(self):
        result = ""
        for row in range(self.get_rows()):
            result += self.data[row].__str__()
            result += "\n"
        return str(result)

    def fill_random(self, lower_value, upper_value):
        for i in range(self.get_rows()):
            self.data[i].__fill_randomvalues__(lower_value, upper_value)

clase array:

import random 
from functools import reduce

class Array():
    def __init__(self, capacity, fill_value = None):
        self.items = list()
        for i in range(capacity):
            self.items.append(fill_value)

    def __len__(self):
        return len(self.items)

    def __str__(self):
        result = ""
        for i in range(self.__len__()):
            result += str(self.items[i]) + " "
        return result

    def __iter__(self):
        return iter(self.items)

    def __getitem__(self, index):
        return self.items[index]

    def __setitem__(self, index, value):
        self.items[index] = value
    
    def __fill_randomvalues__(self, lower_value, upper_value):
        self.items = [random.randint(lower_value, upper_value) for i in range(self.__len__())]
    
    def __fill_secuencialnumbers__(self, start_number, incrase):
        self.items = [start_number + incrase * i for i in range(self.__len__())]

    def __sumelements__(self):
        return reduce(lambda start, finish: start+finish, self.items)

Reto

Les comparto mi solución del reto.

Representación

Código

"""Case 8 - Matrices

Crear representación de una matriz de 3 dimenciones
"""


class DimensionMixin:
    _size = 0
    _items = None
    
    def __len__(self):
        return self._size

    def __str__(self):
        return str(self._items)
    
    def __iter__(self):
        return iter(self._items)

    def __getitem__(self, index):
        return self._items[index]

    def __setitem__(self, index, value):
        self._items[index] = value

    def __repr__(self):
        return str(self)


class Array(DimensionMixin):
    """Representasión de un array."""
    def __init__(self, size : int, fill=None):
        self._items = list()
        self._size = size

        for i in range(size):
            self._items.append(fill)


class Grid(DimensionMixin):
    """Representación de una matríz de 2 dimensiones"""

    def __init__(self, cols: int, rows: int, fill=None) -> None:
        self._items = Array(rows, fill)
        self._cols = cols
        self._rows = rows
        self._size = rows

        for i in range(rows):
            self._items[i] = Array(cols, fill)

    @property
    def count_colums(self):
        """Matrix width"""
        return self._cols
    
    @property
    def count_rows(self):
        """Matrix height"""
        return self._rows

    def get_item_by_coords(self, row_index: int, col_index: int):
        return self._items[row_index][col_index]

    def __repr__(self):
        output = '';

        for r_idx in range(self._rows):
            output += '\n' + repr(self._items[r_idx])
        return output


class Cube(DimensionMixin):
    """Representación de matríz de 3 dimensiones."""

    def __init__(self, depth: int, rows: int, cols: int, fill=None) -> None:
        self._size = depth
        self._depth = depth
        self._cols = cols
        self._rows = rows

        self._items = Array(depth)

        for z in range(depth):
            self._items[z] = Grid(cols, rows, fill)

   @property
   def depth(self):
        return self._depth
    
    @property
    def cols(self):
        return self._cols
    
    @property
    def rows(self):
        return self._rows

    def get_item_by_coords(self, x: int, y: int, z: int):
        return self._items[z][y][z]

    def __repr__(self):
        output = '';
        for idx in range(self._size):
            output += '\n' + str(self._items[idx])
        return output

import random
from prueba import Array

class Cube:
    def __init__(self, rows, depth, columns, fill_value=None):
        self.data = Array(rows)
        for row in range(rows):
            self.data[row] = Array(columns)
            for col in range(columns):
                self.data[row][col] = Array(depth, fill_value=None)


    def get_height(self):
        return len(self.data)


    def get_width(self):
        return len(self.data[0])
    
    def get_depth(self):
        return len(self.data[0][0])

    def __getitem__(self, index):
        return self.data[index]

    def __rempitem__(self, name_array):
        for row in range(name_array.get_height()):
            for column in range(name_array.get_width()):
                for depth in range(name_array.get_depth()):
                    matrix[row][column][depth] = str(random.randint(0, 9)) + " "

    def __str__(self):
        result = ''

        for row in range(self.get_height()):
            for col in range(self.get_width()):
                result += str(self.data[row][col]) + " "
            
            result += '\n'

        return str(result)

if __name__ == '__main__':
    matrix = Cube(3, 3, 3)
    matrix.__rempitem__(matrix)

    print(matrix)

Aquí mi solución al Reto 2 utilizando la definición de cubo y reutilizando la clase Grid!

class Cube:

    def __init__(self, edge_length):
        self.data = []
        for _ in range(edge_length):
            self.data.append(Grid(edge_length, edge_length)

    def __getitem__(self, index):
        return self.data[index]

    def __str__(self):
        result = ""
        for grid in self.data:
            result += str(grid) + "\n"
        return result

Aquí mi código. No es posible imprimir un objeto tridimensional en la terminal (2d), pero si es posible representarlo en manera de grupos, osea, en arrays de arrays (que es como lo interpreta numpy por ejemplo)

Channels es como definí la tercera dimensión, que es común llamarla así cuando se trabaja con imágenes, que es donde es más común encontrar arrays de mas de dos dimensiones. La manera en la que implemente el el método __str__ es parecida a la de numpy, para presentar de una manera visible el array de tres dimensiones

from array import Array

class Cubo():

    def __init__(self, channels, rows, columns, fill_value=None):
        self.cubic = Array(channels, fill_value)
        for channel in range(channels):
            self.cubic[channel] = Array(rows, fill_value)
            for row in range(rows):
                self.cubic[channel][row] = Array(columns, fill_value)

    def get_channel(self):
        return len(self.cubic)

    def get_height(self):
        return len(self.cubic[0])

    def get_width(self):
        return len(self.cubic[0][0])

    def __str__(self):

        print("[", end="")
        for channel in range(self.get_channel()):
            print("[", end="")
            for row in range(self.get_height()):
                print("[", end="")
                for column in range(self.get_width()):
                    print(f" {self.cubic[channel][row][column]} ", end="")
                print("] \n  ", end="")
            print("] \n", end="")
        print("]", end="")

        return ""


Solución reto 2:

class Grid(object):
    def __init__(self, rows, columns, fill_value=None):
        self.data = Array(rows)
        self.rows = rows
        self.columns = columns

        for row in range(rows):
            self.data[row] = Array(columns, fill_value)

    # reto 2
    def __random_fill__(self):

        for row in range(self.rows):
            for column in range(self.columns):
                self.data[row][column] = row * column

para imprimir los valores en consola, basta con usar el metodo str que definimos en clase:

if __name__ == '__main__': 
    matrix = Grid(3, 3)
    print(matrix.__random_fill__())
    print(matrix.__str__())

Reto parte 2:
No se si lo hice bien, porque no se como imprimierlo para que se vean en 3 dimensiones jajaja pero bueno les dejo lo que saque

from array_py import Array
from grid import Grid


class Tensor:
	def __init__(self, rows, columns, deep, fill_value=None):
		self.tensor = Grid(rows, columns, fill_value)

		for i in range(rows):
			for j in range(columns):
				self.tensor[i][j] = Array(deep, fill_value)

	def get_height(self):
		return self.tensor.get_height()

	def get_width(self):
		return self.tensor.get_width()

	def get_deep(self):
		return len(self.tensor[0][0])

	def __getitem__(self, idx):
		return self.tensor[idx]

	def __str__(self):
		result = ""
		for row in range(self.get_height()):
			for col in range(self.get_width()):
				for deep in range(self.get_deep()):
					result += str(self.tensor[row][col][deep]) + " "
				result += '\n'

		return str(result)

	def fill(self):
		for i in range(self.get_height()):
			for j in range(self.get_width()):
				self.tensor[i][j].fill()

Nuevos métodos para mi grid

from customArray import Array
import random

class Grid:
    def __init__(self, rows: int, columns: int, fill_value: int = None):
        self.data = Array(rows)
        
        for row in range(rows):               
            self.data[row] = Array(columns, fill_value) #Doing so it implements the dunder method __setitem__() of the class Array
    
    def get_height(self):
        return len(self.data) #Doing so it implements the dunder method __len__() of the class Array  
        #self.data.__len__.()            
        
    def get_width(self):
        return len(self.data[0]) #Doing so it implements the dunder method __len__() of the class Array            

    def __getitem__(self, index: int):
        return self.data.__getitem__(index)
        #return self.data[index] #Doing so it implements the dunder method __getitem__() of the class Array
    
    def __str__(self):
        result = ""
        
        for row in range(self.get_height()):
            for column in range(self.get_width()):
                result += str(self.data[row][column]) + " "
            result += "\n"
        return str(result)

    def randomitems(self, min: int , max: int):        
        for row in range(self.get_height()):
            for column in range (self.get_width()):
                self.data[row][column]=random.randint(min, max)
    
    def sumitems(self):
        sum = 0
        for row in range(self.get_height()):
            for column in range(self.get_width()):
                sum += sum + self.data[row][column]
        return sum
    
    def max_item(self):
        max = 0
        for row in range(self.get_height()):
            for column in range(self.get_width()):
                if self.data[row][column]>max:
                    max = self.data[row][column]
        return max
    
    def min_item(self):
        min = 0
        for row in range(self.get_height()):
            for column in range(self.get_width()):
                if self.data[row][column]<min:
                    min = self.data[row][column]
        return min

Reto parte 1 y 2

Clase Grid con poblado de datos

from array_py import Array


class Grid:
	def __init__(self, rows, columns, fill_value=None):
		self.data = Array(rows)

		for i in range(rows):
			self.data[i] = Array(columns, fill_value)

	def get_height(self):
		return len(self.data)

	def get_width(self):
		return len(self.data[0])

	def __getitem__(self, idx):
		return self.data[idx]

	def __str__(self):
		result = ""
		for row in range(self.get_height()):
			for col in range(self.get_width()):
				result += str(self.data[row][col]) + " "
			result += '\n'

		return str(result)

	def fill(self):
		for i in range(self.get_height()):
			self.data[i].fill()

Resultaos: