This repository has been archived on 2024-05-19. You can view files and clone it, but cannot push or open issues or pull requests.
l-systems/converter.py
2024-04-17 15:37:25 +02:00

124 lines
3.8 KiB
Python

from csv import reader as csv_reader
from pprint import pformat
from pprint import pp as pprint
from sys import argv, stderr
from xml.dom.minidom import parseString as xml_parser
from xml.etree import ElementTree
class System:
"""Represents an L-System"""
def __init__(
self,
name: str,
base: list[str],
axiom: str,
substitutions: list[tuple[str, str]],
interpretations: list[tuple[str, str]],
):
self.name = name
"""System name"""
self.base = base
"""Set used"""
self.axiom = axiom
"""Axiom used at the start of iterations"""
self.substitutions = substitutions
"""
Substitution for each member of the base,
represented as a couple (member, substitution)
"""
self.interpretations = interpretations
"""
Interpretation for each member of the base,
represented as a couple (member, interpretation)
"""
# TODO: Est-ce que on garde ça ??
# Interpretation of extra symbols added if necessary
extra_symbols = ["[", "]"]
for _, substitution in substitutions:
if any(symbol in substitution for symbol in extra_symbols):
self.interpretations.extend(
[(extra_symbols[0], "STORE"), (extra_symbols[1], "RESTORE")]
)
break
def __repr__(self):
return pformat(self.__dict__, compact=True, width=120, sort_dicts=False)
def to_xml(self) -> ElementTree.Element:
"""Convert the current system into an XML element"""
system = ElementTree.Element("lsystem")
base = ElementTree.SubElement(system, "base")
base.text = "".join(self.base)
axiom = ElementTree.SubElement(system, "axiom")
axiom.text = self.axiom
substitutions = ElementTree.SubElement(system, "substitutions")
for member, substitution in self.substitutions:
sub_element = ElementTree.SubElement(substitutions, "substitution")
sub_element.set("member", member)
sub_element.text = substitution
interpretations = ElementTree.SubElement(system, "interpretations")
for member, interpretation in self.interpretations:
inter_element = ElementTree.SubElement(interpretations, "interpretation")
inter_element.set("member", member)
inter_element.text = interpretation
return system
def data_reader(path: str, delimiter: str = ","):
"""Read a CSV file and returns a list of L-System"""
res: list[System] = []
with open(path) as csv_file:
data = csv_reader(csv_file, delimiter=delimiter)
for system in data:
name = system[0]
base = list(system[1])
axiom = system[2]
substitutions = [(v, system[3 + i]) for i, v in enumerate(base)]
interpretations = [
(v, system[3 + i + len(substitutions)]) for i, v in enumerate(base)
]
res.append(System(name, base, axiom, substitutions, interpretations))
return res
def lsystems_xml(systems: list[System]) -> ElementTree.Element:
"""Convert list of L-system structure into XML"""
root = ElementTree.Element("lsystems")
for system in systems:
root.append(system.to_xml())
return root
if __name__ == "__main__":
if len(argv) != 2:
pprint(f"Syntax error:\n\tpython {argv[0]} file.csv", stream=stderr)
exit(1)
# TODO: Check if we have to dump to stdout or we write into a file
# use `argparse` for cli arguments
# Read data
lsystems = data_reader(argv[1])
# Generate XML
xml = lsystems_xml(lsystems)
# Print XML
dom = xml_parser(ElementTree.tostring(xml))
print(dom.toprettyxml(encoding="UTF-8").decode())