fork(1) download
  1. # Parcial 2 2021/22 (c) 2022 Baltasar MIT License <jbgarcia@uvigo.es>
  2.  
  3.  
  4. import json
  5. from datetime import datetime
  6.  
  7.  
  8. class RegistroTelefonico:
  9. """La clase RegistroTelefonico es capaz de albergar
  10. cuándo se produjeron las llamadas de los usuarios
  11. de una compañía telefónica, a través de un diccionario
  12. de claves datetime (hasta el segundo, no microsegundo) y
  13. valores de listas conteniendo varias
  14. cadenas de caracteres correspondientes a las diferentes
  15. llamadas comenzadas en ese momento.
  16. Las listas con los números de teléfono pueden ser
  17. accedidos como tuplas por el momento en el que se produjeron las llamadas,
  18. mediante el método ficticio get_for(d: datetime) -> tuple[str],
  19. o bien mediante un método ficticio get(i: int) -> tuple[str],
  20. de manera que get(0) devuelve la primera tupla de teléfonos
  21. ordenadas según el momento de la llamada.
  22. por nombre construido (r#i), o por índice.
  23. El constructor no necesita ningún parámetro.
  24. Los únicos métodos en la clase son:
  25. __init__(), add(d: datetime, ll: str), __getattr__(),
  26. __len__() (que devuelve el número de elementos),
  27. y __str__() (que devuelve el contenido del objeto como
  28. texto, en el formato: <formato_datetime_defecto>: 999999999, 999999999).
  29. """
  30. def __init__(self):
  31. self._modified = True
  32. self._cache = tuple()
  33. self._reg = {}
  34.  
  35. @staticmethod
  36. def __datetime_cnv(d: datetime):
  37. """Convierte un datetime con microsegundos a otro sin él."""
  38. return datetime(d.year, d.month, d.day, d.hour, d.minute, d.second)
  39.  
  40. def inserta(self, d: datetime, tlf: str):
  41. """Añade un teléfono a la lista para ese momento"""
  42. self._modified = True
  43. dm = RegistroTelefonico.__datetime_cnv(d)
  44. lls = self._reg.get(dm)
  45.  
  46. if not lls:
  47. self._reg[dm] = [tlf]
  48. else:
  49. lls.append(tlf)
  50.  
  51. def __crea_cache(self):
  52. if self._modified:
  53. self._cache = list(self._reg.items())
  54. self._cache.sort(key=lambda it: it[0])
  55. self._cache = tuple(self._cache)
  56. self._modified = False
  57.  
  58. def __getattr__(self, item):
  59. if item == "get":
  60. self.__crea_cache()
  61. return lambda i: tuple(self._cache[i])
  62. elif item == "get_for":
  63. return lambda d: tuple(self._reg.get(d)) if self._reg.get(d) else tuple()
  64.  
  65. raise AttributeError(item)
  66.  
  67. def to_json(self):#, f):
  68. """
  69. Convertir los datos del objeto en JSON a un fichero.
  70. Formato:
  71. {
  72. '2022-05-13 10:41:00': ["988387000", "988387002"],
  73. '2022-05-13 10:41:35': ["988387001"]
  74. }
  75. """
  76. d_dump = {str(k): v for k, v in self._reg.items()}
  77. return json.dumps(d_dump)#, f)
  78.  
  79. @staticmethod
  80. def from_json(str_json_data):# f):
  81. """
  82. Convertir los datos del fichero a JSON y asignar el diccionario.
  83. Formato:
  84. {
  85. '2022-05-13 10:41:00': ["988387000", "988387002"],
  86. '2022-05-13 10:41:35': ["988387001"]
  87. }
  88. """
  89. d_dump = json.loads(str_json_data)# f)
  90. d_dump = {datetime.strptime(k, "%Y-%m-%d %H:%M:%S"): v for k, v in d_dump.items()}
  91. toret = RegistroTelefonico()
  92. toret._reg = d_dump
  93. return toret
  94.  
  95. def filter(self, pred: callable):
  96. """Devolver aquellos elementos (completos) de la cache que cumplen pred."""
  97. return [tupla for tupla in self._cache if pred(tupla)]
  98.  
  99. def __len__(self):
  100. return len(self._reg)
  101.  
  102. def __str__(self):
  103. self.__crea_cache()
  104.  
  105. return str.join("\n", [str(pair[0]) + ": "
  106. + ", ".join([tlf for tlf in pair[1]])
  107. for pair in self._cache])
  108.  
  109.  
  110. if __name__ == "__main__":
  111. r = RegistroTelefonico()
  112. r.inserta(datetime(2022, 9, 13, 10, 41), "988387000")
  113. r.inserta(datetime(2022, 9, 13, 10, 41), "988387002")
  114. r.inserta(datetime(2022, 9, 13, 10, 41, 35), "988387001")
  115. print(r.get(0))
  116. print("Filtrado por segundo no 0: " + str(r.filter(lambda t: t[0].second != 0)))
  117. print("Filtrado primer tlf acabado en 02: " + str(r.filter(lambda t: t[1][0].endswith("01"))))
  118.  
  119. # Modificado para que se pueda ejecutar en IDEOne,
  120. # Se pedía utilizar ficheros y json.dump()/json.load()
  121. # en lugar de json.dumps()/json.loads()
  122. json_data = r.to_json()
  123. print("Guardando: " + json_data)
  124. print("Recuperando:\n" + str(RegistroTelefonico.from_json(json_data)))
  125.  
Success #stdin #stdout 0.04s 11100KB
stdin
Standard input is empty
stdout
(datetime.datetime(2022, 9, 13, 10, 41), ['988387000', '988387002'])
Filtrado por segundo no 0: [(datetime.datetime(2022, 9, 13, 10, 41, 35), ['988387001'])]
Filtrado primer tlf acabado en 02: [(datetime.datetime(2022, 9, 13, 10, 41, 35), ['988387001'])]
Guardando: {"2022-09-13 10:41:00": ["988387000", "988387002"], "2022-09-13 10:41:35": ["988387001"]}
Recuperando:
2022-09-13 10:41:00: 988387000, 988387002
2022-09-13 10:41:35: 988387001