Source code for pdpy_lib.memory.types

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# **************************************************************************** #
# This file is part of the pdpy project: https://github.com/pdpy-org
# Copyright (C) 2021 Fede Camara Halac
# **************************************************************************** #
""" Pd Types Class Definitions """

from collections import defaultdict
from itertools import zip_longest
from ..core.base import Base

__all__ = [
  'Int',
  'Float',
  'Symbol',
  'List',
]

[docs]class Float(Base): """ A Float base class """ def __init__(self, value=None, name=None, json=None, xml=None): self.__pdpy__ = self.__class__.__name__ super().__init__() if xml is not None: self.name = xml.findtext('name') self.value = self.__num__(xml.findtext('value')) elif json is not None: super().__populate__(self, json=json) elif json is None and xml is None: self.value = self.__num__(value) if value is not None else None self.name = name def __pd__(self): return str(getattr(self, 'value', '')) def __xml__(self): x = super().__element__(scope=self) super().__subelement__(x, 'name', text=self.name) super().__subelement__(x, 'value', text=self.value) return x
[docs]class Symbol(Float): """ A Symbol base class """ def __init__(self, value=None, name=None, json=None, xml=None): self.__pdpy__ = self.__class__.__name__ super().__init__() if xml is not None: self.name = xml.findtext('name') self.value = xml.findtext('value') elif json is not None: super().__populate__(self, json=json) elif json is None and xml is None: self.value = str(value) if value is not None else None self.name = name
[docs]class Int(Float): """ A Int base class """ def __init__(self, value=None, name=None, json=None, xml=None): self.__pdpy__ = self.__class__.__name__ super().__init__() if xml is not None: self.name = xml.findtext('name') self.value = xml.findtext('value') elif json is not None: super().__populate__(self, json=json) elif json is None and xml is None: self.value = int(value) if value is not None else None self.name = name
[docs]class List(Base): """ A List base class """ def __init__(self, name=None, json=None, xml=None): self.__pdpy__ = self.__class__.__name__ super().__init__() if xml is not None: self.name = xml.findtext('name') for e_type in ('float', 'symbol', 'array'): if xml.find(e_type): for x in xml.find(e_type).findall('*'): self.addelement(e_type, x.tag, x.text) elif json is not None: super().__populate__(self, json) else: self.name = name
[docs] def addelement(self, e_type, e_key, e_value): """ Add a type to the list """ # log(1, f"e_type:{e_type}, e_key:{e_key}, e_value:{e_value}") if not hasattr(self, e_type): setattr(self, e_type, defaultdict(list)) attr = getattr(self, e_type) e_value = self.__num__(e_value) if e_type == 'float' else str(e_value) attr[e_key].append(e_value)
def __interleave__(self, s, attr, keys): """ interleave keys variable with attr zip_longest takes care of filling out the list with empty strings if these are of different lengths logic is: 1. for every key 2. get the value from the attr dict 3. return an expanded list of values 4. zip the elements of the list together in nth number of elements 5. filling empty values with empty strings """ # log(1, 'interleave', s, attr, keys) for values in zip_longest(*[attr[k] for k in keys if k in attr], fillvalue=''): # log(1, 'values:', values) # on every paired value for v in values: # if it is a list, iterate over it and join with a space if isinstance(v, list): for val in v: if isinstance(v, list): s += ' '.join(val) else: s += str(val) + " " s += self.__semi__ # otherwise, just append the value as a string else: s += ' ' + str(v) s += self.__semi__ return s def __pd__(self, template): s = '' if hasattr(self, 'float') and hasattr(template, 'float'): keys = getattr(template, 'float') if keys: s = self.__interleave__(s, self.float, keys) s += self.__semi__ if hasattr(self, 'symbol') and hasattr(template, 'symbol'): keys = getattr(template, 'symbol') if keys: s = self.__interleave__(s, self.symbol, keys) s += self.__semi__ if hasattr(self, 'array'): s += ' ' + self.array.__pd__() return s def __xml__(self, template): """ Return the XML Element for this object """ x = super().__element__(scope=self) if hasattr(self, 'float') and hasattr(template, 'float'): keys = getattr(template, 'float') flt = super().__element__(tag='float') for k in keys: if k in self.float: for v in self.float[k]: super().__subelement__(flt, k, text=v) super().__subelement__(x, flt) if hasattr(self, 'symbol') and hasattr(template, 'symbol'): keys = getattr(template, 'symbol') sym = super().__element__(tag='symbol') for k in keys: if k in self.symbol: for v in self.symbol[k]: super().__subelement__(sym, k, text=v) super().__subelement__(x, sym) if hasattr(self, 'array') and hasattr(template, 'array'): for e, t in zip(getattr(self, 'array', []), template.array): _, _template = template.__parent__.getTemplate(t.template) super().__subelement__(x, e.__xml__(_template)) # super().__subelement__(x, self.array.__xml__()) return x