Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python3
- # file: poly.py
- import sys
- from fractions import gcd
- class Fraction:
- def reduce(self):
- g = gcd(self.a, self.b)
- self.a //= g
- self.b //= g
- def __init__(self, a = None, b = None):
- if b is not None:
- self.a = a
- self.b = b
- else:
- if a is None:
- self.a = 0
- self.b = 1
- if type(a) == Fraction:
- self.a = a.a
- self.b = a.b
- if type(a) == int:
- self.a = a
- self.b = 1
- if type(a) == str:
- a = a.rstrip()
- if a.find("/") != -1:
- lst = a.split("/")
- else:
- lst = a.split(" ")
- if len(lst) == 2:
- self.a, self.b = map(int, lst)
- else:
- self.a = int(lst[0])
- self.b = 1
- self.reduce()
- def __str__(self):
- if self.b == 1:
- return str(self.a)
- else:
- return "/".join(map(str, (self.a, self.b)))
- def __lt__(self, other):
- if type(other) == int:
- return self < Fraction(other)
- elif type(other) == float:
- return float(self.a) < float(self.b) * other
- elif type(other) == Fraction:
- return self.a * other.b < other.a * self.b
- else:
- return NotImplemented
- def __gt__(self, other):
- if type(other) == int:
- return self > Fraction(other)
- elif type(other) == float:
- return float(self.a) > float(self.b) * other
- elif type(other) == Fraction:
- return self.a * other.b > other.a * self.b
- else:
- return NotImplemented
- def __eq__(self, other):
- return not (self < other) and not(self > other)
- def __le__(self, other):
- return self < other or self == other
- def __ge__(self, other):
- return self > other or self == other
- def __ne__(self, other):
- return not self == other
- def __mul__(self, other):
- if type(other) == Fraction:
- return Fraction(self.a * other.a, self.b * other.b)
- elif type(other) == int:
- return Fraction(self.a * other, self.b)
- elif type(other) == float:
- return self.a * other / self.b
- else:
- return NotImplemented
- def __rmul__(self, other):
- return self * other
- def __imul__(self, other):
- self = self * other
- return self
- def __truediv__(self, other):
- if self == 0:
- return Fraction()
- elif type(other) == Fraction:
- return Fraction(self.a * other.b, self.b * other.a)
- elif type(other) == int:
- return self / Fraction(other)
- elif type(other) == float:
- return (self.a / self.b) / other
- else:
- return NotImplemented
- def __rtruediv__(self, other):
- return Fraction(1) / (self / other)
- def __itruediv__(self, other):
- self = self / other
- return self
- def __pow__(self, other):
- if type(other) == int:
- if other < 0:
- return 1 / (self ** (-other))
- else:
- res = Fraction()
- res.a = self.a ** other
- res.b = self.b ** other
- return res
- elif type(other) == Fraction:
- return (self.a / self.b) ** (other.a / other.b)
- else:
- return (self.a / self.b) ** other
- def __rpow__(self, other):
- return other ** (self.a / self.b)
- def __ipow__(self, other):
- self = self ** other
- return self
- def __add__(self, other):
- if type(other) == float:
- return (self.a / self.b) + other
- elif type(other) == Fraction:
- return Fraction(self.a * other.b + other.a * self.b, self.b * other.b)
- elif type(other) == int:
- return self + Fraction(other)
- else:
- return NotImplemented
- def __radd__(self, other):
- return self + other
- def __iadd__(self, other):
- self = self + other
- return self
- def __sub__(self, other):
- return self + (-1) * other
- def __rsub__(self, other):
- return other + (-1) * self
- def __isub__(self, other):
- self += (-1) * other
- return self
- def __pos__(self):
- return self
- def __neg__(self):
- return (-1) * self
- def __abs__(self):
- if self.a < 0:
- res = Fraction()
- res.a = -self.a
- res.b = self.b
- return res
- else:
- return self
- def __int__(self):
- return self.a // self.b
- def __float__(self):
- return self.a / self.b
- def __round__(self, a = 0):
- return round(float(self), a)
- class Poly:
- def __reduce(self):
- i = len(self) - 1
- while i > 0 and self.__coef[i] == 0:
- i -= 1
- self.__coef = self.__coef[:i + 1]
- def __init__(self, arg=None, should_copy=True):
- self.__symbol_string = "".join(map(chr, [8304, 185, 178, 179, 8308, 8309, 8310, 8311, 8312, 8313]))
- if arg is None:
- self.__coef = [0]
- elif type(arg) in [int, float, Fraction]:
- self.__coef = [arg]
- elif type(arg) == list:
- if should_copy:
- self.__coef = arg[:]
- else:
- self.__coef = arg
- elif type(arg) == tuple:
- self.__coef = list(arg)
- elif type(arg) == str:
- self.__coef = list(map(eval, arg.split()))
- elif type(arg) == Poly:
- self.__coef = arg.__coef[:]
- self.__reduce()
- def __int2upper_str(self, n):
- return "".join(map(lambda c: self.__symbol_string[ord(c) - ord('0')], str(n)))
- def __monomial2str(self, i):
- res = ""
- if i == 0:
- if type(self.__coef[i]) == float:
- if self.__coef[i] < 0:
- if 1 == len(self.__coef):
- return str(round(self.__coef[i], 3))
- else:
- return "- " + str(-round(self.__coef[i], 3))
- else:
- if 1 == len(self.__coef):
- return str(round(self.__coef[i], 3))
- else:
- return "+ " + str(round(self.__coef[i], 3))
- elif type(self.__coef[i]) == Fraction and self.__coef[i].b != 1:
- if self.__coef[i] < 0:
- if 1 == len(self.__coef):
- return "-(" + str(-self.__coef[i]) + ")"
- else:
- return "- (" + str(-self.__coef[i]) + ")"
- else:
- if 1 == len(self.__coef):
- return "(" + str(self.__coef[i]) + ")"
- else:
- return "+ (" + str(self.__coef[i]) + ")"
- else:
- if 1 == len(self.__coef):
- return str(self.__coef[i])
- else:
- if self.__coef[i] < 0:
- return "- " + str(-self.__coef[i])
- else:
- return "+ " + str(self.__coef[i])
- if self.__coef[i] < 0:
- res += "-"
- elif i < len(self.__coef) - 1:
- res += "+"
- if i < len(self.__coef) - 1:
- res += " "
- if type(self.__coef[i]) == Fraction:
- if self.__coef[i].b != 1:
- res += "(" + str(abs(self.__coef[i])) + ")"
- elif self.__coef[i].b == 1:
- if abs(self.__coef[i].a) != 1:
- res += str(abs(self.__coef[i].a))
- elif type(self.__coef[i]) == int:
- if abs(self.__coef[i]) != 1:
- res += str(abs(self.__coef[i]))
- else:
- k = abs(round(self.__coef[i], 3))
- if k != 1:
- res += str(k)
- if i == 0:
- return res
- elif i == 1:
- res += "x"
- else:
- res += "x" + self.__int2upper_str(i)
- return res
- def __str__(self):
- if self.__coef == [0]:
- return "0"
- res = []
- for i in range(len(self.__coef) - 1, -1, -1):
- if self.__coef[i] != 0:
- res.append(self.__monomial2str(i))
- return " ".join(res)
- def __len__(self):
- return len(self.__coef)
- def __add__(self, other):
- if isinstance(other, Poly):
- a = len(self)
- b = len(other)
- l = max(a, b)
- res = [0 for i in range(l)]
- for i in range(l):
- if i < a:
- res[i] += self.__coef[i]
- if i < b:
- res[i] += other.__coef[i]
- return Poly(res, False)
- else:
- res = self.__coef[:]
- res[0] = res[0] + other
- return Poly(res)
- def __radd__(self, other):
- return self + other
- def __iadd__(self, other):
- self.__coef = (self + other).__coef
- return self
- import random
- random.seed(837283918)
- __count = 0
- def TEST(title = ''):
- global __count
- __count += 1
- print()
- print('=====================================')
- print('Подтест ', __count, ':', title)
- def randInt():
- return random.randint(-1000, 1000)
- def randFloat():
- return random.random() * 2000 - 1000
- def randFraction():
- a = random.randint(-1000, 1000)
- b = random.randint(-1000, 1000)
- while b == 0:
- b = random.randint(-1000, 1000)
- return Fraction(a, b)
- def randZero():
- return random.choice([0, 0.0, Fraction(0)])
- def Zero():
- return 0
- def randCoeff(genFunc = [randInt, randFloat, randFraction, randZero]):
- return random.choice(genFunc)()
- def randIntPoly(n=100):
- L = [randInt() for j in range(random.randint(1, n))]
- while L[-1] == 0:
- L[-1] = randInt()
- return Poly(L)
- def randFractionPoly(n=100):
- L = [randFraction() for j in range(random.randint(1, n))]
- while L[-1] == 0:
- L[-1] = randFraction()
- return Poly(L)
- def randFloatPoly(n=100):
- L = [randFloat() for j in range(random.randint(1, n))]
- while L[-1] == 0:
- L[-1] = randFloat()
- return Poly(L)
- def randPoly(n=100):
- L = [randCoeff() for j in range(random.randint(1, n))]
- while L[-1] == 0:
- L[-1] = randCoeff()
- return Poly(L)
- print('Тестируются сложение многочленов')
- TEST('Метод __add__ для Poly + Poly')
- _A = Poly([2, 3, 1, 3, 4, 5, 1, 2])
- _B = Poly([1, 5, 7, 1, 2])
- _C = _A + _B
- print(_C)
- _A = Poly([-2, 3, -1, -5, 1, -2])
- _B = Poly([1, -5, -7, 1, -2, 3, -3, -1, 2])
- _C = _A + _B
- print(_C)
- _A = Poly([1, 2, 3])
- _B = Poly([1, 2, -3])
- _C = _A + _B
- print(_C)
- TEST('Метод __add__ для Poly + int')
- _A = Poly([2, 3, 1, 3, 4, 5, 1, 2])
- _B = -7
- _C = _A + _B
- print(_C)
- _A = Poly([2, 0, 1])
- _B = -2
- _C = _A + _B
- print(_C)
- _A = Poly([Fraction(12, 7), 0, 1])
- _B = 1
- _C = _A + _B
- print(_C)
- _A = Poly([1.5, 0, 1])
- _B = 1
- _C = _A + _B
- print(_C)
- TEST('Метод __add__ для Poly + Fraction')
- _A = Poly([2, 3, 1, 3, 4, 5, 1, 2])
- _B = Fraction(19, 4)
- _C = _A + _B
- print(_C)
- _A = Poly([2, 0, 1])
- _B = Fraction(-6, 3)
- _C = _A + _B
- print(_C)
- _A = Poly([Fraction(12, 7), 0, 1])
- _B = Fraction(-18, 5)
- _C = _A + _B
- print(_C)
- _A = Poly([1.5, 0, 1])
- _B = Fraction(14, 9)
- _C = _A + _B
- print(_C)
- TEST('Метод __add__ для Poly + float')
- _A = Poly([2, 3, 1, 3, 4, 5, 1, 2])
- _B = 12.35
- _C = _A + _B
- print(_C)
- _A = Poly([2, 0, 1])
- _B = -2.0
- _C = _A + _B
- print(_C)
- _A = Poly([Fraction(12, 7), 0, 1])
- _B = 13.24
- _C = _A + _B
- print(_C)
- _A = Poly([1.5, 0, 1])
- _B = 17.81
- _C = _A + _B
- print(_C)
- TEST('Метод __iadd__ для Poly + Poly')
- _A = Poly([2, 3, 1, 3, 4, 5, 1, 2])
- _B = Poly([1, 5, 7, 1, 2])
- _A += _B
- print(_A)
- _A = Poly([-2, 3, -1, -5, 1, -2])
- _B = Poly([1, -5, -7, 1, -2, 3, -3, -1, 2])
- _A += _B
- print(_A)
- _A = Poly([1, 2, 3])
- _B = Poly([1, 2, -3])
- _A += _B
- print(_A)
- TEST('Метод __iadd__ для Poly + int')
- _A = Poly([2, 3, 1, 3, 4, 5, 1, 2])
- _B = -7
- _A += _B
- print(_A)
- _A = Poly([2, 0, 1])
- _B = -2
- _A += _B
- print(_A)
- _A = Poly([Fraction(12, 7), 0, 1])
- _B = 1
- _A += _B
- print(_A)
- _A = Poly([1.5, 0, 1])
- _B = 1
- _A += _B
- print(_A)
- TEST('Метод __iadd__ для Poly + Fraction')
- _A = Poly([2, 3, 1, 3, 4, 5, 1, 2])
- _B = Fraction(19, 4)
- _A += _B
- print(_A)
- _A = Poly([2, 0, 1])
- _B = Fraction(-6, 3)
- _A += _B
- print(_A)
- _A = Poly([Fraction(12, 7), 0, 1])
- _B = Fraction(-18, 5)
- _A += _B
- print(_A)
- _A = Poly([1.5, 0, 1])
- _B = Fraction(14, 9)
- _A += _B
- print(_A)
- TEST('Метод __iadd__ для Poly + float')
- _A = Poly([2, 3, 1, 3, 4, 5, 1, 2])
- _B = 12.35
- _A += _B
- print(_A)
- _A = Poly([2, 0, 1])
- _B = -2.0
- _A += _B
- print(_A)
- _A = Poly([Fraction(12, 7), 0, 1])
- _B = 13.24
- _A += _B
- print(_A)
- _A = Poly([1.5, 0, 1])
- _B = 17.81
- _A += _B
- print(_A)
- TEST('Метод __radd__ для Poly + int')
- _A = Poly([2, 3, 1, 3, 4, 5, 1, 2])
- _B = -7
- _C = _B + _A
- print(_C)
- _A = Poly([2, 0, 1])
- _B = -2
- _C = _B + _A
- print(_C)
- _A = Poly([Fraction(12, 7), 0, 1])
- _B = 1
- _C = _B + _A
- print(_C)
- _A = Poly([1.5, 0, 1])
- _B = 1
- _C = _B + _A
- print(_C)
- TEST('Метод __radd__ для Poly + Fraction')
- _A = Poly([2, 3, 1, 3, 4, 5, 1, 2])
- _B = Fraction(19, 4)
- _C = _B + _A
- print(_C)
- _A = Poly([2, 0, 1])
- _B = Fraction(-6, 3)
- _C = _B + _A
- print(_C)
- _A = Poly([Fraction(12, 7), 0, 1])
- _B = Fraction(-18, 5)
- _C = _B + _A
- print(_C)
- _A = Poly([1.5, 0, 1])
- _B = Fraction(14, 9)
- _C = _B + _A
- print(_C)
- TEST('Метод __radd__ для Poly + float')
- _A = Poly([2, 3, 1, 3, 4, 5, 1, 2])
- _B = 12.35
- _C = _B + _A
- print(_C)
- _A = Poly([2, 0, 1])
- _B = -2.0
- _C = _B + _A
- print(_C)
- _A = Poly([Fraction(12, 7), 0, 1])
- _B = 13.24
- _C = _B + _A
- print(_C)
- _A = Poly([1.5, 0, 1])
- _B = 17.81
- _C = _B + _A
- print(_C)
- TEST('Специальные тесты на корректность реализации __iadd__')
- _A = Poly([1, 1, 1])
- _B = Poly([1, 1])
- _D = _A
- _A += _B
- print(_D)
- _A += _B
- print(_D)
- _A += _B
- print(_D)
- _A += 1
- print(_D)
- _A += Fraction(1, 2)
- print(_D)
- _A += 1.2
- print(_D)
- for i in range(100):
- TEST('Большой случайный тест')
- if i % 4 == 0:
- _A = randPoly()
- _B = randPoly()
- _x = randCoeff()
- elif i % 4 == 1:
- _A = randIntPoly()
- _B = randIntPoly()
- _x = randInt()
- elif i % 4 == 2:
- _A = randFractionPoly()
- _B = randFractionPoly()
- _x = randFraction()
- elif i % 4 == 3:
- _A = randFloatPoly()
- _B = randFloatPoly()
- _x = randFloat()
- _C = _A + _B
- _D = Poly(_A)
- _D += _B
- _E = _A + _x
- _F = Poly(_A)
- _F += _x
- _G = _x + _A
- print("Source data:")
- print("A = ", _A)
- print("B = ", _B)
- print("x = ", _x)
- print("Result:")
- print("C = ", _C)
- print("D = ", _D)
- print("E = ", _E)
- print("F = ", _F)
- print("G = ", _G)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement