Python科学计算:自动数据结构定义指南

第1关:定义一个类

任务描述
实现一个 Vector 类,来建模三维向量:一个 Vector 对象包含三个(浮点数)成员 a 、 b 、 c ,对应于向量

除 __init__ 外,它还有其他几个方法:一元运算求模( mod )、二元运算求和( add ,已经实现)、二元运算求内积( inner_prod )、二元运算求外积( outer_prod )以及一元方法 to_string (已经实现)。

编程要求
请按照要求实现该类。

class Vector:
    def __init__(self, i, j, k):
    #********* Begin *********#
    
    #********* End  **********#
        
    def mod(self):
    #********* Begin *********#
    
    #********* End  **********#
    
    def add(self, another):
        return Vector(self.a + another.a, self.b + another.b + self.c + another.c)
    
    def inner_prod(self,another):
    #********* Begin *********#
    
    #********* End  **********#
        
    def outer_prod(self, another):
    #********* Begin *********#
    
    #********* End  **********#
        
    def to_string(self):
        return "(%g, %g, %g)"%(self.a, self.b, self.c)
v1 = Vector(1, 0, 1)
v2 = Vector(1, 1, 0)
print v1.outer_prod(v2).to_string()

class Vector:
    def __init__(self, i, j, k):
    #********* Begin *********#
        self.a = i
        self.b = j
        self.c = k
    #********* End  **********#
        
    def mod(self):
    #********* Begin *********#
        import math
        return math.sqrt(self.a ** 2 + self.b ** 2 + self.c ** 2)
    #********* End  **********#
    
    def add(self, another):
        return Vector(self.a + another.a, self.b + another.b + self.c + another.c)
    
    def inner_prod(self,another):
    #********* Begin *********#
        return self.a * another.a + self.b * another.b + self.c * another.c
    #********* End  **********#
        
    def outer_prod(self, another):
    #********* Begin *********#
        x = self.b * another.c - self.c * another.b
        y = self.c * another.a - self.a * another.c
        z = self.a * another.b - self.b * another.a
        return Vector(x,y,z)
    #********* End  **********#
        
    def to_string(self):
        return "(%g, %g, %g)"%(self.a, self.b, self.c)

v1 = Vector(1, 0, 1)
v2 = Vector(1, 1, 0)

print v1.outer_prod(v2).to_string()

第2关:类方法与静态方法

任务描述
扩充上一个任务的 Vector 类,添加一个类方法 parse(cls, s) ,将格式为 (a,b,c) 的字符串 s 解析为分量为 a 、 b 、 c 的向量 —— 假设 a 、 b 、 c 都是对应于某个浮点数的字符串。事实上,在  Python 2.x 中,可以直接将 s 看做是一个元组。

from math import sqrt
class Vector:
    
    def __init__(self, i, j, k):
        self.a, self.b, self.c = i, j, k
    def mod(self):
        return sqrt((self.a)**2 + (self.b)**2 + (self.c)**2)
    def add(self, another):
        return Vector(self.a + another.a, self.b + another.b + self.c + another.c)
    def inner_prod(self,another):
        return self.a*another.a + self.b*another.b + self.c*another.c
    def outer_prod(self, another):
        return Vector(self.b*another.c-self.c*another.b, self.c*another.a-self.a*another.c, self.a*another.b-self.b*another.a)
    @classmethod
    def parse(cls,s):
    #********* Begin *********#
    
    #********* End  **********#
    def to_string(self):
        return "%g *i  + %g *j + %g *k"%(self.a, self.b, self.c)
    
v1 = Vector.parse(input())
v2 = Vector.parse(input())
print("%g"%(v1.inner_prod(v2)))

备注
在 Python 中,成员变量同样也可分为“对象变量”与“类变量”。类变量的定义在任何方法的外面,并需要赋初值。

from math import sqrt

class Vector:
    
    def __init__(self, i, j, k):
        self.a, self.b, self.c = i, j, k

    def mod(self):
        return sqrt((self.a)**2 + (self.b)**2 + (self.c)**2)

    def add(self, another):
        return Vector(self.a + another.a, self.b + another.b + self.c + another.c)

    def inner_prod(self,another):
        return self.a*another.a + self.b*another.b + self.c*another.c

    def outer_prod(self, another):
        return Vector(self.b*another.c-self.c*another.b, self.c*another.a-self.a*another.c, self.a*another.b-self.b*another.a)

    @classmethod
    def parse(cls,s):
    #********* Begin *********#
        s=str(s).strip('()')
        parts=s.split(',')
        return cls(float(parts[0]),float(parts[1]),float(parts[2]))
    #********* End  **********#

    def to_string(self):
        return "%g *i  + %g *j + %g *k"%(self.a, self.b, self.c)
    
v1 = Vector.parse(input())
v2 = Vector.parse(input())

print "%g"%(v1.inner_prod(v2))

第3关:成员的访问权限

任务描述
进一步重构 Vector 类,将其成员变量 a 、 b 、 c 私有化, 即使用变量 __i 、 __j 、 __k 代替,并为每个变量增加两个访问,如对变量 __i ,添加读函数 get_i(self) 以及写函数 set_i(self,i) 。

任务描述
进一步重构 Vector 类,将其成员变量 a 、 b 、 c 私有化, 即使用变量 __i 、 __j 、 __k 代替,并为每个变量增加两个访问,如对变量 __i ,添加读函数 get_i(self) 以及写函数 set_i(self,i) 。

from math import sqrt
class Vector:
    def __init__(self, i, j, k):
    #********* Begin *********#
    
    #********* End  **********#
        
    def mod(self):
    #********* Begin *********#
    
    #********* End  **********#
        
    def add(self, another):
    #********* Begin *********#
    
    #********* End  **********#
        
    def inner_prod(self,another):
    #********* Begin *********#
    
    #********* End  **********#
        
    def outer_prod(self, another):
    #********* Begin *********#
    
    #********* End  **********#
        
    def get_i(self):
    #********* Begin *********#
    
    #********* End  **********#
        
    def set_i(self,i):
    #********* Begin *********#
    
    #********* End  **********#
        
    def get_j(self):
    #********* Begin *********#
    
    #********* End  **********#
        
    def set_j(self, j):
    #********* Begin *********#
    
    #********* End  **********#
        
    def get_k(self):
    #********* Begin *********#
    
    #********* End  **********#
        
    def set_k(self, k):
    #********* Begin *********#
    
    #********* End  **********#
        
    def to_string(self):
        return "(%g, %g, %g)"%(self.__i, self.__j, self.__k)
v1 = Vector(1, 0, 1)
v2 = Vector(1, 1, 0)
print v1.outer_prod(v2).get_k()
编程要求
编写程序时,在

#********* Begin *********#
    
#********* End  **********#
之间填写代码,完成程序要求。

编程要求
编写程序时,在

#********* Begin *********#
    
#********* End  **********#
之间填写代码,完成程序要求。

from math import sqrt

class Vector:
    def __init__(self, i, j, k):
    #********* Begin *********#
        self.a = i
        self.b = j 
        self.c = k
    #********* End  **********#
        
    def mod(self):
    #********* Begin *********#
        return sqrt((self.a)**2 + (self.b)**2 + (self.c)**2)
    #********* End  **********#
        
    def add(self, another):
    #********* Begin *********#
        return Vector(self.a + another.a, self.b + another.b + self.c + another.c)
    #********* End  **********#
        
    def inner_prod(self,another):
    #********* Begin *********#
        return self.a*another.a + self.b*another.b + self.c*another.c
    #********* End  **********#
        
    def outer_prod(self, another):
    #********* Begin *********#
        return Vector(self.b*another.c-self.c*another.b, self.c*another.a-self.a*another.c, self.a*another.b-self.b*another.a)
    #********* End  **********#
        
    def get_i(self):
    #********* Begin *********#
        return self.a
    #********* End  **********#
        
    def set_i(self,i):
    #********* Begin *********#
        self.__i = i
    #********* End  **********#
        
    def get_j(self):
    #********* Begin *********#
        return self.b
    #********* End  **********#
        
    def set_j(self, j):
    #********* Begin *********#
        self.__j = j
    #********* End  **********#
        
    def get_k(self):
    #********* Begin *********#
        return self.c
    #********* End  **********#
        
    def set_k(self, k):
    #********* Begin *********#
        self.__k = k
    #********* End  **********#
        
    def to_string(self):
        return "(%g, %g, %g)"%(self.__i, self.__j, self.__k)

v1 = Vector(1, 0, 1)
v2 = Vector(1, 1, 0)

print v1.outer_prod(v2).get_k()

第4关:使用属性

任务描述
重构 Vector 类,将 get_i 、 set_i 、 …… 、 set_k 等六个成员函数私有化,并且将其封装为三个属性 i 、 j 、 k 。

编程要求
编写程序时,在

#********* Begin *********#
    
#********* End  **********#
之间填写代码,完成程序要求。

from math import sqrt

class Vector:
    def __init__(self, i, j, k):
    #********* Begin *********#
        self.a = i
        self.b = j 
        self.c = k
    #********* End  **********#
        
    def mod(self):
    #********* Begin *********#
        return sqrt((self.a)**2 + (self.b)**2 + (self.c)**2)
    #********* End  **********#
        
    def add(self, another):
    #********* Begin *********#
        return Vector(self.a + another.a, self.b + another.b + self.c + another.c)
    #********* End  **********#
        
    def inner_prod(self,another):
    #********* Begin *********#
        return self.a*another.a + self.b*another.b + self.c*another.c
    #********* End  **********#
        
    def outer_prod(self, another):
    #********* Begin *********#
        return Vector(self.b*another.c-self.c*another.b, self.c*another.a-self.a*another.c, self.a*another.b-self.b*another.a)
    #********* End  **********#
        
    def __get_i(self):
    #********* Begin *********#
        return self.a
    #********* End  **********#
        
    def __set_i(self,i):
    #********* Begin *********#
        self.__i = i
    #********* End  **********#
        
    def __get_j(self):
    #********* Begin *********#
        return self.b
    #********* End  **********#
        
    def __set_j(self, j):
    #********* Begin *********#
        self.__j = j
    #********* End  **********#
    

    def __get_k(self):
    #********* Begin *********#
        return self.c
    #********* End  **********#
    
    def __set_k(self, k):
    #********* Begin *********#
        self.__k = k
    #********* End  **********#

    #********* Begin *********#
    # Define properties here
    i = property(__get_i,__set_i)
    j = property(__get_j,__set_j)
    k = property(__get_k,__set_k)
    #********* End  **********#
    
        
    def to_string(self):
        return "(%g, %g, %g)"%(self.__i, self.__j, self.__k)

v1 = Vector(1, 0, 1)
v2 = Vector(1, 1, 0)


print v1.outer_prod(v2).k

第5关:运算符重载

任务描述
继续重构 Vector 类,使用 + 、 ^ 、 *  三个算符替代原来的 add() 、 inner_product() 、 outer_product() 三个方法调用。

编程要求
编写程序时,在

#********* Begin *********#
    
#********* End  **********#
之间填写代码,完成程序要求。

from math import sqrt

class Vector:
    def __init__(self, i, j, k):
    #********* Begin *********#
        self.__i = i
        self.__j = j
        self.__k = k
    #********* End  **********#
        
    def mod(self):
    #********* Begin *********#
        return sqrt((self.a)**2 + (self.b)**2 + (self.c)**2)
    #********* End  **********#

    #********* Begin *********#
    # add  
    def __add__(self, another):  
    #********* End  **********#
        return Vector(self.__i+another.i,self.__j+another.j,self.__k+another.k)


    #********* Begin *********#
    # innder_prod
    def __xor__(self,another):
    #********* End  **********#
      return self.__i*another.i + self.__j+another.j + self.__k+another.k
        
    #********* Begin *********#
    # outer_prod
    def __mul__(self, another):
        return Vector(self.__j*another.k-self.__k*another.j, self.__k*another.i-self.__i*another.k, self.__i*another.j-self.__j*another.i)

    #********* End  **********#
    
    def __get_i(self):
        return self.__i
        
    def __set_i(self,i):
        self.__i = i
    
    def __get_j(self):
        return self.__j
   
    def __set_j(self, j):
        self.__j = j
   
    def __get_k(self):
        return self.__k
    

    def __set_k(self, k):
        self.__k = k
    
    i = property(__get_i,__set_i)
    j = property(__get_j,__set_j)
    k = property(__get_k,__set_k)

    #********* Begin *********#
    # to_string:
    def __str__(self):
        return "({},{},{})".format(self.__i,self.__j,self.__k)
    #********* End  **********#
        return "(%g, %g, %g)"%(self.__i, self.__j, self.__k)

v1 = Vector(1, 0, 1)
v2 = Vector(1, 1, 0)


print (v1*v2).k

第6关:派生和继承

任务描述
假设当前的 Vector 类定义如下:

class Vector:
  def __init__(self,i,j,k):
    self.__i, self.__j, self.__k = i,j,k
  
  def get_i(self):
    return self.__i
  
  def set_i(self,i):
    self.__i = i
  
  i = property(get_i, set_i)
  
  def get_j(self):
    return self.__j
  
  def set_j(self,j):
    self.__j = j
  
  j = property(get_j,set_j)
  
  def get_k(self):
    return self.__k
  
  def set_k(self,k):
    self.__k = k
  
  # override operator '+'
  def __add__(self,vec):
    return Vector(self.__i+vec.i, self.__j+vec.j, self.__k+vec.k)
  
  # override the 'str' operator
  def __str__(self):
    return str(self.__i)+"*i + "+str(self.__j)+"*j + "+str(self.__k)+"*k"

编程要求
编写程序时,在

#********* Begin *********#
    
#********* End  **********#
之间填写代码。基于 Vector 类派生子类 Matrix ,来模拟一个三行 n 列的矩阵。在 Matrix 类中:

具有一个属性 n ,表示该矩阵的列,该属性封装私有变量 __n ;

由于成员 __i 、 __j 、 __k 不再是标量,因此,其 get / set 方法需要重载 —— 比如,需要将 get_i 中的语句 return __i 替换为 return __i[:] ,将 set_i 中的语句 __i = i 替换为 __i=i[:] ,想一想,为什么?

需要重载 __add__ 方法,将其定义为矩阵加法。

# -*- coding: utf-8 -*-
class Vector:
    def __init__(self, i, j, k):
        self.__i, self.__j, self.__k = i, j, k

    def get_i(self):
        return self.__i

    def set_i(self, i):
        self.__i = i

    i = property(get_i, set_i)

    def get_j(self):
        return self.__j

    def set_j(self, j):
        self.__j = j

    j = property(get_j, set_j)

    def get_k(self):
        return self.__k

    def set_k(self, k):
        self.__k = k

    k = property(get_k, set_k)

    # Override operator '+' for Vector
    def __add__(self, vec):
        return Vector(self.__i + vec.i, self.__j + vec.j, self.__k + vec.k)

    # Override the 'str' operator for Vector
    def __str__(self):
       return "{}*i + {}*j + {}*k".format(self.__i, self.__j, self.__k)


class Matrix:
    def __init__(self, n, vec1, vec2, vec3):
        if len(vec1) != n or len(vec2) != n or len(vec3) != n:
            raise ValueError("All vectors must have the same length as n.")
        self.__n = n
        self.__i = vec1
        self.__j = vec2
        self.__k = vec3

    def get_n(self):
        return self.__n

    def set_n(self, n):
        self.__n = n

    n = property(get_n, set_n)

    def get_i(self):
        return self.__i[:]

    def set_i(self, i):
        if len(i) == self.__n:
            self.__i = i[:]
        else:
            raise ValueError("Length of vector must match number of columns")

    i = property(get_i, set_i)

    def get_j(self):
        return self.__j[:]

    def set_j(self, j):
        if len(j) == self.__n:
            self.__j = j[:]
        else:
            raise ValueError("Length of vector must match number of columns")

    j = property(get_j, set_j)

    def get_k(self):
        return self.__k[:]

    def set_k(self, k):
        if len(k) == self.__n:
            self.__k = k[:]
        else:
            raise ValueError("Length of vector must match number of columns")

    k = property(get_k, set_k)

    # Override '+' operator for Matrix
    def __add__(self, mat):
        if self.__n != mat.n:
            raise ValueError("Matrices must have the same number of columns")
        new_i = [a + b for a, b in zip(self.i, mat.i)]
        new_j = [a + b for a, b in zip(self.j, mat.j)]
        new_k = [a + b for a, b in zip(self.k, mat.k)]
        return Matrix(self.__n, new_i, new_j, new_k)

    def __str__(self):
        result = "["
        result += "[{}]\n".format(", ".join(map(str, self.i)))
        result += "[{}]\n".format(", ".join(map(str, self.j)))
        result += "[{}]".format(", ".join(map(str, self.k)))
        result += "]"
        return result


if __name__ == "__main__":
    v1, v2, v3 = [1.0, 2.0, 3.5, 1.2], [2.1, 3.6, 2.5, 4.5], [5.1, 2.5, 8.1, 2.2]
    m1 = Matrix(4, v1, v2, v3)
    m2 = Matrix(4, v2, v1, v3)
    print m1+m2

第7关:多态行为

编程任务
假设当前的 Vector 类定义如下:

import abc
class Vector:
    def __init__(self, i, j, k):
        self.__i, self.__j, self.__k = i, j, k
    
    def get_i(self):
        return self.__i
    
    def set_i(self,i):
        self.__i = i
    
    def get_j(self):
        return self.__j
    
    def set_j(self,j):
        self.__j = j
    
    def get_k(self):
        return self.__k
    
    def set_k(self,k):
        self.__k = k
    
    i = property(get_i,set_i)
    j = property(get_j,set_j)
    k = property(get_k,set_k)
    
    def __add__(self, vec):
        return Vector(self.__i+vec.__i, self.__j+vec.__j, self.__k+vec.__k)
    
    @abc.abst\fractmethod
    def __str__(self):
        pass  # abst\fract method, having no implementation

编程要求
现在,你需要从 Vector 类中派生两个子类 ——  NumberVector 以及 StringVector ,这两个子类均需要重载 __str__() 运算符,其中:

NumberVector 类 __str__() 算符的返回格式为:
a*i+b*j+c*k , 其中 a 、 b 、 c 分别为 __i 、 __j 、 __k 的当前值。

StringVector 类 __str__() 算符的返回值格式为:
i : str_i\nj : str_j\nk : str_k,其中,str_i 、 str_j 、 str_k 分别为分别为 __i 、 __j 、 __k 的当前值。

# -*- coding: utf-8 -*-
import abc

class Vector(object):  # Python 2 中需要继承 object 才能使用新式类
    def __init__(self, i, j, k):
        self.__i, self.__j, self.__k = i, j, k

    def get_i(self):
        return self.__i

    def set_i(self, i):
        self.__i = i

    def get_j(self):
        return self.__j

    def set_j(self, j):
        self.__j = j

    def get_k(self):
        return self.__k

    def set_k(self, k):
        self.__k = k

    i = property(get_i, set_i)
    j = property(get_j, set_j)
    k = property(get_k, set_k)

    def __add__(self, vec):
        return Vector(self.__i + vec.__i, self.__j + vec.__j, self.__k + vec.__k)

    @abc.abstractmethod
    def __str__(self):
        pass  # abstract method, having no implementation


class NumberVector(Vector):
    def __init__(self, i, j, k):
        super(NumberVector, self).__init__(i, j, k)  # Python 2 需要显式传递类名和 self

    #********* Begin *********#
    def __str__(self):
        return "{}*i+{}*j+{}*k".format(self.i, self.j, self.k)
    #********* End  **********#


class StringVector(Vector):
    def __init__(self, i, j, k):
        super(StringVector, self).__init__(i, j, k)  # Python 2 需要显式传递类名和 self

    #********* Begin *********#
    def __str__(self):
        return "i : {}\nj : {}\nk : {}".format(self.i, self.j, self.k)
    #********* End  **********#


if __name__ == "__main__":
    nvec = NumberVector(3, 4, 5)
    svec = StringVector("x", "y", "z")
    vec_lst = [nvec, svec]
    for vec in vec_lst:
        print(vec)

作者:ykyqt26666

物联沃分享整理
物联沃-IOTWORD物联网 » Python科学计算:自动数据结构定义指南

发表回复