El día 8 de septiembre de 2010 20:13, Christian Pinedo Zamalloa
<chr.pin...@gmail.com> escribió:
> Hola,
>
> llevo más de 2 horas con un problema en Python que no consigo
> solucionar y lo que es peor no consigo ver donde se encuentra el
> problema. Explico el problema.
>
> Dentro del bucle for, en una lista de diccionarios compruebo si está
> un diccionario que tengan una key de nombre id con un valor
> determinado. Si se encuentra se copia el diccionario y se elimina de
> la lista. Posteriormente este diccionario es copiado a otro
> diccionario y sobre este nuevo diccionario se aplican cambios. Pues
> bien al aplicarse cambios en unas keys se pierden los valores de la
> copia...

¿En que te basas para decir eso? ¿Qué valor tiene calls[i] en "DENTRO
DEL BUCLE"?

Con los datos que das se podría pensar que el diccionario viene mal de antes.

> Creo que puede ser un problema con la eliminación del
> diccionario de la lista o las copias de diccionarios que hago....

La copia es muy mejorable como te han indicado. Y parece que tu
diccionario es plano y no vas a necesitar "deep copy". Pero si lo que
guardas con objetos inmutables (y tiene toda la pinta) no deberia
haber problemas en tu modo de copia.

Si miras las trazas verás lo descabellado que es pensar que el
problema está en la eliminación del diccionario de la lista.

> pero
> he intentado mil cosas y no he conseguido nada.
>

Si con trazas no avanzas cambia de estrategia. Igual usar el debugger
es lo suyo.

> Pego el código y el resultado de las pruebas. Gracias!!
>
> CODIGO
> =======
>
>  51     # comprobar si hay un id idéntico en la lista de llamadas
>  52     for i in range(len(calls)):
>  53         if calls[i]['id'] == id:
>  54             if calls[i]['event'] == "ENTERQUEUE" or\
>  55                calls[i]['event'] == "CONNECT":
>  56                 print "DENTRO DEL BUCLE"
>  57                 print "oldcall1"
>  58                 for key in keys:
>  59                     oldcall[key] = calls[i][key]
>  60                 print oldcall
>  61                 calls.pop(i)
>  62                 break
>  63             else:
>  64                 print >> sys.stderr, "Error: Se va a sobreescribir
> un evento\
>  65                 no considerado en el script %s" % call['event']
>  66                 sys.exit(1)
>  67     if oldcall:
>  68         print "oldcall2"
>  69         print oldcall
>  70         for key in keys:
>  71             newcall[key] = oldcall[key]
>  72         print "newcall1"
>  73         print newcall
> ......
>  81     elif event == "CONNECT":
>  82         newcall['event'] = line.split('|')[4]
>  83         newcall['agent'] = line.split('|')[3].split('@')[0].split('/')[1]
>  84         newcall['waittime'] = line.split('|')[5]
>
>
> DEBUG
> =======
>
> DENTRO DEL BUCLE
> oldcall1
> {'waittime': '', 'callerid': '', 'calltime': '', 'agent': '', 'event':
> 'ENTERQUEUE', 'queue': '17810', 'inposition': '', 'outposition': '',
> 'date': '1283941447', 'id': '1283941434.31503'}
> oldcall2
> {'waittime': '', 'callerid': '', 'calltime': '', 'agent': '', 'event':
> 'ENTERQUEUE', 'queue': '17810', 'inposition': '', 'outposition': '',
> 'date': '1283941447', 'id': '1283941434.31503'}
> newcall1
> {'waittime': '', 'callerid': '', 'calltime': '', 'agent': '', 'event':
> 'ENTERQUEUE', 'queue': '17810', 'inposition': '', 'outposition': '',
> 'date': '1283941447', 'id': '1283941434.31503'}
> newcall2
> {'waittime': '119', 'callerid': '', 'calltime': '', 'agent': '17816',
> 'event': 'CONNECT', 'queue': '', 'inposition': '', 'outposition': '',
> 'date': '', 'id': ''}
>

newcall2 aparece mágicamente. ¿De qué sirven trazas que no se
corresponden con el código?

Esto no es una bronca, es un pretexto para sacar el tema de las
pruebas unitarias. La forma profesional de ponerle trazas a tu código
que trae otro montón de ventajas añadidas ;-)

Algunas ventajas:
 * El código de la función que falla y su test unitario es genial para
ayudarte en la lista
 * Ayuda a encontrar muchos errores sin necesidad de que te los
informe un usuario del programa.
 * Cuando encuentras un error, haces la prueba que lo reproduce y
luego garantizas que no lo vuelves a cometer.
 * Automatizas las pruebas. Hacer 700 pruebas manualmente es inhumano,
con test unitarios los puede hacer la máquina mientras duermes. Ayuda
a que puedas tocar el código sin romper cosas.
 * Pueden servir de base para test de carga o de cobertura (por poner
algún ejemplo).

Si he logrado "vendertelos" puede echarle un ojo a:
http://docs.python.org/library/unittest.html

Un saludo:

Javi
_______________________________________________
Python-es mailing list
Python-es@python.org
http://mail.python.org/mailman/listinfo/python-es
FAQ: http://python-es-faq.wikidot.com/

Responder a