diff --git a/app/context/physical_quantity.py b/app/context/physical_quantity.py
index 6639e18..ecd4f51 100644
--- a/app/context/physical_quantity.py
+++ b/app/context/physical_quantity.py
@@ -476,73 +476,106 @@ def feedback_procedure_generator(parameters_dict):
graphs.update({label: graph})
return graphs
-
-def expression_preprocess(name, expr, parameters):
- if parameters.get("strictness", "natural") == "legacy":
- prefix_data = {(p[0], p[1], tuple(), p[3]) for p in set_of_SI_prefixes}
- prefixes = []
- for prefix in prefix_data:
- prefixes = prefixes+[prefix[0]] + list(prefix[-1])
- prefix_short_forms = [prefix[1] for prefix in prefix_data]
- unit_data = set_of_SI_base_unit_dimensions \
- | set_of_derived_SI_units_in_SI_base_units \
- | set_of_common_units_in_SI \
- | set_of_very_common_units_in_SI \
- | set_of_imperial_units
- unit_long_forms = prefixes
- for unit in unit_data:
- unit_long_forms = unit_long_forms+[unit[0]] + list(unit[-2]) + list(unit[-1])
- unit_long_forms = "("+"|".join(unit_long_forms)+")"
- # Rewrite any expression on the form "*UNIT" (but not "**UNIT") as " UNIT"
- # Example: "newton*metre" ---> "newton metre"
- search_string = r"(? "newton metre"
+ search_string = r"(? "kilometre"
- search_string = prefixes+" "+unit_long_forms
+ prefixes = "(" + "|".join(prefixes) + ")"
+ # Rewrite any expression on the form "PREFIX UNIT" as "PREFIXUNIT"
+ # Example: "kilo metre" ---> "kilometre"
+ search_string = prefixes + " " + unit_long_forms
+ match_content = re.search(search_string, expr)
+ while match_content is not None:
+ expr = expr[0:match_content.span()[0]] + " " + "".join(match_content.group().split()) + expr[
+ match_content.span()[
+ 1]:]
match_content = re.search(search_string, expr)
- while match_content is not None:
- expr = expr[0:match_content.span()[0]]+" "+"".join(match_content.group().split())+expr[match_content.span()[1]:]
- match_content = re.search(search_string, expr)
- unit_short_forms = [u[1] for u in unit_data]
- short_forms = "("+"|".join(list(set(prefix_short_forms+unit_short_forms)))+")"
- # Add space before short forms of prefixes or unit names if they are preceded by numbers or multiplication
- # Example: "100Pa" ---> "100 Pa"
- search_string = r"[0-9\*\(\)]"+short_forms
+ unit_short_forms = [u[1] for u in unit_data]
+ short_forms = "(" + "|".join(list(set(prefix_short_forms + unit_short_forms))) + ")"
+ # Add space before short forms of prefixes or unit names if they are preceded by numbers or multiplication
+ # Example: "100Pa" ---> "100 Pa"
+ search_string = r"[0-9\*\(\)]" + short_forms
+ match_content = re.search(search_string, expr)
+ while match_content is not None:
+ expr = expr[0:match_content.span()[0] + 1] + " " + expr[match_content.span()[0] + 1:]
match_content = re.search(search_string, expr)
- while match_content is not None:
- expr = expr[0:match_content.span()[0]+1]+" "+expr[match_content.span()[0]+1:]
- match_content = re.search(search_string, expr)
- # Remove space after prefix short forms if they are preceded by numbers, multiplication or space
- # Example: "100 m Pa" ---> "100 mPa"
- prefix_short_forms = "("+"|".join(prefix_short_forms)+")"
- search_string = r"[0-9\*\(\) ]"+prefix_short_forms+" "
+ # Remove space after prefix short forms if they are preceded by numbers, multiplication or space
+ # Example: "100 m Pa" ---> "100 mPa"
+ prefix_short_forms = "(" + "|".join(prefix_short_forms) + ")"
+ search_string = r"[0-9\*\(\) ]" + prefix_short_forms + " "
+ match_content = re.search(search_string, expr)
+ while match_content is not None:
+ expr = expr[0:match_content.span()[0] + 1] + match_content.group()[0:-1] + expr[match_content.span()[1]:]
match_content = re.search(search_string, expr)
- while match_content is not None:
- expr = expr[0:match_content.span()[0]+1]+match_content.group()[0:-1]+expr[match_content.span()[1]:]
- match_content = re.search(search_string, expr)
- # Remove multiplication and space after prefix short forms if they are preceded by numbers, multiplication or space
- # Example: "100 m* Pa" ---> "100 mPa"
- search_string = r"[0-9\*\(\) ]"+prefix_short_forms+"\* "
+ # Remove multiplication and space after prefix short forms if they are preceded by numbers, multiplication or space
+ # Example: "100 m* Pa" ---> "100 mPa"
+ search_string = r"[0-9\*\(\) ]" + prefix_short_forms + "\* "
+ match_content = re.search(search_string, expr)
+ while match_content is not None:
+ expr = expr[0:match_content.span()[0] + 1] + match_content.group()[0:-2] + expr[match_content.span()[1]:]
match_content = re.search(search_string, expr)
- while match_content is not None:
- expr = expr[0:match_content.span()[0]+1]+match_content.group()[0:-2]+expr[match_content.span()[1]:]
- match_content = re.search(search_string, expr)
- # Replace multiplication followed by space before unit short forms with only spaces if they are preceded by numbers or space
- # Example: "100* Pa" ---> "100 Pa"
- unit_short_forms = "("+"|".join(unit_short_forms)+")"
- search_string = r"[0-9\(\) ]\* "+unit_short_forms
+ # Replace multiplication followed by space before unit short forms with only spaces if they are preceded by numbers or space
+ # Example: "100* Pa" ---> "100 Pa"
+ unit_short_forms = "(" + "|".join(unit_short_forms) + ")"
+ search_string = r"[0-9\(\) ]\* " + unit_short_forms
+ match_content = re.search(search_string, expr)
+ while match_content is not None:
+ expr = expr[0:match_content.span()[0]] + match_content.group().replace("*", " ") + expr[
+ match_content.span()[1]:]
match_content = re.search(search_string, expr)
- while match_content is not None:
- expr = expr[0:match_content.span()[0]]+match_content.group().replace("*", " ")+expr[match_content.span()[1]:]
- match_content = re.search(search_string, expr)
- success = True
- return success, expr, None
+ return expr
+
+def transform_prefixes_to_standard(expr):
+ """
+ Transform ONLY alternative prefix spellings to standard prefix names.
+ Ensure there's exactly one space after the prefix before the unit.
+ Works for both attached (e.g. 'km') and spaced (e.g. 'k m') forms.
+ """
+
+ for prefix_name, symbol, power, alternatives in set_of_SI_prefixes:
+ for alt in alternatives:
+ if not alt:
+ continue
+
+ # Match the alternative prefix either attached to or followed by spaces before a unit
+ # Examples matched: "km", "k m", "microsecond", "micro second"
+ pattern = rf'(?---
Checks if answer <= response is true."])
- N_1_0["answer <= response_TRUE
---
answer <= response is true."]
- N_1_1["answer <= response_FALSE
---
answer <= response is false."]
- N_1_2["answer <= response_UNKNOWN
---
answer <= response is false."]
- N_2_0{{"END
---
Evaluation completed."}}
- N_0_0 --> N_1_2
- N_1_0 --> N_2_0
- N_1_1 --> N_2_0
- N_0_0 --> N_1_0
- N_0_0 --> N_1_1
- N_1_2 --> N_2_0
flowchart TD
N_0_0(["2+answer > response
---
Checks if 2+answer > response is true."])
N_1_0["2+answer > response_TRUE
---
2+answer > response is true."]
N_1_1["2+answer > response_FALSE
---
2+answer > response is false."]
N_1_2["2+answer > response_UNKNOWN
---
2+answer > response is false."]
N_2_0{{"END
---
Evaluation completed."}}
+ N_1_2 --> N_2_0
+ N_1_1 --> N_2_0
+ N_0_0 --> N_1_1
N_0_0 --> N_1_2
+ N_0_0 --> N_1_0
N_1_0 --> N_2_0
+flowchart TD
+ N_0_0(["answer <= response
---
Checks if answer <= response is true."])
+ N_1_0["answer <= response_TRUE
---
answer <= response is true."]
+ N_1_1["answer <= response_FALSE
---
answer <= response is false."]
+ N_1_2["answer <= response_UNKNOWN
---
answer <= response is false."]
+ N_2_0{{"END
---
Evaluation completed."}}
+ N_1_2 --> N_2_0
N_1_1 --> N_2_0
- N_0_0 --> N_1_0
N_0_0 --> N_1_1
- N_1_2 --> N_2_0
+ N_0_0 --> N_1_2
+ N_0_0 --> N_1_0
+ N_1_0 --> N_2_0
```