Hola a todos,

    Hace tiempo escribí esto, igual te sirve aunque falta pulirlo.

Saludos.

#!/usr/bin/env python
# -*- coding: utf-8 -*-


class Vector(list):
    '''Vector de tamaño fijo con/sin comprobación de tipo'''

    def __new__(cls, *args, **kwargs):
        # Internamente los elementos del vector se almacenan en una lista.
        return list.__new__(cls, *args, **kwargs)

def __init__(self, length, default_value=None, initial_values=None, typed=True):
        # El vector tendrá el tamaño indicado por length.
# Los elementos del vector se inicializan con los elementos de initial_values. # Si len(initial_values) < length el vector se rellena con default_value
        # hasta alcanzar la longitud requerida.
# Si len(initial_values) > length se descartan los elementos de initial_values
        # con indice mayor a length.
# Si todos los elementos de initial_values y default_value tienen el mismo # tipo el vector será de dicho tipo y solo podra almacenar valores de # ese tipo. En caso contrario el vector no tendra tipo y podra almacenar
        # elementos de cualquier tipo.
# Si typed == False no se tendra en cuenta el tipo de los elementos.

        try:
            same_type = True
            l = len(initial_values)
            for i in range(length):
                if i < l:
                    self.append(initial_values[i])
same_type = same_type and (type(default_value) == type(initial_values[i]))
                else:
                    self.append(default_value)
        except:
            self.extend([default_value]* length)
        finally:
            self.__length = length
self.__type = type(default_value) if (same_type and typed) else type(None)


    def __setitem__(self, index, value):
        # Comprobamos el tipo antes de insertar un elemento.
        if self.__type == type(value) or self.__type == type(None):
            super(Vector, self).__setitem__(index, value)
        else:
            # Elemento de tipo incorrecto, no se inserta.
            raise ValueError

    def __setslice__(self, i, j, sequence):
        # Impedimos este método para que altere el tamaño del vector.
        # TODO: hacer lo mismo con el resto de métodos de la clase list que
        # pueden cambiar el tamaño del vector.
        raise ValueError # FIXME: poner la excepción correcta.

    def __count__(self):
        return self.__length

    @property
    def type(self):
        return self.__type

    @property
    def length(self):
        return self.__length


class Matrix(Vector):
    '''Matriz bidimensional de tamaño fijo con/sin comprobación de tipo'''

def __init__(self, cols, rows, default_value=None, initial_values=None, typed=True):
        # Indicamos el número de columnas y filas de la matriz.
        self.__cols = cols
        self.__rows = rows
super(Matrix, self).__init__(cols * rows, default_value, initial_values, typed)

    def __setitem__(self, index, value):
        # FIXME: interceptar índices no válidos.
        col, row = index
        index = self.__cols * row + col
        super(Matrix, self).__setitem__(index, value)

    def __getitem__(self, index):
        # FIXME: interceptar índices no válidos.
        col, row = index
        index = self.__cols * row + col
        return super(Matrix, self).__getitem__(index)

    def __repr__(self):
        result = ""
        for i in range(0, self.length, self.cols):
result += "[%s]" % ", ".join([str(s) for s in self[i: i + self.cols]])
        return "[%s]" % result

    def __str__(self):
        result = ""
        for i in range(0, self.length, self.cols):
result += "%s\n" % " ".join([str(s) for s in self[i: i + self.cols]])
        return result

    @property
    def cols(self):
        return self.__cols

    @property
    def rows(self):
        return self.__rows

    def row(self, index):
        '''Devuelve la fila con índice index'''
        # FIXME: comprobar limites
        i = index * self.__cols
        return self[i:i + self.__cols]

    def col(self, index):
        '''Devuelve la columna con índice index'''
        # FIXME: comprobar limites
        return [self[index, i] for i in range(self.__cols)]

    def submatrix(self, ix, iy, jx, jy):
        '''Devuleve una submatrix de la matrix'''
        m = []
        for y in range(iy, jy + 1):
            k = y * self.__cols
            m.append(self[k + ix:k + jx + 1])
        # OJO!! el valor devuelto es un lista y no de la clase matrix
        return m

    def list(self):
        '''Devuleve los elementos de la matrix como una lista'''
        return list(self)

    def sublist(self, ix, iy, jx, jy):
        '''Devuleve una submatrix de la matrix en forma de lista'''
        l = []
        for y in range(iy, jy + 1):
            k = y * self.__cols
            l.extend(self[k + ix:k + jx + 1])
        # OJO!! el valor devuelto es un lista y no de la clase matrix
        return l

def main():
    a = Vector(10, 5,[])
    a[3] = 4
    print a
    b = Vector(15, 2, [x for x in range(10)], False)
    print b
    print b.length
    print b.type
    b[1] = 'a'
    print b
    m = Matrix(3, 3, 0)
    m[0, 0] = 1
    m[1, 0] = 2
    m[2, 0] = 3
    m[0, 1] = 4
    m[1, 1] = 5
    m[2, 1] = 6
    m[0, 2] = 7
    m[1, 2] = 8
    m[2, 2] = 9
    print m
    print repr(m)
    x, y = 1, 1
    print "item[%d, %d]: % d" % (x, y, m[x, y])
    print "total items: %d" % len(m)
    row = m.row(0)
    print "row[0]: ", row
    col = m.col(0)
    print "col[0]: ", col
    submatrix = m.submatrix(0,0,1,1)
    print "submatrix[0,0][1,1]: ", submatrix
    print 1 in submatrix
    print 11 in submatrix
    print m.list()
    sublist = m.sublist(0,0,1,1)
    print "sublist[0,0][1,1]: ", sublist
    print 1 in sublist
    print 11 in sublist
    m2 = Matrix(4,4, 1, [1,2,3,4], False)
    print m2
    print m2.length
    print m2.type

if __name__ == '__main__':
    main()
_______________________________________________
Python-es mailing list
Python-es@python.org
http://mail.python.org/mailman/listinfo/python-es
FAQ: http://python-es-faq.wikidot.com/

Responder a