Delete python_symb directory
This commit is contained in:
parent
cc343851bf
commit
a7461088cd
7 changed files with 0 additions and 306 deletions
|
@ -1,13 +0,0 @@
|
|||
from __future__ import annotations
|
||||
from typing import Union, List, Tuple, Optional, Dict, Callable
|
||||
from tree import Tree
|
||||
from operator import Add, Mul, Neg, Parenthesis
|
||||
|
||||
|
||||
class Expr(Tree):
|
||||
|
||||
def __init__(self, value, children=None):
|
||||
super().__init__(value, children)
|
||||
|
||||
|
||||
|
|
@ -1,132 +0,0 @@
|
|||
from __future__ import annotations
|
||||
from typing import Iterable, Generator
|
||||
from tools import gcd
|
||||
|
||||
|
||||
class Fractions:
|
||||
"""
|
||||
Should represent a fraction not a division
|
||||
"""
|
||||
__slots__ = ['num', 'den']
|
||||
__match_args__ = ("num", "den")
|
||||
|
||||
#todo check if num and den are part of a domain, so a/b as a meaning a gcd work well
|
||||
#todo implement __iadd__ etc... if performance needed
|
||||
|
||||
def __init__(self, *args):
|
||||
match args:
|
||||
case num, den:
|
||||
self.num = num
|
||||
self.den = den
|
||||
case x, :
|
||||
self.num = x
|
||||
self.den = 1
|
||||
|
||||
def __repr__(self):
|
||||
return f'Fractions({self.num}, {self.den})'
|
||||
|
||||
def simplify_gcd(self):
|
||||
"""Simplify fraction by diving num and den by their gcd
|
||||
return None"""
|
||||
match self.num, self.den:
|
||||
case int(num), int(den):
|
||||
gcd_ = gcd(num, den)
|
||||
self.num //= gcd_
|
||||
self.den //= gcd_
|
||||
# can be completed with others objects that support gcd like polynomials etc...
|
||||
|
||||
def simplify_to_num(self):
|
||||
"""from frac(a, 1) return a."""
|
||||
if self.den == 1:
|
||||
return self.num
|
||||
|
||||
def simplify_nested(self, rec=True):
|
||||
"""simplify nested fractions.
|
||||
Fractions(1, Fractions(1, Fractions(1, Fractions(1, 2)))) -> Fractions(2, 1)
|
||||
For one simplification step put rec=False
|
||||
|
||||
return None"""
|
||||
|
||||
def aux(fract):
|
||||
match fract:
|
||||
case Fractions(Fractions(a, b), Fractions(c, d)):
|
||||
fract.num = a * d
|
||||
fract.den = b * c
|
||||
case Fractions(num, Fractions(a, b)):
|
||||
fract.num = num * b
|
||||
fract.den = a
|
||||
case Fractions(Fractions(a, b), den):
|
||||
fract.num = a
|
||||
fract.den = b * den
|
||||
|
||||
if rec:
|
||||
num, den = self.num, self.den
|
||||
if isinstance(num, Fractions) or isinstance(den, Fractions):
|
||||
aux(fract)
|
||||
|
||||
aux(self)
|
||||
|
||||
def simplify_all_(self):
|
||||
self.simplify_gcd()
|
||||
self.simplify_nested()
|
||||
res = self.simplify_to_num()
|
||||
if res:
|
||||
return res
|
||||
|
||||
return self
|
||||
|
||||
def __add__(self, other):
|
||||
match other:
|
||||
case int(x):
|
||||
return Fractions(self.num + self.den*x, self.den)
|
||||
case Fractions(num, den):
|
||||
result = Fractions(self.num*den + num*self.den, self.den*den)
|
||||
return result
|
||||
return ValueError
|
||||
|
||||
def __radd__(self, other):
|
||||
return other + self
|
||||
|
||||
def __neg__(self):
|
||||
return Fractions(-self.num, self.den)
|
||||
|
||||
def __mul__(self, other):
|
||||
match other:
|
||||
case int(x):
|
||||
return Fractions(self.num*x, self.den)
|
||||
case Fractions(num, den):
|
||||
result = Fractions(self.num*num, self.den*den)
|
||||
return result
|
||||
return ValueError
|
||||
|
||||
def __rmul__(self, other):
|
||||
return self*other
|
||||
|
||||
def __truediv__(self, other):
|
||||
match other:
|
||||
case int(x):
|
||||
return Fractions(self.num, self.den*x)
|
||||
case Fractions(num, den):
|
||||
return Fractions(self.num*den, self.den*num)
|
||||
|
||||
def __rtruediv__(self, other):
|
||||
res = self/other
|
||||
return Fractions(res.den, res.num)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
a = Fractions(1, 2)
|
||||
a += 1
|
||||
print(a)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
"""
|
||||
Python int is already an arbitrary precision integer, so we don't need to implement it.
|
||||
"""
|
|
@ -1,56 +0,0 @@
|
|||
from __future__ import annotations
|
||||
from typing import Dict, Callable
|
||||
|
||||
|
||||
class Operator:
|
||||
__slots__ = 'name', 'precedence', 'call'
|
||||
|
||||
def __init__(self, name: str, precedence: int, call: Callable):
|
||||
self.name = name
|
||||
self.precedence = precedence
|
||||
self.call = call
|
||||
|
||||
|
||||
class UnaryOperator(Operator):
|
||||
__slots__ = 'name', 'precedence'
|
||||
|
||||
def __init__(self, name: str, precedence: int, call: Callable):
|
||||
super().__init__(name, precedence, call)
|
||||
|
||||
def __call__(self, expr):
|
||||
return self.call(expr)
|
||||
|
||||
|
||||
class BinProperties:
|
||||
__slots__ = 'associativity', 'commutativity', 'left_distributivity', 'right_distributivity'
|
||||
|
||||
def __init__(self, associativity: bool, commutativity: True,
|
||||
left_distributivity: Dict[str, bool], right_distributivity: Dict[str, bool]):
|
||||
|
||||
self.associativity = associativity
|
||||
self.commutativity = commutativity
|
||||
self.left_distributivity = left_distributivity
|
||||
self.right_distributivity = right_distributivity
|
||||
|
||||
|
||||
class BinOperator(Operator):
|
||||
__slots__ = 'name', 'precedence', 'properties'
|
||||
|
||||
def __init__(self, name: str, precedence: int, properties: BinProperties, call: Callable):
|
||||
super().__init__(name, precedence, call)
|
||||
self.properties = properties
|
||||
|
||||
def __call__(self, left, right):
|
||||
return self.call(left, right)
|
||||
|
||||
|
||||
AddProperties = BinProperties(True, True, {'*': True}, {'*': True})
|
||||
Add = BinOperator('+', 1, AddProperties, lambda x, y: x + y)
|
||||
|
||||
|
||||
MulProperties = BinProperties(True, True, {'+': True}, {'+': True})
|
||||
Mul = BinOperator('*', 2, MulProperties, lambda x, y: x * y)
|
||||
|
||||
Neg = UnaryOperator('-', -1, lambda x: -x)
|
||||
Parenthesis = UnaryOperator('()', 0, lambda x: x)
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
from __future__ import annotations
|
||||
|
||||
|
||||
class Symbols:
|
||||
__slots__ = 'name'
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name
|
|
@ -1,14 +0,0 @@
|
|||
from __future__ import annotations
|
||||
from typing import *
|
||||
|
||||
|
||||
def gcd(a, b):
|
||||
|
||||
if b > a:
|
||||
return gcd(b, a)
|
||||
|
||||
if b == 0:
|
||||
return a
|
||||
|
||||
return gcd(b, a % b)
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
from __future__ import annotations
|
||||
from typing import Iterable, Generator
|
||||
from collections import deque
|
||||
|
||||
|
||||
class Tree:
|
||||
"""
|
||||
Ultra generic Test class. Can be used to represent any Test structure.
|
||||
|
||||
value : value of the node. Can be a binary operator like "+", a ternary operator like "if", a number etc...
|
||||
|
||||
depth_first_order : the default order of the node in the depth first traversal. Used to implement the depth_first method.
|
||||
0 is pre-order, 1 is in-order (for binary Test), -1 is post-order.
|
||||
for instance to write "a ? b : c" you need to write Tree("?", [Tree("a"), Tree("b"), Tree("c")])
|
||||
and set the depth_first_order of the "?" node to 1.
|
||||
|
||||
children : the children of the node. Can be empty.
|
||||
"""
|
||||
__slots__ = ['value', 'children', 'depth_first_order']
|
||||
|
||||
def __init__(self, value, children: Iterable[Tree] = None, depth_first_order: int = 0):
|
||||
self.value = value
|
||||
self.depth_first_order = depth_first_order
|
||||
self.children = children if children else []
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f'Tree({self.value}, {self.children})'
|
||||
|
||||
def height(self) -> int:
|
||||
return 1 + max((child.height() for child in self.children), default=0)
|
||||
|
||||
def size(self) -> int:
|
||||
return 1 + sum(child.size() for child in self.children)
|
||||
|
||||
def breadth_first(self) -> Generator[Tree]:
|
||||
|
||||
queue = deque([self])
|
||||
|
||||
while queue:
|
||||
poped = queue.popleft()
|
||||
for child in poped.children:
|
||||
queue.append(child)
|
||||
|
||||
yield poped
|
||||
|
||||
def depth_first_default(self) -> Generator[Tree]:
|
||||
|
||||
def aux(tree):
|
||||
n = len(tree.children)
|
||||
if not tree.children:
|
||||
yield tree
|
||||
|
||||
for i, child in enumerate(tree.children):
|
||||
if i == tree.depth_first_order:
|
||||
yield tree
|
||||
|
||||
yield from aux(child)
|
||||
|
||||
if tree.depth_first_order == -1:
|
||||
yield tree
|
||||
|
||||
yield from aux(self)
|
||||
|
||||
def depth_first_pre_order(self) -> Generator[Tree]:
|
||||
|
||||
def aux(tree):
|
||||
yield tree
|
||||
for child in tree.children:
|
||||
yield from aux(child)
|
||||
|
||||
yield from aux(self)
|
||||
|
||||
def depth_first_post_order(self) -> Generator[Tree]:
|
||||
|
||||
def aux(tree):
|
||||
for child in tree.children:
|
||||
yield from aux(child)
|
||||
yield tree
|
||||
|
||||
yield from aux(self)
|
Loading…
Add table
Add a link
Reference in a new issue