From ce5216b3e0f23a53a12df456ff34a148e1104ac0 Mon Sep 17 00:00:00 2001 From: MadBonzz Date: Mon, 25 Aug 2025 21:51:12 +0530 Subject: [PATCH 1/6] Made the EED eval into a simple package --- .gitignore | 17 +++++++++++++++++ EED/EED.py | 13 +++++-------- EED/__init__.py | 2 ++ EED/extended_zss.py | 1 + EED/latex_pre_process.py | 11 +++++------ EED/setup.py | 30 ++++++++++++++++++++++++++++++ EED/test.py | 11 +---------- requirements.txt | 4 ++++ 8 files changed, 65 insertions(+), 24 deletions(-) create mode 100644 .gitignore create mode 100644 EED/__init__.py create mode 100644 EED/setup.py create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b1a3c01 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +# Virtual Environment +.venv/ +venv/ +ENV/ +env/ + +# Python cache +__pycache__/ +*.pyc +*.pyo +*.pyd + +# Distribution / Installation +dist/ +build/ +*.egg-info/ +*.egg diff --git a/EED/EED.py b/EED/EED.py index 8a3ada3..6f4f020 100644 --- a/EED/EED.py +++ b/EED/EED.py @@ -4,7 +4,7 @@ import numpy as np import timeout_decorator from extended_zss import ext_distance -from latex_pre_process import * +from .latex_pre_process import * from sympy.simplify import * """ Guide: @@ -197,7 +197,6 @@ def __str__(self): - def print_tree(node, indent=0): """Print a tree structure""" print(' ' * indent + f'└─ {node.label}') @@ -264,9 +263,9 @@ def EED(answer_latex,test_latex,debug_mode=False): if not test_latex: return 0,-1,-1,-1 - if '\\int' in test_latex or '\\int' in answer_latex: + if '\int' in test_latex or '\int' in answer_latex: return 0,-1,-1,-1 - if '\\sum' in test_latex or '\\sum' in answer_latex: + if '\sum' in test_latex or '\sum' in answer_latex: return 0,-1,-1,1 if answer_latex==test_latex: return 100,0.0,-1,0 @@ -322,8 +321,7 @@ def EED(answer_latex,test_latex,debug_mode=False): print("Failed to build expression tree,returning zero") if debug_mode: raise SymPyError(f"Failed to build the sympy expression tree.\n GT:{answer_exp}\n GEN:{test_exp}") - return 0,-1,-1,-1 - + return 0,-1,calc_tree_size(tree_answer),-1 distance=ext_distance( tree_test, tree_answer, @@ -332,9 +330,8 @@ def EED(answer_latex,test_latex,debug_mode=False): insert_cost=insert_tree_func, single_remove_cost=remove_func, remove_cost=remove_tree_func, - update_cost=update_func) + update_cost=update_func) try: - distance=ext_distance( tree_test, diff --git a/EED/__init__.py b/EED/__init__.py new file mode 100644 index 0000000..0059084 --- /dev/null +++ b/EED/__init__.py @@ -0,0 +1,2 @@ +from .latex_pre_process import master_convert +from .EED import EED \ No newline at end of file diff --git a/EED/extended_zss.py b/EED/extended_zss.py index d75fb54..57854a9 100644 --- a/EED/extended_zss.py +++ b/EED/extended_zss.py @@ -158,3 +158,4 @@ def treedist(x, y): return treedists[-1][-1] + diff --git a/EED/latex_pre_process.py b/EED/latex_pre_process.py index 1a99fe6..35aa006 100644 --- a/EED/latex_pre_process.py +++ b/EED/latex_pre_process.py @@ -4,7 +4,6 @@ from sympy import simplify - def brackets_balanced(s: str) -> bool: """ Check if the brackets in a LaTeX string are balanced @@ -26,7 +25,6 @@ def brackets_balanced(s: str) -> bool: return len(stack) == 0 - def remove_non_ascii(text): return text.encode("ascii", errors="ignore").decode() @@ -172,7 +170,7 @@ def replacer(match): numerator, denominator = match.group(1), match.group(2) wrap_num = f'{{{numerator}}}' if not (numerator.startswith('{') and numerator.endswith('}')) else numerator wrap_den = f'{{{denominator}}}' if not (denominator.startswith('{') and denominator.endswith('}')) else denominator - return fr'\frac{wrap_num}{wrap_den}' + return fr'\frac{{{wrap_num}}}{{{wrap_den}}}' return re.sub(pattern, replacer, latex_str) @@ -280,7 +278,7 @@ def vec_lower_idx(input_str): Return: str(str): Converted """ - pattern = r'\\vec\{([^{}]+)_{([^{}]+)}\}' + pattern = r'\\vec{([^{}]+)_{([^{}]+)}\}' replacement = r'\\vec{\1}_{\2}' return re.sub(pattern, replacement, input_str) def convert_vec_syntax(text): @@ -321,7 +319,7 @@ def extract_last_equal_content(s: str, strip_whitespace: bool = True) -> str: """ Extract the content after the last occurrence of specific mathematical comparison or assignment operators. - :param strip_whitespace: If True, removes leading and trailing whitespace from the extracted content. Defaults to True. + :param strip_whitespace: If True, removes leading and trailing whitespace from the extracted content. (e.g., '=', '\\approx', '\\ge', '\\le', etc.) within the input string `s`. It then extracts and returns the content that follows the operator. If no operator is found, the entire string is returned. Optionally, leading and trailing whitespace can be stripped from the extracted content. @@ -477,7 +475,7 @@ class MyConfig: Args: interpret_as_mixed_fractions (bool): Whether to interpert 2 \frac{1}{2} as 2/2 or 2 + 1/2 interpret_simple_eq_as_assignment (bool): Whether to interpret simple equations as assignments k=1 -> 1 - interpret_contains_as_eq (bool): Whether to interpret contains as equality x \\in {1,2,3} -> x = {1,2,3} + interpret_contains_as_eq (bool): Whether to interpret contains as equality x \in {1,2,3} -> x = {1,2,3} lowercase_symbols (bool): Whether to lowercase all symbols """ class MyNormalization: @@ -521,3 +519,4 @@ def master_convert(s): Sym=latex2sympy(preprocessed_stage2,normalization_config=MyNormalization(),conversion_config=MyConfig()) return Sym + diff --git a/EED/setup.py b/EED/setup.py new file mode 100644 index 0000000..52fc6f1 --- /dev/null +++ b/EED/setup.py @@ -0,0 +1,30 @@ +from setuptools import setup, find_packages +import os + +with open(os.path.join(os.path.dirname(__file__), "..", "README.md"), "r", encoding="utf-8") as fh: + long_description = fh.read() + +setup( + name='eed', + version='0.1.0', + packages=find_packages(), + description='A Python package for calculating the Expression Edit Distance (EED) for LaTeX expressions.', + long_description=long_description, + long_description_content_type="text/markdown", + author='PhyBench', # Should be updated in README.md + author_email='phybench@example.com', # Should be updated in README.md + url='https://github.com/phybench/phybench-eed', # Add a URL to your project + license='MIT', + classifiers=[ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + ], + python_requires='>=3.6', + install_requires=[ + 'sympy', + 'numpy', + 'latex2sympy2-extended', + 'timeout-decorator', + ], +) \ No newline at end of file diff --git a/EED/test.py b/EED/test.py index 74b693c..688fb7c 100644 --- a/EED/test.py +++ b/EED/test.py @@ -1,13 +1,4 @@ -from latex_pre_process import master_convert -# This is a test for the master_convert function - -test_latex = r"\\boxed{t=x^2+y^2}" -converted_latex = master_convert(test_latex) -print(f"Converted LaTeX: {converted_latex}") - - - -from EED import EED +from eed import master_convert, EED # This is a test for the EED function answer_latex='2 m g + 4\\frac{mv_0^2}{l}' gen_latex_1 ="2 m g+4\\frac{mv_0^2}{l}" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..3e4eaec --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +sympy +numpy +latex2sympy2-extended +timeout-decorator From a6122eb38b7bdd83c7b794367c05caadfab9b89a Mon Sep 17 00:00:00 2001 From: MadBonzz Date: Mon, 25 Aug 2025 21:53:09 +0530 Subject: [PATCH 2/6] minor change --- EED/readme.md | 77 --------------------------------------------------- 1 file changed, 77 deletions(-) delete mode 100644 EED/readme.md diff --git a/EED/readme.md b/EED/readme.md deleted file mode 100644 index b7d05a7..0000000 --- a/EED/readme.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -tags: [EED] -title: EED Scoring -created: '2025-04-25T13:38:52.246Z' -modified: '2025-04-25T14:18:31.370Z' ---- - -# EED Scoring - -The core function of our EED scoring. - -> We use latex2sympy2_extended package to convert latex expression to sympy symbolic forms (many pre-process procedures are applied) and use an extended Zhang-Shasha algorithm to calculate the minimum editing distance between expression trees. - -**WARNING**: timeout_decorator inside EED.py is **NOT** supported in **Windows**. -**Workaround**: For Windows users, you can manually handle timeouts by using `threading` or `multiprocessing` modules to implement timeout functionality. - -## Features -- More detailed pre-process procedure, ensuring most input LaTeX can be safely converted to SymPy -- Extended tree editing algorithm added -- A simple scoring function **EED(ans, test)** for LaTeX input -- Supports customized weights and scoring functions -## Quick Start - -### Environment -```bash -pip install sympy numpy latex2sympy2_extended timeout_decorator -``` - -### Basic Usage -```python -from EED import EED - -answer_latex="2 m g + 4\\frac{mv_0^2}{l}" -gen_latex="2 m g+2\\frac{mv_0^2}{l}" -# The [0] index retrieves the score from the output of the EED function -result = EED(answer_latex,gen_latex)[0] -print(result) -``` -## Example -```python -from EED import EED - -answer_latex="2 m g + 4\\frac{mv_0^2}{l}" -gen_latex_1 ="2 m g+4\\frac{mv_0^2}{l}" -gen_latex_2 ="2 m g+2\\frac{mv_0^2}{l}" -result_1 = EED(answer_latex,gen_latex_1)[0] -result_2 = EED(answer_latex,gen_latex_2)[0] -print(f"The EED Score of Expression 1 is: {result_1:.0f}") -print(f"The EED Score of Expression 2 is: {result_2:.0f}") -``` -#### Output -```bash -The EED Score of Expression 1 is:100 -The EED Score of Expression 2 is:47 -``` -**NOTICE**: Inputs with an incorrect format will automatically receive a **0** point as output without raising any errors. - -If you want to debug, please set: -```python -EED(answer_latex,gen_latex,debug_mode=True) -``` - -## File structure - -- EED.py: The main scoring function with default parameter settings. You can edit this file to customize your scoring strategy. - -- extended_zss.py: The extended tree editing algorithm based on Zhang-Shasha algorithm - -- latex_pre_process.py : Many very detailed pre-process functions that convert a LaTeX input into a more canonical and standardized form for later latex2sympy. - -## Contributing - -There is still much work to do! -Pull requests are welcome. Open an issue first to discuss changes. - - - From ef3fca99f2a20651c478b419b77dfd3516596495 Mon Sep 17 00:00:00 2001 From: MadBonzz Date: Mon, 25 Aug 2025 21:53:47 +0530 Subject: [PATCH 3/6] updated name --- EED/setup.py | 2 +- EED/test.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/EED/setup.py b/EED/setup.py index 52fc6f1..b61e770 100644 --- a/EED/setup.py +++ b/EED/setup.py @@ -5,7 +5,7 @@ long_description = fh.read() setup( - name='eed', + name='EED', version='0.1.0', packages=find_packages(), description='A Python package for calculating the Expression Edit Distance (EED) for LaTeX expressions.', diff --git a/EED/test.py b/EED/test.py index 688fb7c..e5aaae7 100644 --- a/EED/test.py +++ b/EED/test.py @@ -1,4 +1,4 @@ -from eed import master_convert, EED +from EED import master_convert, EED # This is a test for the EED function answer_latex='2 m g + 4\\frac{mv_0^2}{l}' gen_latex_1 ="2 m g+4\\frac{mv_0^2}{l}" From a6862659ffc822ecbf96940e010b43f2bd9ec9c8 Mon Sep 17 00:00:00 2001 From: MadBonzz Date: Mon, 25 Aug 2025 21:57:33 +0530 Subject: [PATCH 4/6] minor change in structure --- EED/setup.py => setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename EED/setup.py => setup.py (90%) diff --git a/EED/setup.py b/setup.py similarity index 90% rename from EED/setup.py rename to setup.py index b61e770..cef824f 100644 --- a/EED/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages import os -with open(os.path.join(os.path.dirname(__file__), "..", "README.md"), "r", encoding="utf-8") as fh: +with open("README.md", "r", encoding="utf-8") as fh: long_description = fh.read() setup( From 66f89980136c513d5ce163b0a67f2d1c1b2664e9 Mon Sep 17 00:00:00 2001 From: MadBonzz Date: Mon, 25 Aug 2025 22:31:08 +0530 Subject: [PATCH 5/6] minor update --- EED/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/EED/__init__.py b/EED/__init__.py index 0059084..ef85868 100644 --- a/EED/__init__.py +++ b/EED/__init__.py @@ -1,2 +1,3 @@ -from .latex_pre_process import master_convert -from .EED import EED \ No newline at end of file +from .latex_pre_process import * +from .EED import * +from .extended_zss import * \ No newline at end of file From f12a533dfaee4bdf8992164b0a759ea4e10701c4 Mon Sep 17 00:00:00 2001 From: MadBonzz Date: Mon, 25 Aug 2025 22:33:39 +0530 Subject: [PATCH 6/6] bug fix --- EED/EED.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EED/EED.py b/EED/EED.py index 6f4f020..e222181 100644 --- a/EED/EED.py +++ b/EED/EED.py @@ -3,7 +3,7 @@ from sympy.core.numbers import Pi, Exp1,I,Infinity,NegativeInfinity import numpy as np import timeout_decorator -from extended_zss import ext_distance +from .extended_zss import ext_distance from .latex_pre_process import * from sympy.simplify import * """