Path: blob/master/exercices/oop/numbered_indentation/solution_numbered.py
306 views
import re12text_input = """a3b4c5d6e7f8"""910text_output = """1. a111.1. b121.1.1. c131.1.2. d141.2. e152. f16"""1718IGNORE_PATTERN = "//"19DEPTH_PATTERN = " " * 4 # 4 spaces202122class Numerotation:23def __init__(self) -> None:24self._positions = [0]2526def update(self, depth):27max_index = len(self._positions) - 128if depth > max_index:29# to avoid the case with an identation level error30# for example jumping from 2. to 2.1.1.31# we keep adding depths32for _ in range(depth - max_index):33self._positions.append(1)34elif depth == max_index:35# we are still at the deepest level so we increment36self._positions[depth] += 137else:38# we are one or more level higher, we increment this level39self._positions[depth] += 140# and delete the sub levels41for _ in range(max_index - depth):42self._positions.pop()4344def __str__(self):45# we convert the list of int to a list of string first46# then separate it with a dot and add a final dot47o = ".".join(map(str, self._positions))48return f"{o}."495051def main():52lines = text_input.splitlines()53numerotation = Numerotation()54output = []55for line in lines:56print(numerotation)57if not line:58continue59if line.startswith(IGNORE_PATTERN):60output.append(f"{line}\n")61continue62if not line.startswith(DEPTH_PATTERN):63depth = 064numerotation.update(depth)65output.append(f"{numerotation} {line}\n")66continue67depth = len(re.findall(DEPTH_PATTERN, line))68if depth > 0:69numerotation.update(depth)70# we need to inject the numerotation after the depth patterns71index_after_patterns = depth * len(DEPTH_PATTERN)72o_line = f"{line[:index_after_patterns]}{numerotation} {line[index_after_patterns:]}\n"73output.append(o_line)74continue75return "".join(output)767778if __name__ == "__main__":79o = main()80assert o == text_output818283