Documentation de Pyromaths 21.8.2

pyromaths.classes.SquareRoot

Contenu

Code source de pyromaths.classes.SquareRoot

#!/usr/bin/env python3

# Pyromaths
# Un programme en Python qui permet de créer des fiches d'exercices types de
# mathématiques niveau collège ainsi que leur corrigé en LaTeX.
# Copyright (C) 2006 -- Jérôme Ortais (jerome.ortais@pyromaths.org)
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#

'''
Created on 19 déc. 2014

@author: jerome
'''
from pyromaths.outils.Arithmetique import carrerise
from pyromaths.outils.decimaux import decimaux
from pyromaths.outils import Priorites3
from pyromaths import classes

from math import sqrt
[docs]class SquareRoot: ''' Définit la classe SquareRoot permettant de manipuler des racines carrées. SquareRoot([a,b], [c, d], e) ou SquareRoot([a,b], [c, d], [e, None]) permet de définir a*sqrt(b)+c*sqrt(d)+e Cette définition permet d'utiliser pyromaths.outils.Priorites3 >>> from pyromaths.classes.SquareRoot import SquareRoot >>> repr(SquareRoot(-4,[-2,1],[3,45],[-1,7],8)) SquareRoot([[-4, None], [-2, 1], [3, 45], [-1, 7], [8, None]]) '''
[docs] def __init__(self, *radicandes): ''' Constructor ''' # print radicandes, len(radicandes), radicandes[0], len(radicandes[0]) if len(radicandes) == 1 and len(radicandes[0]) == 2 and not isinstance(radicandes[0][0], list) and not isinstance(radicandes[0][1], list): # SquareRoot([3, 4]), self.racines = [radicandes[0]] else: if len(radicandes) == 1 and (len(radicandes[0]) != 2 or isinstance(radicandes[0][0], list) or isinstance(radicandes[0][1], list)): # SquareRoot([1, [3, 4]]) radicandes = radicandes[0] self.racines = [] for arg in radicandes: if isinstance(arg, list) and len(arg) == 2: # On gère a*sqrt(b) if isinstance(arg[1], (float, int))and arg[1] < 0: raise ValueError(u'Le radicande doit être un nombre positif.') else: self.racines.append(arg) elif isinstance(arg, (float, int)): self.racines.append([arg, None]) else: raise ValueError(u'Not Implemented : SquareRoot(%s)' % arg)
[docs] def __str__(self): r"""Renvoie une version LaTeX d'un objet SquareRoot. >>> from pyromaths.classes.SquareRoot import SquareRoot >>> str(SquareRoot([[-4, None], [-2, 1], [3, 45], [-1, 7], [8, None]])) -4-2\,\sqrt{1}+3\,\sqrt{45}-\sqrt{7}+8 :rtype: String """ def print_coef(coef): """Gère le format du coef """ if isinstance(coef, (float, int)): if coef > 0: return "+" + decimaux(coef) else: return decimaux(coef) if isinstance(coef, classes.Fractions.Fraction): if isinstance(coef.n, int) and isinstance(coef.d, int) and coef.n < 0 and coef.d > 0: return "-" + str(Fraction(-coef.n, coef.d, coef.code)) return "+" + str(coef) if isinstance(coef, str): texte = "(" + "".join(Priorites3.texify([Priorites3.splitting(coef)])) + ")" if texte[0] != "-": return "+" + texte else: return texte s = "" for m in self.racines: if m[1] == None: # pas de racine ici s = s + print_coef(m[0]) else: # Racine carrée if m[0] == 1: s += r'+\sqrt{%s}' % m[1] elif m[0] == -1: s += r'-\sqrt{%s}' % m[1] else: s += print_coef(m[0]) + r'\,\sqrt{%s}' % m[1] # supprime le + en début de séquence s = s.lstrip("+") if not s: s = "0" return s
[docs] def __repr__(self): """Renvoie une chaîne de caractère représentant un :mod:`SquareRoot` évaluable pour créer un :mod:`SquareRoot`. >>> from pyromaths.classes.SquareRoot import SquareRoot >>> repr(SquareRoot(-4, [-2, 1], [3, 45], [-1, 7], 8)) SquareRoot([[-4, None], [-2, 1], [3, 45], [-1, 7], [8, None]]) :rtype: String """ return "SquareRoot(%s)" % self.racines
[docs] def __len__(self): """*object*\ .\ **__len__**\ () Renvoie le nombre d'éléments de l'objet SquareRoot. >>> from pyromaths.classes.SquareRoot import SquareRoot >>> len(SquareRoot(3, [2, 2], [4, 5])) 3 :rtype: integer """ return len(self.racines)
[docs] def __getitem__(self, i): """*object*\ .\ **__getitem__**\ (*integer*) Renvoie le i ème élément de l'objet SquareRoot. >>> from pyromaths.classes.SquareRoot import SquareRoot >>> SquareRoot(3, [2, 2], [4, 5])[2] [4, 5] :rtype: list """ return self.racines[i]
[docs] def __add__(self, other): """Renvoie la somme d'un objet SquareRoot et d'un nombre. >>> from pyromaths.classes.SquareRoot import SquareRoot >>> repr(SquareRoot([3,45],3)+SquareRoot([2,45])) SquareRoot([[3, None], [5, 45]]) :rtype: SquareRoot """ if not isinstance(other, SquareRoot): other = SquareRoot([other, None]) self.racines.extend(other.racines) return SquareRoot(self.racines).simplifie()
[docs] def __radd__(self, other): """ >>> from pyromaths.classes.SquareRoot import SquareRoot >>> repr(2+SquareRoot([3,45],3)) SquareRoot([[5, None], [3, 45]]) :rtype: SquareRoot """ other = SquareRoot([other, None]) other.racines.extend(self.racines) return SquareRoot(other.racines).simplifie()
[docs] def __neg__(self): """*object*\ .\ **__neg__**\ () ``p.__neg__()`` est équivalent à ``-p`` est équivalent à ``p = -p`` Renvoie l'opposé d'un objet SquareRoot. :rtype: SquareRoot """ if self.EstDecomposable() or self.EstReductible(): return '-%r' % self.simplifie() r = list(self.racines) for i in range(len(r)): r[i][0] = -r[i][0] return SquareRoot(r)
[docs] def __abs__(self): """ Renvoie la valeur absolue d'un objet SquareRoot >>> from pyromaths.classes.SquareRoot import SquareRoot >>> repr(abs(SquareRoot([5, 5], [-2, 7]))) SquareRoot([[5, 5], [-2, 7]]) >>> repr(abs(SquareRoot([-5, 5], [2, 7]))) SquareRoot([[5, 5], [-2, 7]]) :rtype: SquareRoot """ t = 0 for e in self.racines: if e[1] == None: t += e[0] else: t += e[0] * sqrt(e[1]) if t > 0: return self else: return -self
def evaluate(self, other): t, t2 = 0, 0 for e in self.racines: if e[1] == None: t += e[0] else: t += e[0] * sqrt(e[1]) if isinstance(other, SquareRoot): for e in other.racines: if e[1] == None: t2 += e[0] else: t2 += e[0] * sqrt(e[1]) else: t2=other return t, t2
[docs] def __lt__(self, other): t, t2 = self.evaluate(other) if t<t2: return True else: return False
[docs] def __le__(self, other): t, t2 = self.evaluate(other) if t<=t2: return True else: return False
[docs] def __eq__(self, other): t, t2 = self.evaluate(other) if t==t2: return True else: return False
[docs] def __ne__(self, other): t, t2 = self.evaluate(other) if t!=t2: return True else: return False
[docs] def __gt__(self, other): t, t2 = self.evaluate(other) if t>t2: return True else: return False
[docs] def __ge__(self, other): t, t2 = self.evaluate(other) if t>=t2: return True else: return False
[docs] def __mul__(self, other): """Multiplie un objet SquareRoot par un nombre. >>> from pyromaths.classes.SquareRoot import SquareRoot >>> repr(SquareRoot([3,45],3)*SquareRoot([2,45],-1)) SquareRoot([['6*45', None], [-3, 45], [6, 45], [-3, None]]) """ if not isinstance(other, SquareRoot): other = SquareRoot([other, None]) reduction = False if self.EstReductible(): self = self.simplifie() reduction = True if other.EstReductible(): other = other.simplifie() reduction = True if reduction: return '%r*%r' % (self, other) lprod = [] for e in self.racines: for f in other.racines: if e[1] == None or f[1] == None: lprod.append([e[0] * f[0], e[1] or f[1]]) elif e[1] == f[1]: lprod.append(['%r*%r' % (e[0] * f[0], e[1]), None]) elif carrerise(e[1]) == 1 or carrerise(f[1]) == 1: if carrerise(e[1]) == 1: e[0], e[1] = e[0] * int(sqrt(e[1])), 1 if carrerise(f[1]) == 1: f[0], f[1] = f[0] * int(sqrt(f[1])), 1 lprod.append([e[0] * f[0], e[1] * f[1]]) else: lprod.append([e[0] * f[0], e[1] * f[1]]) return SquareRoot(lprod)
[docs] def __rmul__(self, other): """ >>> from pyromaths.classes.SquareRoot import SquareRoot >>> repr(5*SquareRoot([3,45],3)) SquareRoot([[15, 45], [15, None]]) :rtype: SquareRoot """ return SquareRoot([other, None]) * self
[docs] def __floordiv__(self, other): """ Division entière par un entier >>> from pyromaths.classes.SquareRoot import SquareRoot >>> repr(SquareRoot([10, 8], [15, 5])//5) SquareRoot([[2, 8], [3, 5]]) :rtype: SquareRoot """ if isinstance(other, int): r = list(self.racines) for i in range(len(r)): r[i][0] = r[i][0] // other return SquareRoot(r) else: raise NotImplemented
[docs] def EstDecomposable(self): """ Renvoie True si une des racines est de la forme sqrt{a**2*b} avec a != 1 >>> from pyromaths.classes.SquareRoot import SquareRoot >>> SquareRoot([5, 8], [1, 7]).EstDecomposable() True >>> SquareRoot([5, 7], [1, 7]).EstDecomposable() False :rtype: Boolean """ for e in self.racines: if e[1] != None and (carrerise(e[1]) != e[1] or e[1] == 1): return True return False
[docs] def EstReductible(self): """ Renvoie True si la somme de racines est réductible >>> from pyromaths.classes.SquareRoot import SquareRoot >>> SquareRoot([5, 8], [1, 45]).EstReductible() False >>> SquareRoot([5, 8], [1, 8]).EstReductible() True :rtype: Boolean """ lradicandes = [] rationnel = False for e in self.racines: if e[1] != None: if e[1] in lradicandes: return True else: lradicandes.append(e[1]) elif e[1] == None: if rationnel: return True else: rationnel = True return False
[docs] def Decompose(self): """ Décompose une unique racine carrée de la forme a*sqrt(b^2*c) en a*sqrt(b^2)*sqrt(c) >>> from pyromaths.classes.SquareRoot import SquareRoot >>> SquareRoot([5, 8]).Decompose() SquareRoot([[5, 4]])*SquareRoot([[1, 2]]) :rtype: string """ racine = self.racines[0] if racine[1] == None: return repr(racine[0]) if isinstance(racine[1], int): complement = carrerise(racine[1]) if complement == 1: if racine[0] == 1: return int(sqrt(racine[1])) if racine[0] == -1: return -int(sqrt(racine[1])) if racine[1] == 1: return str(racine[0]) return '%r*%r' % (racine[0], int(sqrt(racine[1]))) if complement == racine[1]: return repr(self) return '%r*%r' % (SquareRoot([racine[0], racine[1] // complement]), SquareRoot([1, complement])) raise ValueError(u'Not Implemented : SquareRoot(%s)' % racine)
[docs] def simplifie(self): """ Additionne les nombres rationnels et décompose les racines carrées. >>> from pyromaths.classes.SquareRoot import SquareRoot >>> repr(SquareRoot([[3, 9]]).simplifie()) '3*3' >>> repr(SquareRoot(-2, [-2, 1], [3, 1], [-1, 7], 8).simplifie()) SquareRoot([[6, None], [1, 1], [-1, 7]]) >>> repr(SquareRoot(-2, [-2, 1], [3, 45], [-1, 7], 8).simplifie()) SquareRoot([[6, None], [-2, 1], [3, 45], [-1, 7]]) >>> repr(SquareRoot([-2,1],[3,45]).simplifie()) '-2+SquareRoot([[3, 9]])*SquareRoot([[1, 5]])' :rtype: SquareRoot ou String """ decomposable = self.EstDecomposable() reductible = self.EstReductible() if not decomposable and not reductible: return self if reductible: racines = [] # racines = [[sum([x[0] for i, x in enumerate(self.racines) if x[1] == None]), None]] # TODO: cas de fractions lsomme = [x[0] for i, x in enumerate(self.racines) if x[1] == None] s = '' for ls in lsomme: if isinstance(ls, str): s += '+%s' % ls else: s += '+%r' % ls s.lstrip('+') racines.append([eval(s), None]) for pos in reversed([i for i, x in enumerate(self.racines) if x[1] == None]): self.racines.__delitem__(pos) if racines[0][0] == 0: racines = [] while len(self.racines) > 0: # racines.append([sum([x[0] for i, x in enumerate(self.racines) if x[1] == self.racines[0][1]]), self.racines[0][1]]) # TODO: cas de fractions lsomme = [x[0] for i, x in enumerate(self.racines) if x[1] == self.racines[0][1]] s = '' for ls in lsomme: if isinstance(ls, str): s += '+%s' % ls else: s += '+%r' % ls s.lstrip('+') racines.append([eval(s), self.racines[0][1]]) if racines[-1][0] == 0: racines.pop(-1) for pos in reversed([i for i, x in enumerate(self.racines) if x[1] == self.racines[0][1]]): self.racines.__delitem__(pos) if racines: if len(racines) == 1 and racines[0][1] == None: return racines[0][0] else: return SquareRoot(racines) else: return 0 # Décomposable s = '' if len(self.racines) == 1 and isinstance(SquareRoot(self.racines).Decompose(), int): return SquareRoot(self.racines).Decompose() for e in self.racines: decomposee = SquareRoot(e).Decompose() if isinstance(decomposee, int): decomposee = str(decomposee) if decomposee[0]in'+-': s += decomposee else: s += '+' + decomposee s = s.lstrip('+') return s
def __float__(self): value=0 for item in self.racines: if item[1]!=None: if type(item[0])==str: value = value + float(eval(item[0])) * sqrt(item[1]) else: value = value + item[0]*sqrt(item[1]) else: value = value + item[0] return value

Contenu