Skip to content

Instantly share code, notes, and snippets.

@ricardosiri68
Last active August 29, 2015 14:00
Show Gist options
  • Save ricardosiri68/645710ac58060f4782cc to your computer and use it in GitHub Desktop.
Save ricardosiri68/645710ac58060f4782cc to your computer and use it in GitHub Desktop.
class MyDict:
"""
*--------------------------------------------------------------------------
* crea un diccionario personalizado con los mismos objectos y metodos
*--------------------------------------------------------------------------
"""
def __init__(self, *args):
self.__values = []
try:
for key, value in args:
try:
hash(key)
except TypeError:
raise TypeError("%s no es un objeto inmutable" % key)
self[key] = value
except TypeError:
raise TypeError("no es una tupla o una lista")
except ValueError:
raise ValueError(
"el iterable tiene demaciados valores para desempaquetar"
)
def __getitem__(self, key):
for k, v in self.__values:
if key == k:
return v
raise KeyError("la clave '%s' no existe en el diccionario" % key)
def __delitem__(self, key):
for i in range(len(self.__values)):
if self.__values[i][0] == key:
del self.__values[i]
break
def __setitem__(self, key, value):
found = False
for i in range(len(self.__values)):
if self.__values[i][0] == key:
self.__values[i] = key, value
found = True
if not found:
self.__values.append((key, value))
def clear(self):
self.__values = []
def copy(self):
return self.__class__(*self.__values)
def fromkeys(cls, iter, value=None):
return cls(*[(key, value) for key in iter])
def get(self, key, default=None):
try:
return self[key]
except KeyError:
if not default is None:
return default
else:
raise KeyError(key)
def items(self):
"""
*----------------------------------------------------------------------
* el metodo items de los diccionarios built-in no permiten indexado
* de modo que una lista no es la correcta devolucion. Siendo asi, se
* usa un generador que es lo mas parecido al objecto dict_items que
* tengo a mano xD
*----------------------------------------------------------------------
"""
for kv in self.__values:
yield kv
def keys(self):
"""
*----------------------------------------------------------------------
* lo mismo que sucede con el metodo items no sucede con el metodo keys
*----------------------------------------------------------------------
"""
for key, values in self.__values:
yield key
def pop(self, key):
value = self[key]
del self[key]
return value
def popitem(self):
"""
*----------------------------------------------------------------------
* en teoria popitem deberia remover y devolver un item aleatorio pero
* para eso es necesario el modulo random y no quiero importar nada para
* que quede mas limpio de dependencias solo emergera el primero de la
* lista
*----------------------------------------------------------------------
"""
return self.__values.pop(0)
def update(self, d):
if isinstance(d, self.__class__):
for key, value in d.items():
self[key] = value
else:
raise TypeError("El objeto ingresado no es iterable")
def values(self):
"""
*----------------------------------------------------------------------
* lo mismo que sucede con los metodos items y keys suscede con values
*----------------------------------------------------------------------
"""
for key, value in self.__values:
yield value
def __repr__(self):
out = "{ "
for kv in self.__values:
out += " %s : %s," % kv
return out + " }"
import unittest
from mydict import MyDict
class TestMyDict(unittest.TestCase):
def testInitialize(self):
d = MyDict(("test1", 1), ("test2", 2), ("test3", 3))
self.assertIsInstance(d, MyDict)
def testWrongTypeKey(self):
self.assertRaises(TypeError, MyDict, ([1, 2], 1))
self.assertRaises(ValueError, MyDict, (1, 2, 1))
def testRepr(self):
r = str(MyDict(("test", 1)))
self.assertEqual("{ test : 1, }", r)
def testClear(self):
d = MyDict(("test1", 1), ("test2", 2))
self.assertEqual(1, d["test1"])
d.clear()
self.assertRaises(KeyError, d.get, "test1")
def testCopy(self):
d = MyDict(("test1", 1), ("test2", 2))
same, copy = d, d.copy()
self.assertTrue(same is d)
self.assertFalse(copy is d)
self.assertEqual(1, copy["test1"])
def testGet(self):
d = MyDict(("test1", 1), ("test2", 2))
self.assertEqual(1, d.get("test1"))
self.assertEqual(False, d.get("test66", False))
self.assertRaises(KeyError, d.get, "test66")
def testItems(self):
d = MyDict(("test1", 1), ("test2", 2))
self.assertTupleEqual(tuple(d.items()), (("test1", 1), ("test2", 2)))
def testKeys(self):
d = MyDict(("test1", 1), ("test2", 2))
self.assertTupleEqual(tuple(d.keys()), ("test1", "test2"))
def testPop(self):
d = MyDict(("test1", 1), ("test2", 2))
self.assertEqual(1, d.pop("test1"))
self.assertRaises(KeyError, d.get, "test1")
def testPopitem(self):
d = MyDict(("test1", 1), ("test2", 2))
self.assertEqual(d.popitem(), ("test1", 1))
self.assertRaises(KeyError, d.get, "test1")
def testUpdate(self):
d = MyDict(("test1", 1), ("test2", 2))
d.update(MyDict(("test2", 222), ("test3", 3)))
self.assertEqual(str(d), "{ test1 : 1, test2 : 222, test3 : 3, }")
def testValues(self):
d = MyDict(("test1", 1), ("test2", 2))
self.assertTupleEqual(tuple(d.values()), (1, 2))
if __name__ == "__main__":
unittest.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment