第一步、建立模块。
把代码:
'''二次根式加、减、乘、除(除数项数不超过2)和乘方运算
@作者 码老师
@微信公众号 学思营 ID:xuesying
@公司 深圳五行星软件有限公司
@日期 2020-11-01
@使用方法
1、导入模块
>>>from quadraticradical import *
2、单项二次根
空单项二次根式(与0相等)例如:
>>>QR()
整数单项二次根式例如:
>>>QR(3)
分数单项二次根式例1:
>>>QR("1/2")
分数单项二次根式例2:
>>>from fractions import Fraction
>>>QR(Fraction(1, 2))
小数单项二次根式(字符串输入,系统自动转为分数):
>>>QR("3.14")
如果单项二次根式有根号数,底数在常数之后,例如
>>>QR("3.14", 10)
3、多项二次根式
空多项二次根式(与0相等):
>>>pr = PR()
>>>pr.pt()
可以有列表化单项二次根式,单项二次根式和多项二次根式参数,例如:
>>>q1 = QR("3.14", 2)
>>>p1 = PR([12, 98])
>>>_test = PR(q1, p1, QR("2/3", 10), PR(q1, [9, 8]), ["5/3", 20])
>>>_test.pt()
4、加多项二次根式:
>>>_test.add(["2.5", 3], PR(["7.5", 18])).pt()
5、减多项二次根式:
>>>_test.sub(PR(["3/2",32], ["3/4",20])).pt()
6、乘多项二次根式:
>>>_test.mul([1,30],[1]).pt()
7、除以常数:
>>>_test.div("-1/2").pt()
8、除以单项二次根式:
>>>_test.div(["1/2","1/10"]).pt()
9、除以二项二次根式:
>>>_test.div(["1/2","1/10"], ["0.125", "3.75"]).pt()
10、乘方:
>>>PR([1,3],[1,2]).pow(5).pt()
'''
import math
from fractions import Fraction
#二次方根数类
class QR:
'''quadratic radical'''
coefficient = 0 #系数 有理数
bottom = 1 #方根的底——非负有理数
#相反数
def opp(self):
if self.coefficient != None:
self.coefficient = -self.coefficient
return self
#倒数
def rec(self):
self.coefficient = Fraction(1, self.coefficient * self.bottom)
return self
#克隆
def clone(self):
return QR(self.coefficient, self.bottom)
#打印
def print(self, isFirst):
if self.coefficient == None or self.coefficient == 0 or self.bottom == None or self.bottom == 0:
return ""
else:
if self.coefficient == 1:
s = ""
elif self.coefficient == -1:
s = "-"
else:
s = str(self.coefficient)
if self.coefficient > 0:
if not isFirst:
s = "+" + s
if self.bottom != 1:
s += "sqrt(%d)" % self.bottom
return s
#比较大小:底降序
#第二个要在前正值;合并0;其它负值
def cmp(pr, otherPr):
return otherPr.bottom - pr.bottom;
#初始化方法
def __init__(self, coefficient=0, bottom=1):
#print("coefficient=",coefficient,"bottom=",bottom)
if not isinstance(coefficient, (int, Fraction, str)) or not isinstance(bottom, (int, Fraction, str)):
raise ValueError("输入的不是整数、分数或字符串(小数、分数)!")
if isinstance(coefficient, (str)):
coefficient = Fraction(coefficient)
if isinstance(bottom, (str)):
bottom = Fraction(bottom)
if bottom < 0:
raise ValueError("底数不可以小于0!")
self.coefficient = coefficient
self.bottom = bottom
self.__simplestQuadraticRadical() #化简
#平方方法
def square(self):
return self.coefficient**2 * self.bottom
#描述自己
def __str__(self):
if self.coefficient == 0 or self.bottom == 0:
return "0"
if self.bottom == 1:
return str(self.coefficient)
return "%ssqrt(%s)" % (str(self.coefficient), str(self.bottom))
#化成最简二次根式
def __simplestQuadraticRadical(self):
#如果底是分数,就化为整数
if isinstance(self.bottom, (Fraction)):
self.coefficient = Fraction(self.coefficient, self.bottom.denominator)
self.bottom = self.bottom.numerator * self.bottom.denominator
return self.__firstStep()
#第一步:检测自己是否是平方数,如果是就变成整数
def __firstStep(self):
#print("第一步:检测自己是否是平方数")
tmp = round(math.sqrt(self.bottom)) #开方的最近整数
if tmp ** 2 == self.bottom:
self.coefficient *= tmp
self.bottom = 1
return self
return self.__secondStep()
#第二步:如果不是平方数,计算最大的可能因数
def __secondStep(self):
#print("第二步:如果不是平方数,计算最大的可能因数")
maxNum = self.bottom // 2
return self.__thirdStep(maxNum)
#第三步:寻找不大于最大的可能因数的最近平方数
def __thirdStep(self, maxNum):
#print("第三步:寻找不小于最大的可能因数的最近平方数")
end = math.ceil(math.sqrt(maxNum))
return self.__fourthStep(end)
#第四步:分解平方数的因数
def __fourthStep(self, end):
#print("第四步:分解平方数的因数")
factors = [] #平方数是self.intNum的因数的数
startNum = self.bottom #开始数
for i in range(end, 1, -1):
i2 = i ** 2
endNum = startNum // i2
if i2 * endNum == startNum:
factors.append(i)
startNum = endNum
return self.__fifthStep(factors, startNum)
#第五步:平方数因数开方成倍数,根式化成最简式
def __fifthStep(self, factors, startNum):
#print("第五步:平方数因数开方成倍数,根式化成最简式")
if len(factors) == 0:
return self #根式已经是最简根式
else:
self.coefficient *= self.__getCoefficient(factors)
self.bottom = startNum
return self
#根据因数的二次方根,生成最简根式的系数
def __getCoefficient(self, factors):
rst = 1
for f in factors:
rst *= f
return rst
#乘二次根式
def mul(self, otherQr):
self.coefficient *= otherQr.coefficient
self.bottom *= otherQr.bottom
return self.__simplestQuadraticRadical()
#多项二次根式
class PR:
'''多项quadratic radical'''
#项quadratic radical列表
terms = None
#克隆
def __clone(self):
p = PR()
if self.terms == None or len(self.terms) == 0:
return p
lth = len(self.terms)
t = []
for i in range(lth):
t.append(self.terms[i].clone())
p.terms = t
return p
#排序合并同类项,按底数从大到小
def __sort1(terms, idx, num):
term = terms[num] #需检查的元素
for i in range(idx+1): #把元素插入或合并到结果中
m = terms[i]
t = m.cmp(term) #比较
if t == 0: #合并同类项
m.coefficient += term.coefficient
return idx
elif t > 0: #新的高阶项,高阶项插入当前位置
idx += 1
for p in range(idx, i, -1): #后推其它项
terms[p] = terms[p-1]
terms[i] = term #插入该项
return idx #返回结果数
idx += 1
terms[idx] = term #把新项插在结果最后
return idx
#合并同类项与排序
def __sort(terms):
idx = 0 #结果下标
lth = len(terms)
for num in range(1, lth):
idx = PR.__sort1(terms, idx, num) #排序和合并1项
#print("idx=%d" % idx)
#消除0系数项
temp = []
for num in range(idx +1):
term = terms[num]
if term.coefficient != 0:
temp.append(term)
nlth = len(temp)
if nlth == 0:
del(terms[0:])
return terms
else:
for num in range(nlth):
terms[num] = temp[num]
if nlth < lth:
del(terms[nlth:])
return terms;
#打印自己
def __str__(self):
s = "原式="
if self.terms == None or len(self.terms) == 0:
s += "0"
else:
s += self.terms[0].print(True)
for i in range(1, len(self.terms)):
s += self.terms[i].print(False)
return s
def pt(self):
print(self)
#加
def __add(self, isSub, *terms):
if terms != None and len(terms) > 0:
if self.terms == None:
self.terms = []
for term in terms:
if isinstance(term, PR):
if term.terms != None and len(term.terms) > 0:
for t in term.terms:
if isSub:
self.terms.append(t.clone().opp()) #克隆,保证原式不受影响
else:
self.terms.append(t.clone())
else:
if isinstance(term, QR):
if isSub:
self.terms.append(term.clone().opp()) #克隆防止影响原对象
else:
self.terms.append(term.clone())
else:
if isSub:
self.terms.append(QR(*term).opp()) #解包list添加1个单项式,无需克隆
else:
self.terms.append(QR(*term))
PR.__sort(self.terms) #排序
def add(self, *terms):
s = self.__clone() #克隆防止改变原对象
s.__add(False, *terms)
return s
#减
def sub(self, *terms):
s = self.__clone() #克隆防止改变原对象
s.__add(True, *terms)
return s
#乘除常数,私有方法不克隆
def __muldiv(self, fraction, isdiv):
if self.terms != None and len(self.terms) >0:
if isinstance(fraction, (int, Fraction)):
p = fraction
else:
p = Fraction(fraction)
for term in self.terms:
if isdiv:
term.coefficient /= p
else:
term.coefficient *= p
return self
#多项乘单项,私有方法都不可以克隆
def __mul(pr, qr):
for term in pr.terms:
term.mul(qr)
PR.__sort(pr.terms) #排序
return pr
#乘
def mul(self, *terms):
if terms == None or len(terms) == 0: #空调用返回自己
return self
if len(terms) == 1 and isinstance(terms[0],(int, Fraction, str)): #乘一个有理数
return self.__clone().__muldiv(terms[0], False) #需要克隆对象
p = PR(*terms) #建立要乘的多项式 如果里面有Mn或Pn,则它们会被克隆
if self.terms == None or len(self.terms) == 0: #self是空多项式可忽略
return p
elif p.terms != None and len(p.terms) >0:
lth = len(p.terms)
s = self.__clone().__mul(p.terms[0]) #乘单项式
if lth == 1:
return s
for i in range(lth-1): #克隆对象乘
s.__add(False, self.__clone().__mul(p.terms[i+1]))
return s
else: #p为空多项式
return self;
#乘方
def pow(self, num):
if not isinstance(num, (int)) or num < 2:
print("请输入大于1的整数")
return self
if self.terms == None or len(self.terms) == 0:
return self
s = self.__clone()
for i in range(num-1):
s = s.mul(self) # 由于mul会克隆,这里不用克隆
return s
#2项式倒数,使用平方差公式
def __rec2(self):
d = self.terms[0].square() - self.terms[1].square() #分母
self.terms[1].opp() #第二项取相反数
return self.__muldiv(d, True)
#除
def div(self, *terms):
if terms == None or len(terms) == 0: #空调用返回自己
return self
if len(terms) == 1 and isinstance(terms[0],(int, Fraction, str)):
return self.__clone().__muldiv(terms[0], True)
pq = PR(*terms)
if pq.terms == None or len(pq.terms) == 0:
return self
elif len(pq.terms) == 1:
return self.__clone().__mul(pq.terms[0].rec())
elif len(pq.terms) == 2: #只处理2项式
return self.mul(pq.__rec2()) #2项式倒数
else:
raise ValueError("除数多项二次根式超过了2项,超出本模块处理范围!")
#构造
def __init__(self, *terms):
if terms == None or len(terms) > 0:
self.terms = []
for term in terms:
if isinstance(term, (QR)):
self.terms.append(term.clone())
elif isinstance(term, (PR)):
if term.terms != None and len(term.terms) > 0:
for t in term.terms:
self.terms.append(t.clone())
else:
self.terms.append(QR(*term)) #解包参数
PR.__sort(self.terms) #排序合并同类项,按底数从大到小
if __name__ == "__main__":
print("\n二次根式测试:")
print("\n导入二次根式模块:")
print('>>>from quadraticradical import *')
print("\n构造函数测试:")
print('>>>_qr = QR("3/2", 32)')
print('>>>_pr = PR(["3/5", 8])')
print('>>>_test = PR(["-3.14", 128], _qr, _pr, [4])')
print('>>>_test.pt()')
_qr = QR("3/2", 32)
_pr = PR(["3/5", 8])
_test = PR(["-3.14", 128], _qr, _pr, [4])
_test.pt()
print("对比")
print('>>>_test = PR(["-3.14", 128], ["3/2", 32], ["3/5", 8], [4])')
print('>>>_test.pt()')
_test = PR(["-3.14", 128], ["3/2", 32], ["3/5", 8], [4])
_test.pt()
print("\n减多项二次根式测试:")
print('>>>_test.sub(PR(["3/2",162], ["3/4",27])).pt()')
_test.sub(PR(["3/2",162], ["3/4",27])).pt()
print("\n加多项二次根式测试:")
print('>>>_test.add(["2.5", 125], PR(["7.5", 45])).pt()')
_test.add(["2.5", 125], PR(["7.5", 45])).pt()
print("\n乘多项二次根式测试:")
print('>>>_test.mul([1,2],[3, 5]).pt()')
_test.mul([1,2],[3, 5]).pt()
print("\n多项二次根式除以常数测试:")
print('>>>_test.div("-1/2").pt() ')
_test.div("-1/2").pt()
print("\n多项二次根式乘方测试:")
print('>>>PR([1,2],[1,3]).pow(5).pt()')
PR([1,2],[1,3]).pow(5).pt()
print("\n多项二次根式除以一项二次根式测试:")
print('>>>_test.div(["-1/2", 8]).pt() ')
_test.div(["-1/2", 8]).pt()
print("\n多项二次根式除以二项二次根式测试:")
print('>>>_test.div(["-1/2", 8],[1]).pt() ')
_test.div(["-1/2", 8],[1]).pt()
复制到quadraticradical.py文件中,生成二次根式运算模块:
;运行模块无异常:
。
第二步、按说明导入模块。
。
第三步、按照模块的使用说明测试课本例题。
1、二次根式
2、二次根式的乘除
3、二次根式的加减
练习题:用二次根式计算器计算你做过的练习题,核对结果。