refactored Sums into a class in sumfinder (much cleaner) and added method to output Sums to stdout
This commit is contained in:
parent
6bcdade804
commit
e1d71014d4
File diff suppressed because one or more lines are too long
|
@ -1,22 +1,22 @@
|
|||
#!/usr/bin/env python3
|
||||
from pathlib import Path
|
||||
from sumfinder import load_sums, remove_invalid_sums
|
||||
from sumfinder import Sums
|
||||
from linuxmem import read_meminfo_stdout
|
||||
|
||||
|
||||
def main():
|
||||
sums = load_sums(Path('../expe001.5/alambix97-meminfo-sums.json'))
|
||||
print(f'starting sums ({len(sums)} sums):')
|
||||
print(sums)
|
||||
sums = Sums.load(Path('../expe001.5/alambix97-meminfo-sums.json'))
|
||||
print(f'starting sums ({sums.get_num_equations()} sums):')
|
||||
sums.print()
|
||||
|
||||
variables = read_meminfo_stdout(Path('../bug3897/alambix98/20240806-223916-meminfo.stdout'))
|
||||
# variables = read_meminfo_stdout(Path('../bug3897/alambix97/20240805-191606-meminfo.stdout'))
|
||||
(valid_sums, invalid_sums) = remove_invalid_sums(sums, variables)
|
||||
print(f'invalid sums ({len(invalid_sums)} sums):')
|
||||
print(invalid_sums)
|
||||
(valid_sums, invalid_sums) = sums.validate_on_variables(variables)
|
||||
print(f'invalid sums ({invalid_sums.get_num_equations()} sums):')
|
||||
invalid_sums.print()
|
||||
|
||||
print(f'valid sums ({len(valid_sums)} sums):')
|
||||
print(valid_sums)
|
||||
print(f'valid sums ({valid_sums.get_num_equations()} sums):')
|
||||
valid_sums.print()
|
||||
|
||||
|
||||
main()
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
from .sumfinder import Sums # noqa
|
||||
from .sumfinder import SumExporter # noqa
|
||||
from .sumfinder import load_sums # noqa
|
||||
from .sumfinder import find_sums # noqa
|
||||
from .sumfinder import sums_to_dot # noqa
|
||||
from .sumfinder import find_and_graph_sums # noqa
|
||||
from .sumfinder import remove_invalid_sums # noqa
|
||||
|
|
|
@ -9,7 +9,7 @@ import subprocess
|
|||
|
||||
VarName = str
|
||||
VarValue = int
|
||||
Sums = List[Dict[VarName, List[VarName]]]
|
||||
Sum = Dict[VarName, List[VarName]]
|
||||
|
||||
|
||||
class IntVariable():
|
||||
|
@ -24,6 +24,66 @@ class IntVariable():
|
|||
return f'{self.name}: {self.value}'
|
||||
|
||||
|
||||
class Sums():
|
||||
|
||||
variables: Set[IntVariable]
|
||||
sums: List[Sum]
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.variables = set()
|
||||
self.sums = []
|
||||
|
||||
def get_num_variables(self):
|
||||
return len(self.variables)
|
||||
|
||||
def get_num_equations(self):
|
||||
return len(self.sums)
|
||||
|
||||
@staticmethod
|
||||
def load(sums_file_path: Path) -> 'Sums':
|
||||
sums = Sums()
|
||||
with open(sums_file_path, 'rt', encoding='utf8') as sums_file:
|
||||
root_dict = json.loads(sums_file.read())
|
||||
assert root_dict['format'] == 'sums-v001'
|
||||
sums.sums = root_dict['sums']
|
||||
sums.variables = {IntVariable(var_id, var_value) for var_id, var_value in root_dict['variables'].items()}
|
||||
return sums
|
||||
|
||||
def save(self, sums_file_path: Path):
|
||||
root_dict = {}
|
||||
root_dict['format'] = 'sums-v001'
|
||||
root_dict['variables'] = {var.name: var.value for var in self.variables}
|
||||
root_dict['sums'] = self.sums
|
||||
sums_file_path.write_text(json.dumps(root_dict))
|
||||
|
||||
def print(self):
|
||||
equation_index = 0
|
||||
for s in self.sums:
|
||||
print(f"{equation_index}: {s['total']} = {' + '.join([comp_id for comp_id in s['components']])}")
|
||||
equation_index += 1
|
||||
|
||||
def validate_on_variables(self, variables: Dict[VarName, VarValue]) -> Tuple['Sums', 'Sums']:
|
||||
"""
|
||||
returns the tuple valid_sums, invalid_sums after checking each of the sum of input_sum againts the given variables
|
||||
"""
|
||||
valid_sums: Sums = Sums()
|
||||
invalid_sums: Sums = Sums()
|
||||
for _sum in self.sums:
|
||||
# for total_var_id, components in input_sums.items():
|
||||
total_var_id = _sum['total']
|
||||
components = _sum['components']
|
||||
|
||||
computed_total_value = 0
|
||||
for component_var_id in components:
|
||||
computed_total_value += variables[component_var_id]
|
||||
real_total_value = variables[total_var_id]
|
||||
if computed_total_value == real_total_value:
|
||||
valid_sums.sums.append(_sum)
|
||||
else:
|
||||
invalid_sums.sums.append(_sum)
|
||||
return (valid_sums, invalid_sums)
|
||||
|
||||
|
||||
class ISumHandler(abc.ABC):
|
||||
|
||||
@abc.abstractmethod
|
||||
|
@ -48,35 +108,23 @@ class SumExporter(ISumHandler):
|
|||
'''handler that exports the sums as a graphviz dot file
|
||||
'''
|
||||
sum_file_path: Path
|
||||
variables: Set[IntVariable]
|
||||
sums: Sums
|
||||
|
||||
def __init__(self, sum_file_path: Path):
|
||||
self.sum_file_path = sum_file_path
|
||||
self.variables = set()
|
||||
self.sums = []
|
||||
self.sums = Sums()
|
||||
|
||||
def on_sum_found(self, total: IntVariable, components: List[IntVariable]):
|
||||
self.variables.add(total)
|
||||
self.sums.variables.add(total)
|
||||
for component in components:
|
||||
self.variables.add(component)
|
||||
self.sums.variables.add(component)
|
||||
print(f"sum found: {total.name} = {' + '.join([comp.name for comp in components])}")
|
||||
self.sums.append({'total': total.name, 'components': [comp.name for comp in components]})
|
||||
self.sums.sums.append({'total': total.name, 'components': [comp.name for comp in components]})
|
||||
|
||||
def on_end(self):
|
||||
print(f'exporting sums to {self.sum_file_path}')
|
||||
root_dict = {}
|
||||
root_dict['format'] = 'sums-v001'
|
||||
root_dict['variables'] = {var.name: var.value for var in self.variables}
|
||||
root_dict['sums'] = self.sums
|
||||
self.sum_file_path.write_text(json.dumps(root_dict))
|
||||
|
||||
|
||||
def load_sums(sums_file_path: Path) -> Sums:
|
||||
with open(sums_file_path, 'rt', encoding='utf8') as sums_file:
|
||||
root_dict = json.loads(sums_file.read())
|
||||
assert root_dict['format'] == 'sums-v001'
|
||||
return root_dict['sums']
|
||||
self.sums.save(self.sum_file_path)
|
||||
|
||||
|
||||
def explore(total: IntVariable, components: List[IntVariable], cur_sum: VarValue, cur_var_index: int, contrib_components: List[IntVariable], sum_handler: ISumHandler):
|
||||
|
@ -266,12 +314,8 @@ def sums_to_dot(sum_file_path: Path, dot_file_path: Path):
|
|||
"yellowgreen"]
|
||||
|
||||
print(f'creating {dot_file_path} from {sum_file_path}')
|
||||
with open(sum_file_path, 'rt', encoding='utf8') as sum_file:
|
||||
root_dict = json.load(sum_file)
|
||||
sums = Sums.load(sum_file_path)
|
||||
# print(root_dict)
|
||||
variables = {IntVariable(var_name, var_value) for var_name, var_value in root_dict['variables'].items()}
|
||||
# print(variables)
|
||||
sums = root_dict['sums']
|
||||
# print(sums)
|
||||
with open(dot_file_path, 'wt+', encoding='utf8') as dot_file:
|
||||
dot_file.write(f'digraph {to_dot_symbol(sum_file_path.stem)}\n')
|
||||
|
@ -279,10 +323,10 @@ def sums_to_dot(sum_file_path: Path, dot_file_path: Path):
|
|||
dot_file.write('layout = neato\n')
|
||||
dot_file.write('overlap = false\n')
|
||||
|
||||
for variable in variables:
|
||||
for variable in sums.variables:
|
||||
dot_file.write(f'{to_dot_symbol(variable.name)} [label="{variable.name}={variable.value}"];\n')
|
||||
sum_index = 0
|
||||
for s in sums:
|
||||
for s in sums.sums:
|
||||
dot_file.write(f"{to_dot_symbol(s['total'])} -> {{{','.join([to_dot_symbol(comp) for comp in s['components']])}}} [color={svg_colors[sum_index % len(svg_colors)]}, label={sum_index}];\n")
|
||||
sum_index += 1
|
||||
dot_file.write('}\n')
|
||||
|
@ -298,25 +342,3 @@ def find_and_graph_sums(variables: Dict[str, int], set_id: str):
|
|||
sums_to_dot(sums_file_path, dot_file_path)
|
||||
print(f'creating {svg_file_path} from {dot_file_path}')
|
||||
subprocess.run(f'dot -Tsvg {dot_file_path} > {svg_file_path}', shell=True, check=True)
|
||||
|
||||
|
||||
def remove_invalid_sums(input_sums: Sums, variables: Dict[VarName, VarValue]) -> Tuple[Sums, Sums]:
|
||||
"""
|
||||
returns the tuple valid_sums, invalid_sums after checking each of the sum of input_sum againts the given variables
|
||||
"""
|
||||
valid_sums: Sums = []
|
||||
invalid_sums: Sums = []
|
||||
for _sum in input_sums:
|
||||
# for total_var_id, components in input_sums.items():
|
||||
total_var_id = _sum['total']
|
||||
components = _sum['components']
|
||||
|
||||
computed_total_value = 0
|
||||
for component_var_id in components:
|
||||
computed_total_value += variables[component_var_id]
|
||||
real_total_value = variables[total_var_id]
|
||||
if computed_total_value == real_total_value:
|
||||
valid_sums.append(_sum)
|
||||
else:
|
||||
invalid_sums.append(_sum)
|
||||
return (valid_sums, invalid_sums)
|
||||
|
|
Loading…
Reference in New Issue