__init__.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. import datetime
  2. import typing
  3. class Person:
  4. """
  5. >>> alice = Person('alice')
  6. >>> alice.name = 'Alice Test'
  7. >>> alice.birth_date = datetime.date(2019, 12, 23)
  8. >>> alice
  9. Person(alice, Alice Test, *2019-12-23)
  10. >>> str(alice)
  11. 'Alice Test (*2019-12-23)'
  12. >>> bob = Person('bob')
  13. >>> bob.name = 'Bob Test'
  14. >>> alice.father = bob
  15. """
  16. def __init__(self, identifier: str):
  17. self.identifier: str = identifier
  18. self.name: typing.Optional[str] = None
  19. self.birth_date: typing.Optional[datetime.date] = None
  20. self.mother: typing.Optional["Person"] = None
  21. self.father: typing.Optional["Person"] = None
  22. def __repr__(self) -> str:
  23. """
  24. >>> p = Person("max-mustermann")
  25. >>> repr(p)
  26. 'Person(max-mustermann)'
  27. >>> p.name = "Hr. Mustermann"
  28. >>> repr(p)
  29. 'Person(max-mustermann, Hr. Mustermann)'
  30. >>> p.name = "Max Mustermann"
  31. >>> repr(p)
  32. 'Person(max-mustermann, Max Mustermann)'
  33. >>> p.birth_date = datetime.date(1976, 2, 1)
  34. >>> repr(p)
  35. 'Person(max-mustermann, Max Mustermann, *1976-02-01)'
  36. """
  37. return "{}({})".format(
  38. type(self).__name__,
  39. ", ".join(
  40. filter(
  41. None,
  42. (
  43. self.identifier,
  44. self.name,
  45. "*" + self.birth_date.isoformat()
  46. if self.birth_date is not None
  47. else None,
  48. ),
  49. )
  50. ),
  51. )
  52. def __str__(self) -> str:
  53. """
  54. >>> p = Person("max-mustermann")
  55. >>> p.name = "Max Mustermann"
  56. >>> str(p)
  57. 'Max Mustermann'
  58. >>> p.birth_date = datetime.date(1976, 2, 1)
  59. >>> str(p)
  60. 'Max Mustermann (*1976-02-01)'
  61. """
  62. return (self.name or "unnamed") + (
  63. " (*{})".format(self.birth_date.isoformat()) if self.birth_date else ""
  64. )
  65. def __eq__(self, other: "Person") -> bool:
  66. """
  67. >>> maxl = Person("max")
  68. >>> maxl.name = "Max Mustermann"
  69. >>> maxl == Person("max")
  70. True
  71. >>> erika = Person("erika")
  72. >>> erika.name = "Max Mustermann"
  73. >>> maxl == erika
  74. False
  75. """
  76. return self.identifier == other.identifier
  77. def merge(self, person: "Person") -> None:
  78. """
  79. >>> p1 = Person("max")
  80. >>> p1.name = "Max Mustermann"
  81. >>> str(p1)
  82. 'Max Mustermann'
  83. >>> p2 = Person("max2")
  84. >>> p2.birth_date = datetime.date(1976, 2, 1)
  85. >>> p2.mother = Person("mother")
  86. >>> p2.father = Person("father")
  87. >>> str(p2)
  88. 'unnamed (*1976-02-01)'
  89. add attributes of p2 to p1:
  90. >>> p1.merge(p2)
  91. >>> str(p1)
  92. 'Max Mustermann (*1976-02-01)'
  93. >>> p1.mother, p1.father
  94. (Person(mother), Person(father))
  95. p2 is unchanged:
  96. >>> str(p2)
  97. 'unnamed (*1976-02-01)'
  98. """
  99. for attr in ["name", "birth_date", "mother", "father"]:
  100. if getattr(person, attr) is not None:
  101. setattr(self, attr, getattr(person, attr))
  102. class PersonCollection:
  103. """
  104. >>> bob = Person('bob')
  105. >>> bob.name = 'Bob Test'
  106. >>> alice = Person('alice')
  107. >>> alice.name = 'Alice Test'
  108. >>> alice.father = bob
  109. >>> collection = PersonCollection()
  110. >>> collection.add_person(alice)
  111. Person(alice, Alice Test)
  112. >>> for person in collection:
  113. ... print(person.name)
  114. Bob Test
  115. Alice Test
  116. """
  117. def __init__(self):
  118. self._persons = {}
  119. self.__it = None
  120. def __getitem__(self, identifier: str) -> Person:
  121. """
  122. >>> c = PersonCollection()
  123. >>> c.add_person(Person("alice"))
  124. Person(alice)
  125. >>> c["alice"]
  126. Person(alice)
  127. """
  128. return self._persons[identifier]
  129. def add_person(self, person: Person) -> Person:
  130. """
  131. >>> c = PersonCollection()
  132. >>> c.add_person(Person("alice"))
  133. Person(alice)
  134. >>> c.add_person(Person("bob"))
  135. Person(bob)
  136. >>> c["bob"]
  137. Person(bob)
  138. >>> bob = Person("bob")
  139. >>> bob.birth_date = datetime.date(2010, 2, 3)
  140. >>> bob.mother = Person("bob-mum")
  141. >>> bob.father = Person("bob-dad")
  142. >>> c.add_person(bob)
  143. Person(bob, *2010-02-03)
  144. >>> list(c)
  145. [Person(alice), Person(bob, *2010-02-03), Person(bob-mum), Person(bob-dad)]
  146. """
  147. if person.mother is not None:
  148. person.mother = self.add_person(person.mother)
  149. if person.father is not None:
  150. person.father = self.add_person(person.father)
  151. if person.identifier not in self._persons:
  152. self._persons[person.identifier] = person
  153. return person
  154. existing_person = self._persons[person.identifier]
  155. existing_person.merge(person)
  156. return existing_person
  157. def __iter__(self) -> "PersonCollection":
  158. """
  159. >>> c = PersonCollection()
  160. >>> for identifier in ['alice', 'bob', 'charlie']:
  161. ... c.add_person(Person(identifier))
  162. Person(alice)
  163. Person(bob)
  164. Person(charlie)
  165. >>> list(c)
  166. [Person(alice), Person(bob), Person(charlie)]
  167. """
  168. self.__it = iter(self._persons.values())
  169. return self
  170. def __next__(self) -> Person:
  171. return next(self.__it)