Python 面向对象编程——自定义矩阵

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

"""
@Project : platform
@File    : sim_numpy_array.py
@version : V0.0.1
@Author  : wuchangwen
@Email   :
@Time    : 2019/10/16 12:24
@Software: PyCharm
@Desc    :
@Update  :
"""


class SimNumpyArray(object):
    def __init__(self, p):
        """可以接收列表、元组,range对象等类型的数据,并且每个元素都必须为数字"""
        if type(p) not in (list, tuple, range):
            print("data type error")
            return
        for item in p:
            # 下面这行用来判断参数类型,可以这样写
            # if isinstance(item,(int,float,complex)):
            if type(item) not in (int, float, complex):
                print('data type error')
                return
        self.__data = [list(p)]
        self.__row = 1
        self.__col = len(p)

    # 析构函数
    def __del__(self):
        del self.__data

    # 修改大小,首先检查给定的大小参数是否合适
    def reshape(self, size):
        """
        参数必须为元组或列表,如(row,col)或[row,col]
        row 或 col 其中一个为-1,表示自动计算
        :param size:
        :return:
        """
        if not (isinstance(size, list) or isinstance(size, tuple)):
            print("size parameter error")
            return
        if len(size) != 2:
            print('size parameter error')
            return

        if (not isinstance(size[0], int) or (not isinstance(size[1], int))):
            print('size parameter error')
            return

        if size[0] != -1 and size[1] != -1 and size[0] * size[1] != self.__row * self.__col:
            print('size parameter error')
            return

        # 行数或列数为-1表四该值自动计算
        if size[0] == -1:
            if size[1] == -1 or (self.__row * self.__col) % size[1] != 0:
                print('size parameter error')
                return
        if size[1] == -1:
            if size[0] == -1 or (self.__row * self.__col) % size[0] != 0:
                print('size parameter error')
                return
        # 重新合并数据
        data = [t for i in self.__data for t in i]

        # 修改大小
        if size[0] == -1:
            self.__row = int(self.__row * self.__col / size[1])
            self.__col = size[1]
        elif size[1] == -1:
            self.__col = int(self.__row * self.__col / size[0])
            self.__row = size[0]
        else:
            self.__row = size[0]
            self.__col = size[1]
        self.__data = [[data[row * self.__col + col] for col in range(self.__col)] for row in range(self.__row)]

    # 在交互模式直接使用变量名作为表达式查看值时调用该函数
    def __repr__(self):
        # return repr('\n'.join(map(str,self.__data)))
        for i in self.__data:
            print(i)
        return ''

    # 使用print()函数输出值时调用该函数
    def __str__(self):
        return '\n'.join(map(str, self.__data))

    # 属性,矩阵转置
    @property
    def T(self):
        b = SimNumpyArray([t for i in self.__data for t in i])
        b.reshape((self.__row, self.__col))
        b.__data = list(map(list, zip(*b.__data)))
        b.__row, b.__col = b.__col, b.__row
        return b

    # 通用代码,适用于矩阵与整数,实数,复数的加、减、乘、除、整除、幂
    def __operate(self, n, op):
        b = SimNumpyArray([t for i in self.__data for t in i])
        b.reshape((self.__row, self.__col))
        b.__data = [[eval(str(j) + op + str(n)) for j in item] for item in b.__data]
        return b

    # 通用代码,适用于矩阵之间的加、减
    def __matrixAddSub(self, n, op):
        c = SimNumpyArray([1])
        c.__row = self.__row
        c.__col = self.__col
        c.__data = [[eval(str(x[i]) + op + str(y[i])) for i in range(len(x))] for x, y in zip(self.__data, n.__data)]
        return c

    # 所有元素统一加一个数字,或者两个矩阵相加
    def __add__(self, n):
        # 参数是整数或实数,则返回矩阵
        # 其中的每个元素为原矩阵中元素与该整数或实数的加法结果
        if type(n) in (int, float, complex):
            return self.__operate(n, "+")
        elif isinstance(n, SimNumpyArray):
            # 如果参数为同类型矩阵,且大小一致,则为两个矩阵中对应元素相加
            if n.__row == self.__row and n.__col == self.__col:
                return self.__matrixAddSub(n, "+")
            else:
                print('two matrix must be the same size')
                return
        else:
            print('data type error')
            return

    # 所有元素统一减一个数字,或者两个矩阵相减
    def __sub__(self, n):
        # 参数是整数或实数,则返回矩阵
        # 其中的每个元素为原矩阵中元素与该整数或实数的减法结果
        if type(n) in (int, float, complex):
            return self.__operate(n, "-")
        elif isinstance(n, SimNumpyArray):
            # 如果参数为同类型矩阵,且大小一致,则为两个矩阵中对应元素相减
            if n.__row == self.__row and n.__col == self.__col:
                # 先实例化一个临时对象,其值临时为[1]
                return self.__matrixAddSub(n, "-")
            else:
                print('two matrix must be the some size')
                return
        else:
            print('data type error')
            return

    # 所有元素统一乘以一个数字,或者两个矩阵相乘
    def __mul__(self, n):
        # 参数是整数或实数,则返回矩阵
        # 其中的每个元素为原始矩阵中元素与该整数或实数的加法结果
        if type(n) in (int, float, complex):
            return self.__operate(n, '*')
        elif isinstance(n, SimNumpyArray):
            # 如果参数为同类型矩阵,且第一个矩阵的列数等于第二个矩阵的行数
            if n.__row == self.__col:
                data = []
                for row in self.__data:
                    t = []
                    for ii in range(n.__col):
                        col = [c[ii] for c in n.__data]
                        tt = sum([i * j for i, j in zip(row, col)])
                        t.append(tt)
                    data.append(t)
                c = SimNumpyArray([t for i in data for t in i])
                c.reshape((self.__row, n.__col))
                return c
            else:
                print('zise error')
                return
        else:
            print('data type error')
            return

    # 所有元素统一除以一个数字
    def __truediv__(self, n):
        if type(n) in (int, float, complex):
            return self.__operate(n, '/')
        else:
            print('data type error')
            return

    # 矩阵元素与数字计算整商
    def __floordiv__(self, n):
        if type(n) in (int, float, complex):
            return self.__operate(n, '//')
        else:
            print('data type error')
            return

    # 矩阵与数字的幂运算
    def __pow__(self, n):
        if type(n) in (int, float, complex):
            return self.__operate(n, "**")
        else:
            print('data type error')
            return

    # 测试两个矩阵是否相等
    def __eq__(self, n):
        if isinstance(n, SimNumpyArray):
            if self.__data == n.__data:
                return True
            else:
                return False
        else:
            print('data type error')
            return

    # 测试矩阵自身是否小于另一个矩阵
    def __lt__(self, n):
        if isinstance(n, SimNumpyArray):
            if self.__data < n.__data:
                return True
            else:
                return False
        else:
            print('data type error')
            return

    # 成员测试运算符
    def __contains__(self, v):
        if v in self.__data:
            return True
        else:
            return False

    # 支持迭代
    def __iter__(self):
        return iter(self.__data)

    # 通用方法,计算三角函数
    def __triangle(self, method):
        try:
            b = SimNumpyArray([t for i in self.__data for t in i])
            b.reshape((self.__row, self.__col))
            b.__data = [[eval("__import__('math')." + method + "(" + str(j) + ")") for j in item] for item in b.__data]
            return b
        except Exception as e:
            raise Exception("method error")

    # 属性,对所有元素求正弦
    @property
    def sin(self):
        return self.__triangle('sin')

    # 属性,对所有元素求余弦
    @property
    def cos(self):
        return self.__triangle('cos')
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,133评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,682评论 3 390
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,784评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,508评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,603评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,607评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,604评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,359评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,805评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,121评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,280评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,959评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,588评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,206评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,193评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,144评论 2 352

推荐阅读更多精彩内容