Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 4, 2018 21:31:20

Comandante4
Зарегистрирован: 2017-12-25
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Реализация класса Matrix

Добрый вечер. Нужна помощь:

1. Реализуйте класс Matrix. Он должен содержать:
Конструктор от списка списков. Гарантируется, что списки состоят из чисел, не пусты и все имеют одинаковый размер. Конструктор должен копировать содержимое списка списков, т.е. при изменении списков, от которых была сконструирована матрица, содержимое матрицы изменяться не должно.
Метод __str__ переводящий матрицу в строку. При этом элементы внутри одной строки должны быть разделены знаками табуляции, а строки — переносами строк. При этом после каждой строки не должно быть символа табуляции и в конце не должно быть переноса строки.
Метод size без аргументов, возвращающий кортеж вида (число строк, число столбцов)
На проверку вы должны сдать только файл, содержащий описание класса и одну строку вне класса (в качестве основной программы):

exec(stdin.read())

И в начале файла:

from sys import stdin

Для тестирования класса вы можете вместо строки exec(stdin.read()) вставлять код из примеров или писать свой код.

Формат ввода

Вводится исходный код тестирующей программы на языке Python.

Формат вывода

Выведите результат её работы в текущем окружении при помощи exec как это указано в условии.


2. Добавьте в предыдущий класс следующие методы:
__add__ принимающий вторую матрицу того же размера и возвращающий сумму матриц
__mul__ принимающий число типа int или float и возвращающий матрицу, умноженную на скаляр
__rmul__ делающий то же самое, что и __mul__. Этот метод будет вызван в том случае, аргумент находится справа. Можно написать __rmul__ = __mul__

В Pycharm на компьютере тест

 m = Matrix([[10, 10], [0, 0], [1, 1]])
print(m.size())
проходится,
 (3, 2)
а тестировщик на сайте выдаёт Runtime Error.
Может, кто-нибудь сможет посоветовать, что исправить?
 from sys import stdin
from copy import deepcopy
import numpy
class Matrix:
    def __init__(self, list_of_lists):
        self.matrix = deepcopy(list_of_lists)
    def __str__(self):
        return '\n'.join('\t'.join(map(str, row))
                         for row in self.matrix)
    def size(self):
        sizepair = (len(self.matrix), len(self.matrix[0]))
        return sizepair
    def __getitem__(self, idx):
        return self.matrix[idx]
    def __add__(self, other):
        other = numpy.matrix(other)
        result = []
        numbers = []
        for i in range(len(self.matrix)):
            for j in range(len(self.matrix[0])):
                summa = other[i][j] + self.matrix[i][j]
                numbers.append(summa)
                if len(numbers) == len(self.matrix):
                    result.append(numbers)
                    numbers = []
        return Matrix(result)
    def __mul__(self, other):
        m1 = numpy.array(self.matrix)
        return Matrix(m1 * other)
    def __rmul__(self, other):
        m2 = numpy.array(self.matrix)
        return Matrix(other * m2)
exec(stdin.read())

Отредактировано Comandante4 (Янв. 4, 2018 21:46:46)

Прикреплённый файлы:
attachment Безымянный-1.jpg (196,2 KБ)

Офлайн

#2 Янв. 5, 2018 03:06:12

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10003
Репутация: +  857  -
Профиль   Отправить e-mail  

Реализация класса Matrix

Comandante4
  
    def __add__(self, other):
        other = numpy.matrix(other)
И при чём тут numpy? Подавать нужно такую же матрицу и залазить у неё в self.matrix . На входе сравнивать размерности обеих матриц; если не равны, выдавать исключение ещё до начала суммирования.

Comandante4
  
    def __getitem__(self, idx):
        return self.matrix[idx]
Метод __getitem__ должен принимать i и j и по ним доставать элемент матрицы.

Comandante4
  
    def __mul__(self, other):
        m1 = numpy.array(self.matrix)
        return Matrix(m1 * other)
    def __rmul__(self, other):
        m2 = numpy.array(self.matrix)
        return Matrix(other * m2)
Там же написано в задании, что умножение матрицы на число коммутативно и можно просто сделать один метод, при этом второй метод просто сделать в виде ссылки на первый метод.

И numpy нигде в задании нет. Модуль numpy не является стандартным модулем питона, и поэтому запросто может отсутствовать где-нибудь, где твой скрипт будут запускать. Поэтому его и не дают использовать чаще всего.

Comandante4
а тестировщик на сайте выдаёт Runtime Error.
Обычно это значит, что что-то в коде слишком долго выполняется (если оно у тебя запускается, а на сайте то же самое выдаёт Runtime Error).



Отредактировано py.user.next (Янв. 6, 2018 02:34:49)

Офлайн

#3 Янв. 5, 2018 17:53:30

Comandante4
Зарегистрирован: 2017-12-25
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Реализация класса Matrix

py.user.next
В _add_ исправил. Но, честно говоря, умножение матрицы на скаляр без numpy получается реализовать плохо. Например (без привязки к _mul_):
 m = [[1, 1, 0], [0, 2, 10], [10, 15, 30]]
alpha = 15
m1 = list()
for i in range(len(m)):
    for j in range(len(m[0])):
        m1.append(m[i][j] * alpha)
print(m1)
Вывод получается таким:
 [15, 15, 0, 0, 30, 150, 150, 225, 450]
Хотелось бы на выходе всё-таки получить список списков. В общем-то, добавления полученного в ещё один список тоже не помогает.

Отредактировано Comandante4 (Янв. 5, 2018 17:54:04)

Офлайн

#4 Янв. 5, 2018 18:09:11

vic57
Зарегистрирован: 2015-07-07
Сообщения: 913
Репутация: +  127  -
Профиль  

Реализация класса Matrix

 >>> m = [[1, 1, 0], [0, 2, 10], [10, 15, 30]]
>>> out = []
>>> for i in m:
	tmp = []
	for j in i:
		tmp.append(j*15)
	out.append(tmp)
	
>>> out
[[15, 15, 0], [0, 30, 150], [150, 225, 450]]
>>> 

Офлайн

#5 Янв. 5, 2018 19:13:27

Comandante4
Зарегистрирован: 2017-12-25
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Реализация класса Matrix

py.user.next
vic57

Благодарю ! Вы очень помогли

Офлайн

#6 Янв. 6, 2018 02:36:33

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10003
Репутация: +  857  -
Профиль   Отправить e-mail  

Реализация класса Matrix

Comandante4
Но, честно говоря, умножение матрицы на скаляр без numpy получается реализовать плохо.
  
>>> m = [[1, 1, 0], [0, 2, 10], [10, 15, 30]]
>>> alpha = 15
>>> 
>>> out = [[alpha * i for i in row] for row in m]
>>> out
[[15, 15, 0], [0, 30, 150], [150, 225, 450]]
>>>
Ты просто не знаешь питон даже на базовом уровне, поэтому у тебя ничего и не получается. Учи питон лучше, можешь использовать книгу Dive Into Python 3, там это всё показано.



Отредактировано py.user.next (Янв. 6, 2018 02:38:40)

Офлайн

#7 Март 12, 2018 17:56:19

Arthur_Filimonov
Зарегистрирован: 2018-03-11
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Реализация класса Matrix

Ориентируйся на этот код, правда тут без numpy:

 class matrix(object):
    def __init__(self, list2D):
        self.list2D = list2D
        self.dim_R = len(self.list2D)
        self.dim_C = len(self.list2D[0])
    def __repr__(self):
        res = ''
        for x in self.list2D:
            s = ''
            for y in x:
                s += str(y) + '    '
            res += s.strip() + '\n'
        return res.strip()
    def __add__(self, other):
        if self.dim_R == other.dim_R and self.dim_C == other.dim_C:
            result = []
            res = []
            for x in range(self.dim_R):
                for y in range(self.dim_C):
                    sum = self.list2D[x][y] + other.list2D[x][y]
                    res.append(sum)
                result.append(res)
                res = []
            return matrix(result)
        else:
            return 'Размерности не совпадают'
    def __sub__(self, other):
        if self.dim_R == other.dim_R and self.dim_C == other.dim_C:
            res = []
            result = []
            for x in range(self.dim_R):
                for y in range(self.dim_C):
                    sub = self.list2D[x][y] - other.list2D[x][y]
                    res.append(sub)
                result.append(res)
                res = []
            return matrix(result)
        else:
            return 'Размерности не совпадают'
    def __mul__(self, other):
        if isinstance(other, int) or isinstance(other, float):
            result = [[other * x for x in y] for y in self.list2D]
            return matrix(result)
        elif self.dim_C != other.dim_R:
            return 'Нельзя перемножить матрицы таких размерностей'
        else:
            a = range(self.dim_C)
            b = range(self.dim_R)
            c = range(other.dim_C)
            result = []
            for i in b:
                res = []
                for j in c:
                    el, m = 0, 0
                    for k in a:
                        m = self.list2D[i][k] * other.list2D[k][j]
                        el += m
                    res.append(el)
                result.append(res)
            return matrix(result)
    def __rmul__(self, other):
        return self.__mul__(other)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version