# Principled Programming / Tim Teitelbaum / Chapter 18.
from intpair import Pair
from fractionAsSubclassOfIntPair import Fraction
from rationalAsSubclassOfFractionAsSubclassOfIntPair import Rational

# Demonstrate identity vs equality.
z1: Pair = Pair(2,3)
z2: Pair = Pair(2,3)
z3: Pair = z2
print(z1==z2, z1 is z2)
print(z2==z3, z2 is z3)
print()

# Demonstrate the effect of Fraction getting its own definition of __eq__.
z1: Pair = Pair(2,3)
z2: Fraction = Fraction(2,3)
print(z1, z2)
print(z1==z2)
print()

# Demonstrate dynamic dispatch, and overridden __str__.
o: object
o = Pair(4,6); print(o)
o = Fraction(4,6); print(o)
o = Rational(4,6); print(o)
o = Rational(6,3); print(o)
print()

# Demonstrate the effect of letting Rational rely on the def of __eq__ in Fraction.
z1: Fraction = Fraction(2,3)
z2: Fraction = Fraction(4,6)
z3: Fraction = Fraction(2,1)
z4: Rational = Rational(4,6)
z5: Rational = Rational(6,3)
print(z1, z2, z3, z4, z5)
print(z1==z4, z2==z4, z3==z5, z4==z5)
print()

# Demonstrate the canonical form of rationals.
print(Rational(2,3))
print(Rational(4,6))
print(Rational(-4,6))
print(Rational(4,-6))
print(Rational(-4,-6))
print(Rational(6,3))
print(Rational(0,1))
print(Rational(0,10))
print(Rational(0,-10))
print(Rational(2,3) == Rational(4,6))

print()