0

I'm trying to figure it out a way to create a namedtuple with variable fields depending on the data you receive, in my case, I'm using the data from StatCounter and not on all the periods are the same browsers. I tried this way but it is a bit ugly and I'm sure there is a better way to achieve it.

def namedtuple_fixed(name: str, fields: List[str]) -> namedtuple:
    """Check the fields of the namedtuple and changes the invalid ones."""

    fields_fixed: List[str] = []

    for field in fields:
        field = field.replace(" ", "_")

        if field[0].isdigit():
            field = f"n{field}"

        fields_fixed.append(field)

    return namedtuple(name, fields_fixed)


Records: namedtuple = namedtuple("empty_namedtuple", "")


def read_file(file: str) -> List["Records"]:
    """
    Read the file with info about the percentage of use of various browsers
    """
    global Records

    with open(file, encoding="UTF-8") as browsers_file:
        reader: Iterator[List[str]] = csv.reader(browsers_file)
        field_names: List[str] = next(reader)
        Records = namedtuple_fixed("Record", field_names)
        result: List[Records] = [
            Records(
                *[
                    dt.datetime.strptime(n, "%Y-%m").date()
                    if record.index(n) == 0
                    else float(n)
                    for n in record
                ]
            )
            for record in reader
        ]
    return result

The "namedtuple_fixed" function is to fix the names that have invalid identifiers.

Basically, I want to create a named tuple that receives a variable number of parameters, depending on the file you want to analyze. And if it's with type checking incorporated (I mean using NamedTuple from the typing module), much better. Thanks in advance.

Davichete
  • 415
  • 7
  • 14

1 Answers1

0

This solves my problem, but just partially


class Record(SimpleNamespace):
    def __repr__(self):
        items = [f"{key}={value!r}" for key, value in self.__dict__.items()]
        return f"Record({', '.join(items)})"

Using the types.SimpleSpace documentation

And it can cause problems, like for example if you initiallize a Record like the following:

foo = Record(**{"a": 1, "3a": 2})
print(foo.a) # Ok
print(foo.3a) # Syntax Error
Davichete
  • 415
  • 7
  • 14