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