Mapytex/mapytex/calculus/core/MO/fraction.py

135 lines
3.3 KiB
Python
Raw Permalink Normal View History

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
#
# Copyright © 2017 lafrite <lafrite@Poivre>
#
# Distributed under terms of the MIT license.
from mapytex.calculus.core.tree import Tree
from .mo import Molecule, MO
from .atoms import MOnumber
2021-09-26 06:29:07 +00:00
from decimal import Decimal
from ..arithmetic import gcd
__all__ = ["MOFraction"]
2019-05-14 04:55:56 +00:00
class MOFraction(Molecule):
""" Fraction math object"""
MAINOP = "/"
def __init__(self, numerator, denominator, negative=False):
""" Initiate the MOFraction
It can't be indempotent.
:param numerator: Numerator of the Fraction
:param denominator: Denominator of the Fraction
:param negative: Is the fraction negative (not concidering sign of
numerator or denominator.
>>> f = MOFraction(2, 3)
>>> f
<MOFraction 2 / 3>
>>> print(f.tree)
/
> 2
> 3
>>> print(f)
2 / 3
>>> f = MOFraction(2, 3, negative = True)
>>> f
<MOFraction - 2 / 3>
"""
_numerator = MO.factory(numerator)
_denominator = MO.factory(denominator)
2019-05-14 04:55:56 +00:00
base_tree = Tree("/", _numerator, _denominator)
if negative:
tree = Tree("-", None, base_tree)
else:
tree = base_tree
Molecule.__init__(self, tree)
self._numerator = _numerator
self._denominator = _denominator
self.negative = negative
2018-03-12 04:34:26 +00:00
@property
def numerator(self):
""" Get the numerator. If self is negative, getting the opposite of the _numerator
"""
if self.negative:
return Tree("-", None, self._numerator)
return self._numerator
@property
def denominator(self):
return self._denominator
2021-09-26 06:29:07 +00:00
@property
def _value(self):
return Decimal(self._numerator._value) / Decimal(self._denominator._value)
2018-03-12 04:34:26 +00:00
def inverse(self):
""" return the inverse fraction """
2019-05-14 04:55:56 +00:00
return MOFraction(self._denominator, self._numerator, self.negative)
def differentiate(self):
""" differentiate a fraction and get something!
:example:
>>> a = MOFraction(2, 3)
>>> a.differentiate()
<MOnumber 0>
"""
d_num = self.numerator.differentiate()
d_denom = self.denominator.differentiate()
if d_num == 0 and d_denom == 0:
return MOnumber(0)
else:
raise NotImplementedError
def simplified(self):
""" Simplified version of self
:examplex
>>> f = MOFraction(2, 3)
>>> f
<MOFraction 2 / 3>
>>> f.simplified()
<MOFraction 2 / 3>
>>> f = MOFraction(2, 6)
>>> f
<MOFraction 2 / 6>
>>> f.simplified()
<MOFraction 1 / 3>
>>> f = MOFraction(32, 24)
>>> f.simplified()
<MOFraction 4 / 3>
>>> f = MOFraction(32, 8)
>>> f.simplified()
<MOnumber 4>
"""
frac_gcd = gcd(self.numerator._value, self.denominator._value)
new_num = self.numerator._value / frac_gcd
new_denom = self.denominator._value / frac_gcd
if new_denom == 1:
return MOnumber(new_num)
return MOFraction(new_num, new_denom)
# -----------------------------
# Reglages pour 'vim'
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
# cursor: 16 del