目录
- 第一章 导论
- 1.4 Python数据
- 1.4.1 内建集合数据类型
- 1.4.1.1 列表
- 1.4.1.2 字符串
- 1.4.1.3 集合
- 1.4.1.4 字典
- 1.4.3 控制结构
- 1.4.6 定义类
- 1.4.6.1 Fraction类
- 1.4.6.2 继承:逻辑门与电路
- 1.8 练习题
第一章 导论
介绍抽象数据类型,复习Python。
1.4 Python数据
1.4.1 内建集合数据类型
1.4.1.1 列表
运算:索引([ ])、连接(+)、重复(*)、成员(in)、长度(len)、切片([:])
方法:append、insert、pop、sort、reverse、del、index、count、remove。
del(l[index]):删除索引号index的元素,无返回值
l.pop():删除最后一个值,并返回
l.remove(item):移除列表中第一次出现的item
1.4.1.2 字符串
方法:.center(w); .count(item); .ljust(w); .rjust(w); .lower(); .upper(); .find(item); .split(schar)
1.4.1.3 集合
运算:成员(in)、长度(len)、|、&、<=、-
方法:.union(otherset)、 .intersection(.otherset)、 .issubset(otherset)、 .difference(otherset); .add(item); .remove(item); .pop(); .cleat()
1.4.1.4 字典
运算符:[ ]、in、del
方法:.keys(); .values(); .items(), .get(key); .get(key, alt)
1.4.3 控制结构
列表解析式:
sqlist = [x*x for x in range(1,11) if x%2 !=0]
1.4.6 定义类
1.4.6.1 Fraction类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | class Fraction: # 构造方法 def __init__(self, top, bottom): ''' top: 分子 bottom: 分母 ''' if all([isinstance(x,int) for x in [top,bottom]]): common = self.gcd(top,bottom) label = (top*bottom)//abs(top*bottom) self.num = label*abs(top//common) self.den = abs(bottom//common) else: raise TypeError("分子分母必须都为整数") # str(),print() 给用户看的,用于显示内容 def __str__(self): return "{}/{}".format(self.num,self.den) # repr(),Fraction 用于调试和开发,复现obj = eval() def __repr__(self): return "Fraction({},{})".format(self.num,self.den) # 加法 def __add__(self,otherfraction): newnum = self.num*otherfraction.den+self.den*otherfraction.num newden = self.den * otherfraction.den # common = self.gcd(newnum,newden) # return Fraction(newnum//common,newden//common) return(Fraction(newnum,newden)) # 右加 def __radd__(self,otherfraction): newnum = self.num*otherfraction.den+self.den*otherfraction.num newden = self.den * otherfraction.den return(Fraction(newnum,newden)) # += # def __iadd__(self,otherfraction): ## newnum = self.num*otherfraction.den+self.den*otherfraction.num ## newden = self.den * otherfraction.den # self = (Fraction(newnum,newden)) # self = self.__add__(self,otherfraction) # 减法 def __sub__(self,otherfraction): return self.__add__(Fraction(-otherfraction.num, otherfraction.den)) # 乘法 def __mul__(self,otherfraction): newnum = self.num * otherfraction.num newden = self.den * otherfraction.den return Fraction(newnum, newden) # 除法 def __truediv__(self,otherfraction): return self.__mul__(Fraction(otherfraction.den, otherfraction.num)) # 等于 def __eq__(self,other): first = self.num * other.den second = other.num * self.den return first == second # 不等 def __ne__(self,other): first = self.num * other.den second = other.num * self.den return first != second # 大于 def __gt__(self,other): first = self.num * other.den second = other.num * self.den return first > second # 大于等于 def __ge__(self,other): first = self.num * other.den second = other.num * self.den return first >= second # 小于 def __lt__(self,other): first = self.num * other.den second = other.num * self.den return first < second # 小于等于 def __le__(self,other): first = self.num * other.den second = other.num * self.den return first <= second # 求解最大公因子 def gcd(self,m,n): while m % n!=0: oldm = m oldn = n m = oldn n = oldm%oldn return n # 返回分子 def getNum(self): return self.num # 返回分母: def getDen(self): return self.den # 复制 def copy(self): return Fraction(self.num,self.den) if __name__=="__main__": f1 = Fraction(4,5) print(f1) f2 = Fraction(2,-4) print(f2) print("f1+f2:", f1+f2) print("f1-f2:", f1-f2) print("f1*f2:", f1*f2) print("f1/f2:", f1/f2) f1+=f2 print("f1+=f2", f1) print("==",f1==f2) print("!=",f1!=f2) print(">",f1>f2) print(">=",f1>=f2) print("<",f1<f2) print("<=",f1<=f2) |
结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 4/5 -1/2 f1+f2: 3/10 f1-f2: 13/10 f1*f2: -2/5 f1/f2: -8/5 f1+=f2 3/10 == False != True > True >= True < False <= False |
在命令行中输入变量名显示__repr__:
1 2 3 4 5 | >>> from Fraction import Fraction >>> f1 = Fraction(-3,2) >>> f1 Fraction(-3,2) >>> |
1.4.6.2 继承:逻辑门与电路
IS-A用于描述子类和父类关系
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | # 超类LogicGate class LogicGate: def __init__(self,n): self.label = n self.output = None def getLabel(self): return self.label def getOutput(self): self.output = self.performGateLogic() return self.output # 二引脚逻辑门 class BinaryGate(LogicGate): def __init__(self,n): super().__init__(n) self.pinA = None self.pinB = None def getPinA(self): return int(input("Enter Pin A for gate" + self.getLabel() + "-->")) def getPinB(self): return int(input("Enter Pin B for gate" + self.getLabel() + "-->")) # 单引脚逻辑门 class UnaryGate(LogicGate): def __init__(self,n): super().__init__(n) self.pin = None def getPin(self): return int(input("Enter Pin for gate" + self.getLabel() + "-->")) # 与门 class AndGate(BinaryGate): def __init__(self,n): super().__init__(n) def performGateLogic(self): self.pinA = self.getPinA() self.pinB = self.getPinB() if self.pinA == 1 and self.pinB == 1: return 1 else: return 0 # 或门 class OrGate(BinaryGate): def __init__(self,n): super().__init__(n) def performGateLogic(self): self.pinA = self.getPinA() self.pinB = self.getPinB() if self.pinA == 1 or self.pinB == 1: return 1 else: return 0 # 非门 class NotGate(UnaryGate): def __init__(self,n): super().__init__(n) def performGateLogic(self): self.pin = self.getPin() if self.pin==1: return 0 else: return 1 if __name__=="__main__": g1 = AndGate("G1") print(g1.getOutput()) g2 = OrGate("G2") print(g2.getOutput()) g3 = NotGate("G3") print(g3.getOutput()) |
HAS-A关系 (HAS-A意即“有一个”)
连接器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | # 超类LogicGate class LogicGate: def __init__(self,n): self.label = n self.output = None def getLabel(self): return self.label def getOutput(self): self.output = self.performGateLogic() return self.output # 二引脚逻辑门 class BinaryGate(LogicGate): def __init__(self,n): super().__init__(n) self.pinA = None self.pinB = None def getPinA(self): if self.pinA == None: return int(input("Enter Pin A for gate" + self.getLabel() + "-->")) else: return self.pinA.getFrom().getOutput() def getPinB(self): if self.pinB == None: return int(input("Enter Pin B for gate" + self.getLabel() + "-->")) else: return self.pinB.getFrom().getOutput() def setNextPin(self,source): if self.pinA == None: self.pinA = source else: if self.pinB == None: self.pinB = source else: raise RuntimeError("Error: NO EMPTY PINS") # 单引脚逻辑门 class UnaryGate(LogicGate): def __init__(self,n): super().__init__(n) self.pin = None def getPin(self): if self.pin == None: return int(input("Enter Pin for gate" + self.getLabel() + "-->")) else: return self.pin.getFrom().getOutput() def setNextPin(self,source): if self.pin == None: self.pin = source else: print("Cannot Connect: NO EMPTY PINS on this gate") # 与门 class AndGate(BinaryGate): def __init__(self,n): super().__init__(n) def performGateLogic(self): self.pinA = self.getPinA() self.pinB = self.getPinB() if self.pinA == 1 and self.pinB == 1: return 1 else: return 0 # 与非门 class NandGate(BinaryGate): def __init__(self,n): super().__init__(n) def performGateLogic(self): self.pinA = self.getPinA() self.pinB = self.getPinB() if self.pinA == 1 and self.pinB == 1: return 0 else: return 1 # 或非门 class NorGate(BinaryGate): def __init__(self,n): super().__init__(n) def performGateLogic(self): self.pinA = self.getPinA() self.pinB = self.getPinB() if self.pinA == 0 and self.pinB == 0: return 1 else: return 0 # 或门 class OrGate(BinaryGate): def __init__(self,n): super().__init__(n) def performGateLogic(self): self.pinA = self.getPinA() self.pinB = self.getPinB() if self.pinA == 1 or self.pinB == 1: # pinA = self.getPinA() # pinB = self.getPinB() # if pinA == 1 or pinB == 1: return 1 else: return 0 # 异或门 class NorGate(BinaryGate): def __init__(self,n): super().__init__(n) def performGateLogic(self): self.pinA = self.getPinA() self.pinB = self.getPinB() if self.pinA == self.pinB: return 0 else: return 1 # 非门 class NotGate(UnaryGate): def __init__(self,n): super().__init__(n) def performGateLogic(self): self.pin = self.getPin() if self.pin==1: return 0 else: return 1 class Connector(): def __init__(self,fgate,tgate): self.fromgate = fgate self.togate = tgate tgate.setNextPin(self) def getFrom(self): return self.fromgate def getTo(self): return self.togate if __name__=="__main__": g1 = AndGate("G1") g2 = AndGate("G2") g3 = OrGate("G3") g4 = NotGate("G4") c1 = Connector(g1,g3) c2 = Connector(g2,g3) c3 = Connector(g3,g4) print(g4.getOutput()) |
1.8 练习题
- 实现简单的方法getNum 和getDen ,它们分别返回分数的分子和分母。
- 如果所有分数从一开始就是最简形式会更好。修改Fraction 类的构造方法,立即使用最大公因数来化简分数。注意,这意味着__add__
不再需要化简结果。 - 实现下列简单的算术运算:sub 、mul 和__truediv__ 。
- 实现下列关系运算:gt 、ge 、lt 、le 和__ne__ 。
- 修改Fraction 类的构造方法,使其检查并确保分子和分母均为整数。如果任一不是整数,就抛出异常。
- 我们假设负的分数是由负的分子和正的分母构成的。使用负的分母会导致某些关系运算符返回错误的结果。一般来说,这是多余的限制。请修改构造方法,使得用户能够传入负的分母,并且所有的运算符都能返回正确的结果。
- 研究__radd__ 方法。它与__add__ 方法有何区别?何时应该使用它?请动手实现__radd__ 。
- 研究__iadd__ 方法。它与__add__ 方法有何区别?何时应该使用它?请动手实现__iadd__ 。
- 研究__repr__ 方法。它与__str__ 方法有何区别?何时应该使用它?请动手实现__repr__ 。
- 研究其他类型的逻辑门(例如与非门、或非门、异或门)。将它们加入电路的继承层次结构。你需要额外添加多少代码?
- 最简单的算术电路是半加器。研究简单的半加器电路并实现它。 将半加器电路扩展为8位的全加器。
- 本章展示的电路模拟是反向工作的。换句话说,给定一个电路,其输出结果是通过反向访问输入值来产生的,这会导致其他的输出值被反向查询。这个过程一直持续到外部输入值被找到,此时用户会被要求输入数值。修改当前的实现,使电路正向计算结果。当收到输入值的时候,电路就会生成输出结果。
- 设计一个表示一张扑克牌的类,以及一个表示一副扑克牌的类。使用这两个类实现你最喜欢的扑克牌游戏。
- 在报纸上找到一个数独游戏,并编写一个程序求解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | # 电路正向计算&半加器 # 超类LogicGate class LogicGate: def __init__(self,n): self.label = n self.output = None def getLabel(self): return self.label def getOutput(self): self.output = self.performGateLogic() return self.output # 二引脚逻辑门 class BinaryGate(LogicGate): def __init__(self,n,pinA=None,pinB=None): super().__init__(n) self.pinA = pinA self.pinB = pinB self.output = self.getOutput() # def getPinA(self): # if self.pinA == None: # return int(input("Enter Pin A for gate" + self.getLabel() + "-->")) # else: # return self.pinA.getFrom().getOutput() # def getPinB(self): # if self.pinB == None: # return int(input("Enter Pin B for gate" + self.getLabel() + "-->")) # else: # return self.pinB.getFrom().getOutput() def __str__(self): return "{} - pinA: {}; pinA: {}; output: {}".format(self.label,self.pinA, self.pinB,self.output) def setNextPin(self,source): if self.pinA == None: self.pinA = source.output else: if self.pinB == None: self.pinB = source.output else: raise RuntimeError("Error: NO EMPTY PINS") # 单引脚逻辑门 class UnaryGate(LogicGate): def __init__(self,n,pin=None): super().__init__(n) self.pin = None self.output = self.getOutput() # def getPin(self): # if self.pin == None: # return int(input("Enter Pin for gate" + self.getLabel() + "-->")) # else: # return self.pin.getFrom().getOutput() def __str__(self): return "{} - pin: {}; output: {}".format(self.label,self.pin,self.output) def setNextPin(self,source): if self.pin == None: self.pin = source.output else: print("Cannot Connect: NO EMPTY PINS on this gate") # 与门 class AndGate(BinaryGate): def __init__(self,n,pinA=None, pinB=None): super().__init__(n,pinA,pinB) def performGateLogic(self): # self.pinA = self.getPinA() # self.pinB = self.getPinB() if self.pinA == 1 and self.pinB == 1: return 1 else: return 0 # 与非门 class NandGate(BinaryGate): def __init__(self,n,pinA=None, pinB=None): super().__init__(n,pinA,pinB) def performGateLogic(self): # self.pinA = self.getPinA() # self.pinB = self.getPinB() if self.pinA == 1 and self.pinB == 1: return 0 else: return 1 # 或门 class OrGate(BinaryGate): def __init__(self,n,pinA=None, pinB=None): super().__init__(n,pinA,pinB) def performGateLogic(self): # self.pinA = self.getPinA() # self.pinB = self.getPinB() if self.pinA == 1 or self.pinB == 1: # pinA = self.getPinA() # pinB = self.getPinB() # if pinA == 1 or pinB == 1: return 1 else: return 0 # 或非门 class NorGate(BinaryGate): def __init__(self,n,pinA=None, pinB=None): super().__init__(n,pinA,pinB) def performGateLogic(self): # self.pinA = self.getPinA() # self.pinB = self.getPinB() if self.pinA == 0 and self.pinB == 0: return 1 else: return 0 # 异或门 class NorGate(BinaryGate): def __init__(self,n,pinA=None,pinB=None): super().__init__(n,pinA,pinB) def performGateLogic(self): # self.pinA = self.getPinA() # self.pinB = self.getPinB() if self.pinA == self.pinB: return 0 else: return 1 # 非门 class NotGate(UnaryGate): def __init__(self,n,pin=None): super().__init__(n,pin) def performGateLogic(self): # self.pin = self.getPin() if self.pin==1: return 0 else: return 1 class Connector(): def __init__(self,fgate,tgate): self.fromgate = fgate self.togate = tgate tgate.setNextPin(fgate) def getFrom(self): return self.fromgate def getTo(self): return self.togate class HalfAdder(): def __init__(self,n,A,B): self.label = n self.A = A self.B = B self.S = NorGate("n1",A,B).output self.C = AndGate("n2",A,B).output def __str__(self): return "{} - A: {}; B: {}; S: {}; C: {}".format(self.label,self.A,self.B,self.S,self.C) class Adder(): def __init__(self,) if __name__=="__main__": # g1 = AndGate("G1",0,1) # g2 = AndGate("G2",1,1) # g3 = OrGate("G3") # g4 = NotGate("G4") # c1 = Connector(g1,g3) # c2 = Connector(g2,g3) # c3 = Connector(g3,g4) # print(g1) # print(g2) # print(g3) # print(g4) # print(g4.output) h1 = HalfAdder("h1",0,0) h2 = HalfAdder("h2",0,1) h3 = HalfAdder("h3",1,0) h4 = HalfAdder("h4",1,1) print(h1) print(h2) print(h3) print(h4) |