Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add feature to print result parts to console #56

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/api/console_stringifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def result_to_str(self, result: Result):
Returns the result as human-readable string.
"""

return f"{result.name} = {self.create_str(result.value, result.uncertainties, result.unit)}"
return f"{result.name} = {self.create_str(result)}"

def _modify_unit(self, unit: str) -> str:
"""
Expand Down
41 changes: 41 additions & 0 deletions src/api/printable_result.py
paul019 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import api.config as c
from api.latexer import get_latexer
from domain.result import Result
from application import error_messages


class PrintableResult:
Expand All @@ -13,6 +14,46 @@ def print(self):
stringifier = ConsoleStringifier(c.configuration.to_stringifier_config())
print(stringifier.result_to_str(self._result))

def get_str(self) -> str:
stringifier = ConsoleStringifier(c.configuration.to_stringifier_config())
return stringifier.create_str(self._result)

def get_str_value(self) -> str:
stringifier = ConsoleStringifier(c.configuration.to_stringifier_config())
return stringifier.create_str_value(self._result)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be beneficial to also have access to the value and the uncertainties as numeric values, not only as strings? For example,

res = wiz.res(3.14, ...)
# Some further calculation
print(res.value + 1.0)

In this case, we should make very clear in the docs that the object returned by wiz.res() is non-modifiable, e.g. you cannot set res.value = 42 afterwards and expect the underlying value to change. It is read-only.

But maybe that is overkill and we should leave it at strings. One could also argue that the user already knows the numerical value upfront, so they could instead just assign it the a local variable before passing it to wiz.res() and would be good to go... This would also avoid confusion about the modifiability ob the object returned by wiz.res() since when you only get back strings, you probably don't expect that this would modify the underlying valueres.value = "42.0". In that case, maybe we can even drop the "str" part of the method names? Since the datatype is clear by the method signature -> str.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But maybe that is overkill and we should leave it at strings.

I agree :-)


def get_str_without_uncert(self) -> str:
stringifier = ConsoleStringifier(c.configuration.to_stringifier_config())
return stringifier.create_str_without_uncert(self._result)

def get_uncerts(self) -> list[dict[str, str]]:
stringifier = ConsoleStringifier(c.configuration.to_stringifier_config())
return [
{
"name": u.name,
"string": stringifier.create_str_uncert(u, self._result.unit),
}
for u in self._result.uncertainties
]
paul019 marked this conversation as resolved.
Show resolved Hide resolved

def get_str_uncert_total(self) -> str:
stringifier = ConsoleStringifier(c.configuration.to_stringifier_config())
short_result = self._result.get_short_result()
if short_result is None:
raise RuntimeError(error_messages.SHORT_RESULT_IS_NONE)
return stringifier.create_str_uncert(short_result.uncertainties[0], self._result.unit)

def get_str_short(self) -> str:
stringifier = ConsoleStringifier(c.configuration.to_stringifier_config())
short_result = self._result.get_short_result()
if short_result is None:
raise RuntimeError(error_messages.SHORT_RESULT_IS_NONE)
return stringifier.create_str(short_result)

def get_str_without_unit(self) -> str:
stringifier = ConsoleStringifier(c.configuration.to_stringifier_config())
return stringifier.create_str_without_unit(self._result)

def to_latex_str(self) -> str:
"""Converts the result to a string that can be used in LaTeX documents.

Expand Down
36 changes: 9 additions & 27 deletions src/application/latex_commandifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ def result_to_latex_cmd(self, result: Result) -> str:
latex_str = rf"\newcommand*{{\{cmd_name}}}[1][]{{" + "\n"

# Default case (full result) & value
builder.add_branch("", self.result_to_latex_str(result))
builder.add_branch("value", self.result_to_latex_str_value(result))
builder.add_branch("", self.s.create_str(result))
builder.add_branch("value", self.s.create_str_value(result))

# Without uncertainty
if len(result.uncertainties) > 0:
builder.add_branch("withoutUncert", self.result_to_latex_str_without_uncert(result))
builder.add_branch("withoutUncert", self.s.create_str_without_uncert(result))

# Single uncertainties
for i, u in enumerate(result.uncertainties):
Expand All @@ -37,24 +37,24 @@ def result_to_latex_cmd(self, result: Result) -> str:
else:
uncertainty_name = u.name if u.name != "" else Helpers.number_to_word(i + 1)
uncertainty_name = f"uncert{Helpers.capitalize(uncertainty_name)}"
uncertainty_latex_str = self.s.create_str(u.uncertainty, [], result.unit)
uncertainty_latex_str = self.s.create_str_uncert(u, result.unit)
builder.add_branch(uncertainty_name, uncertainty_latex_str)

# Total uncertainty and short result
if len(result.uncertainties) >= 2:
short_result = result.get_short_result()
if short_result is None:
raise RuntimeError(error_messages.SHORT_RESULT_IS_NONE)
uncertainty_latex_str = self.s.create_str(
short_result.uncertainties[0].uncertainty, [], result.unit
uncertainty_latex_str = self.s.create_str_uncert(
short_result.uncertainties[0], result.unit
)
builder.add_branch("uncertTotal", uncertainty_latex_str)
builder.add_branch("short", self.result_to_latex_str(short_result))
builder.add_branch("short", self.s.create_str(short_result))

# Unit
if result.unit != "":
builder.add_branch("unit", rf"\unit{{{result.unit}}}")
builder.add_branch("withoutUnit", self.result_to_latex_str_without_unit(result))
builder.add_branch("withoutUnit", self.s.create_str_without_unit(result))

# Error message
keywords = builder.keywords
Expand All @@ -74,22 +74,4 @@ def result_to_latex_str(self, result: Result) -> str:
"""
Returns the result as LaTeX string making use of the siunitx package.
"""
return self.s.create_str(result.value, result.uncertainties, result.unit)

def result_to_latex_str_value(self, result: Result) -> str:
"""
Returns only the value as LaTeX string making use of the siunitx package.
"""
return self.s.create_str(result.value, [], "")

def result_to_latex_str_without_uncert(self, result: Result) -> str:
"""
Returns the result without uncertainty as LaTeX string making use of the siunitx package.
"""
return self.s.create_str(result.value, [], result.unit)

def result_to_latex_str_without_unit(self, result: Result) -> str:
"""
Returns the result without unit as LaTeX string making use of the siunitx package.
"""
return self.s.create_str(result.value, result.uncertainties, "")
return self.s.create_str(result)
23 changes: 22 additions & 1 deletion src/application/stringifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from typing import List, Tuple
from typing import Protocol, ClassVar
from decimal import Decimal
from domain.result import Result

# for why we use a Protocol instead of a ABC class, see
# https://github.com/microsoft/pyright/issues/2601#issuecomment-977053380
Expand Down Expand Up @@ -51,7 +52,7 @@ class Stringifier(Protocol):
def __init__(self, config: StringifierConfig):
self.config = config

def create_str(self, value: Value, uncertainties: List[Uncertainty], unit: str) -> str:
def _create_str(self, value: Value, uncertainties: List[Uncertainty], unit: str) -> str:
"""
Returns the result as LaTeX string making use of the siunitx package.

Expand Down Expand Up @@ -84,6 +85,26 @@ def create_str(self, value: Value, uncertainties: List[Uncertainty], unit: str)
unit,
)

def create_str(self, result: Result) -> str:
"""
Returns the result as LaTeX string making use of the siunitx package.

This string does not yet contain "\newcommand*{}".
"""
return self._create_str(result.value, result.uncertainties, result.unit)

def create_str_uncert(self, uncertainty: Uncertainty, unit: str) -> str:
return self._create_str(uncertainty.uncertainty, [], unit)

def create_str_value(self, result: Result) -> str:
return self._create_str(result.value, [], "")

def create_str_without_uncert(self, result: Result) -> str:
return self._create_str(result.value, [], result.unit)

def create_str_without_unit(self, result: Result) -> str:
return self._create_str(result.value, result.uncertainties, "")

# pylint: disable-next=too-many-arguments
def _assemble_str_parts(
self,
Expand Down