How to properly print the output __str__ - python

How to properly print the output str
class Complex(object):
def __init__(self, real, imaginary):
self.real = real
self.imaginary = imaginary
def __add__(self, other):
return Complex(self.real+other.real, self.imaginary+other.imaginary)
def __sub__(self, other):
return Complex(self.real-other.real, self.imaginary-other.imaginary)
def __str__(self):
return '{} & {}i'.format(self.real, self.imaginary)
if __name__ == '__main__':
c = map(float, input().split())
d = map(float, input().split())
x = Complex(*c)
#print (x)
y = Complex(*d)
#print (y)
print(*map(str, [x+y, x-y]), sep='\n')
Input
2 1
5 6
Output
7.0 & 7.0i
-3.0 & -5.0i
Expected out if for addtion it should print + and for substraction it should print -
7.00+7.00i
-3.00-5.00i

class Complex(object):
def __init__(self, real, imaginary):
self.real = real
self.imaginary = imaginary
def __add__(self, other):
return Complex(self.real+other.real, self.imaginary+other.imaginary)
def __sub__(self, other):
return Complex(self.real-other.real, self.imaginary-other.imaginary)
def __str__(self):
return '{:.2f}{}{:.2f}i'.format(self.real, '+' if self.imaginary >= 0 else '', self.imaginary)
if __name__ == '__main__':
c = map(float, input().split())
d = map(float, input().split())
x = Complex(*c)
#print (x)
y = Complex(*d)
#print (y)
print(*map(str, [x+y, x-y]), sep='\n')
You should manually add sign, if var is positive.
Also in your expected result you have 2 decimal points, so you need to add {:.2f}.

Use this in your str implementation.
def __str__(self):
return f"{self.real}{ '+' if self.imaginary >= 0 else ''}{self.imaginary}i"

Instead of this:
def __str__(self):
return '{} & {}i'.format(self.real, self.imaginary)
You could do this:
def __str__(self):
def __map_imaginary(imag):
if imag > 0:
return "+{:2f}i".format(imag)
if imag < 0:
return "{:2f}i".format(imag)
if imag == 0:
return ""
return "{}{}".format(self.real, __map_imaginary(self.imag))
I have assumed that you don't want to print imaginary part if it equals to 0. You can change that at will.

Related

Trying to Add two Points on ECC but the third point is always not on the curve

I'm using this code to add two points together using finite Fields
class FieldElement():
def __init__(self,num,prime):
if num>=prime or num < 0:
error = "num s not in field"
raise ValueError(error)
self.num = num
self.prime=prime
def __eq__(self,other):
if other is None:
return
return self.num == other.num and self.prime == other.prime
def __ne__(self,other):
return not (self == other)
def __add__ (self,other):
if self.prime != other.prime:
raise ValueError("cannot add two numbers in diffirent fields")
num = (self.num+other.num)%self.prime
return self.__class__(num,self.prime)
def __mul__(self,other):
if self.prime != other.prime:
raise ValueError("cannot add two numbers in different fields")
num = (self.num * other.num)%self.prime
return self.__class__(num,self.prime)
def __pow__(self,exponent):
n = exponent%(self.prime-1)
num = pow(self.num,n,self.prime)
return self.__class__(num,self.prime)
def __sub__(self,other):
if self.prime != other.prime:
raise ValueError("cannot add two numbers in different fields")
num = (other.num - self.num)%self.prime
return self.__class__(num,self.prime)
def __truediv__(self,other):
if self.prime != other.prime:
raise TypeError("cannot divide two numbers in different Fields")
num = self.num * pow(other.num,self.prime-2,self.prime)%self.prime
return self.__class__(num,self.prime)
class Point ():
def __init__(self, x,y,a,b):
self.a = a
self.b = b
self.y = y
self.x = x
if self.x is None and self.y is None:
return
if (self.y**2) != (self.x**3 + a*x + b):
raise ValueError("{} , {} not in the Curve".format(x.num,y.num))
def __repr__(self):
return "Point({},{}){}_{}".format(self.x,self.y,self.a,self.b)
def __eq__(self,other):
return self.x == other.x and self.y == other.y and self.a == other.a and self.b == other.b
def __add__(self,other):
if other.a != self.a or other.b != self.b:
raise TypeError("Points{},{} are the same curve".format(self,other))
if self.x is None:
return other
if other.x is None:
return self
if other.x == self.x and other.y != self.y:
return self.__class__(None,None,self.a,self.b)
if self != other:
s = (other.y-self.y)/(other.x-self.x)
x = (s**2 - self.x - other.x)
y = s*(self.x - x) - self.y
return self.__class__(x,y,self.a,self.b)
if self == other :
s = (3*self.x**2+self.a)/(2* self.y)
x = s**2-2*self.x
y = s*(self.x-x)-self.y
return self.__class__(x,y,self.a,self.b)
if self == other and self.y == 0*self.x:
return self.__class__(None,None,self.a,self.b)
def __eq__(self,other):
return self.x == other.x and self.y == other.y and self.a==other.a and self.b==other.b
def __mul__(self,other):
numX = self.x * other.x
numY = self.y * other.y
return self.__class__(numX,numY,self.a,self.b)
and the bellow code to test it ,
from test import FieldElement,Point
prime = 223
a = FieldElement(num=0,prime=prime)
b = FieldElement(num=7,prime=prime)
x1 = FieldElement(num=47,prime=prime)
y1 = FieldElement(num=71,prime=prime)
x2 = FieldElement(num=17,prime=prime)
y2 = FieldElement(num=56,prime=prime)
p1 = Point(x1,y1,a,b)
p2 = Point(x2,y2,a,b)
p3 = p1+p2
print(p3)
Whatever points I add I get the same error that the third point is not on the the curve, I think the problem is on if (self.y**2) != (self.x**3 + a*x + b) some how it's not checking the new point correctly or Point __add__ method does not calculate the new point correctly, what am missing here ?
You should test every module before use
In the Field, the subtraction is wrong! you calculate b-a not a-b
def __sub__(self,other):
if self.prime != other.prime:
raise ValueError("cannot add two numbers in different fields")
num = (other.num - self.num)%self.prime
return self.__class__(num,self.prime)
must be
def __sub__(self,other):
if self.prime != other.prime:
raise ValueError("cannot add two numbers in different fields")
num = (self.num - other.num)%self.prime
return self.__class__(num,self.prime)
The other problem as stated in the other answer doesn't make a problem since the first operand is the member of the class, however, you should use
if (self.y**2) != (self.x**3 + self.a*self.x + self.b):
You should also implement __str__ for your field and point classes to print easy to test your code!
def __str__(self):
return num
I've tested and now works. The below is the SageMath Code (test here) that you can compare the result and use a test base for your code.
E = EllipticCurve(GF(223),[0,7])
print(E)
R1 = E(47,71)
R2 = E(17,56)
print(R1+R2)
I think that the line:
if (self.y**2) != (self.x**3 + a*x + b):
should be
if (self.y**2) != (self.x**3 + self.a*self.x + self.b):
as a, x and b will not be treated as field elements.

How to get output in Real Number instead of complex number?

I made the following code to solve any quadratic polynomial but I want the final output to be a Real Number (Either a whole number or a fraction) but I get Complex numbers like (3+0j). How to convert them?
Here is the Code:-
import cmath
a = float(raw_input("Enter the Coefficient of x^2 :- "))
b = float(raw_input("Enter the coefficient of x :- "))
c = float(raw_input("Enter the value of constant term or c :- "))
d = ((b*b) - (4*a*c))
if d < 0:
print "There are no Real Roots of this equation"
else:
x1 = (((-b) + cmath.sqrt(float(d))) // 2*a)
x2 = (((-b) - cmath.sqrt(float(d))) // 2*a)
if x1 == x2:
print "x = ", x1
else:
print "x = ", x1, "or", x2
Desired Result:- I want the final result to be a Real Number(both Rational and irrational is allowed including fractions)(Like: 4, 4/3 or something like that).
Simply only print the real part, besides you have to devide by 2a
x1 = (((-b) + cmath.sqrt(float(d))) / (2*a))
x2 = (((-b) - cmath.sqrt(float(d))) / (2*a))
if x1 == x2:
print "x = ", x1.real
else:
print "x = ", x1.real, "or", x2.real
You can use a class like Complex and support imaginary solutions as well.
Code taken from http://hplgit.github.io/primer.html/doc/pub/class/._class-solarized005.html
class Complex(object):
def __init__(self, real, imag=0.0):
self.real = real
self.imag = imag
def __add__(self, other):
return Complex(self.real + other.real,
self.imag + other.imag)
def __sub__(self, other):
return Complex(self.real - other.real,
self.imag - other.imag)
def __mul__(self, other):
return Complex(self.real*other.real - self.imag*other.imag,
self.imag*other.real + self.real*other.imag)
def __div__(self, other):
sr, si, or, oi = self.real, self.imag, \
other.real, other.imag # short forms
r = float(or**2 + oi**2)
return Complex((sr*or+si*oi)/r, (si*or-sr*oi)/r)
def __abs__(self):
return sqrt(self.real**2 + self.imag**2)
def __neg__(self): # defines -c (c is Complex)
return Complex(-self.real, -self.imag)
def __eq__(self, other):
return self.real == other.real and self.imag == other.imag
def __ne__(self, other):
return not self.__eq__(other)
def __str__(self):
return '(%g, %g)' % (self.real, self.imag)
def __repr__(self):
return 'Complex' + str(self)
def __pow__(self, power):
raise NotImplementedError\
('self**power is not yet impl. for Complex')

Manipulating Python Magic Methods

I have more of a background with data science libraries or calling methods and attributes from classes. I am experimenting with manipulating magic methods. I am having a difficult time getting bool types and returning their opposites.
I did something with str and datetime objects that worked but can't seem to to the same with __cmp__, __lt__, __eq__ or `gt'. Here is my code:
class Opposite:
def __cmp__(self, other):
if other.__class__.__name__ == 'bool':
return other
def __lt__(self, other):
if other.__class__.__name__ == 'bool':
return other
def __eq__(self, other):
if other.__class__.__name__ == 'bool':
return other
def __gt__(self, other):
if other.__class__.__name__ == 'bool':
return other
if __name__=="__main__":
""" test class Compare """
a = 1
b = 1
c = a < b
d = a > b
e = a == b
print("Results:\na\t{}\nb\t{}\nc\t{}\nd\t{}\ne\t{}\n".format(a,b,c,d,e))
print("\nType:\na-type\t{}\nb-type\t{}\nc-type\t{}\nd-type\t{}\ne-type\t{}\n"
.format(type(a),type(b),type(c),type(d),type(e)))
This prints the following:
Results:
a 1
b 1
c False
d False
e True
Type:
a-type <class 'int'>
b-type <class 'int'>
c-type <class 'bool'>
d-type <class 'bool'>
e-type <class 'bool'>
As you can see, the results are the same as not using the class at all. I added an __init__ method to print using Opposite and it only prints that if I instantiate the object with something like a = Opposite().
I would like to enter something like a > b, a < b, or a == b, and return the opposite boolean value, True, or False, as an exercise.
I tried several things such as placing the methods under the __init__ method I created, which didn't work either. I read on this and still don't quite understand how to do this with booleans, integers and floats for that matter. The way the methods are above is how I was able to turn datetime objects into strings with __add__, __radd__ and __rsub__ methods.
Thank you for your help.
EDIT
Thanks to your help, I have a better understanding and have completed my small experiment with this code:
class Opposite:
def __init__(self, x):
self._x = x
def __lt__(self, other):
return not self._x < other._x
def __eq__(self, other):
return not self._x == other._x
def __gt__(self, other):
return not self._x > other._x
def __le__(self, other):
return not self._x <= other._x
def __ge__(self, other):
return not self._x >= other._x
def tester(w, x, y, z):
try:
# Original values
a = w < x
b = w > x
c = w == x
d = w <= x
e = w >= x
# Opposite values
f = y < z
g = y > z
h = y == z
i = y <= z
j = y >= z
# Results
k = 'Fail' if a == f else 'Success'
l = 'Fail' if b == g else 'Success'
m = 'Fail' if c == h else 'Success'
n = 'Fail' if d == i else 'Success'
o = 'Fail' if e == j else 'Success'
print('\nComparing {} and {}:\t<\t>\t==\t<=\t>='.format(w, x))
print('Original Values:', end='\t')
print('{0}\t{1}\t{2}\t{3}\t{4}'.format(a, b, c, d, e))
print('Opposite Values:', end='\t')
print('{0}\t{1}\t{2}\t{3}\t{4}'.format(f, g, h, i, j))
print('Comparisons:', end='\t')
print('\t{0}\t{1}\t{2}\t{3}\t{4}'.format(k, l, m, n, o))
except(Exception) as err:
print(err)
if __name__=="__main__":
""" test class Compare """
a = 1
b = 2
c = Opposite(a)
d = Opposite(b)
tester(a, b, c, d)
This prints the following:
Comparing 1 and 2: < > == <= >=
Original Values: True False False True False
Opposite Values: False True True False True
Comparisons: Success Success Success Success Success
If you mean that you want to return the negation of the boolean resulting from the comparison you could do something like
class T:
def __init__(self, x):
self._x = x
def __lt__(self, other):
return not self._x < other._x
t1 = T(1)
t2 = T(2)
print(t1 < t2) #False
Note that in the comparison self._x < other._x you are using the __lt__ method of the int class.

Updating object values in class

I have a question about how to return the update value of an object in a class and then use that in another function in the same class. Here is my old code.
class Vector:
def __init__(self, a):
self.a = a
assert type(self.a) == list
for i in self.a:
assert type(i) == int or type(i) == float
def dim(self):
return len(self.a)
def __getitem__(self, i):
assert i >= 1 and i <= self.dim()
return self.a[i-1]
def __setitem__(self, i, x):
assert i >= 1 and i <= self.dim()
self.a[i-1] = x
return self.a[i-1]
def __str__(self):
return 'Vector: ' + str(self.a)
def __add__(self, other):
assert type(other.a) == list and other.dim() == self.dim()
n = []
for j in range(self.dim()):
n.append(self.a[j]+other.a[j])
self.a = n
return self.a
so when i'm running this test case:
v1 = Vector([2, 3, 4])
v2 = Vector([1, 2, 3])
str(v1 + v2)
my output is '[3, 5, 7]' which means it is only following return self.a and not the __str__ function however i want my output to be 'Vector: [3, 5, 7]' as it should be following the __str__ function. I fixed this by returning Vector(self.a) in the __add__ function but i dont know why this works. Can anyone explain why that works, and why return self.a does not simply update the object value and run the __str__ function instead?
Note: Python uses following equivalent notations:
v[i] == v.__getitem__(i)
v[i] = x == v.__setitem__(i, x)
str(v) == v.__str__()
v + other == v.__add__(other)

Dependent variable in Python

I would like to define an Integer class in python, where an Integer (called y) can be related to another Integer (called x) and get updated automatically when this Integer x changes. More concretely I would like to have the following behavior
>>> x = Integer(7)
>>> y = x + 2
>>> print y
9
>>> x.set(9)
>>> print y
11
>>> z = x + y
>>> y.set(10)
>>> print z
19
I realize that one can do this in sympy but I am interested in implementing this myself. I would be grateful if someone can please point out how one would go about this in the simplest manner? Thank you.
I've not used Sympy before but here's my attempt:
class Integer(object):
def __init__(self, value_or_callback):
if isinstance(value_or_callback, int):
self._value_callback = lambda: value_or_callback
else:
self._value_callback = value_or_callback
#property
def value(self):
return self._value_callback()
def set(self, new_value):
self._value_callback = lambda: new_value
def __add__(self, other):
if isinstance(other, int):
return Integer(lambda: self.value + other)
elif isinstance(other, Integer):
return Integer(lambda: self.value + other.value)
else:
raise TypeError(other)
def __radd__(self, other):
return self.__add__(other)
def __repr__(self):
return str(self.value)
if __name__ == '__main__':
x = Integer(7)
y = x + 2
print(y)
x.set(9)
print(y)
z = x + y
y.set(10)
print(z)
Output
9
11
19

Categories