Iniciar sesión

Ver la versión completa : pygame y xml



namikata
27/01/2006, 21:02
me estoy volviendo loco con el tema de xml. Conoceis alguna forma de tratar archivos xml (un DOM por ejemplo) en pygame?

he encontrado bastante sobre xml y python pero no sirve para el pygame de la gp2x.

gracias!!!

pezezin
29/01/2006, 06:42
Buff, XML es una movida de cuidado.

Lo primero es que PyGame no te va a dar ninguna facilidad para trabajar con XML, tienes que recurrir a las bibliotecas de Python. Yo hice pruebas con MiniDOM, que es relativamente sencillo. Si quieres, te explico como usarlo de manera rápida.

namikata
29/01/2006, 06:49
si por favor, seria una gran ayuda :(

he buscado algo de xml en python pero me obligaba a instalar un monton de archivos que (teniendo n cuenta que estoy empezando con python) no sabia cuales de ellos tenia que copiar ni nada, un lio vamos

yo esperaba algo como copiar un par de archivos al directorio del juego, hacer un par de imports y ala, a trabajar

toda ayuda es bienvenida por que la verdad es que estoy atascado con eso :mad:

namikata
29/01/2006, 07:35
he encontrado algo de documentacion sobre minidom y me he puesto a ello, pero no saber python complica las cosas :D

una pregunta, no sabras que archivos tengo que copiar junto con el juego a la gp2x para que tire?

Uncanny
29/01/2006, 08:04
he encontrado algo de documentacion sobre minidom y me he puesto a ello, pero no saber python complica las cosas :DHombre, antes de usar el modulo PyGame lo ideal sería que aprendieras a usar Python :D

Si quieres saber como usar XML con minidom, en los capítulos 9 y 10 de Inmersión en Python (http://almacen.gulic.org/diveintopython-5.4-es.14/toc/index.html) tienes más info.

namikata
29/01/2006, 08:10
estoy metido en todo el lio, tengo 3 pestañas abiertas una con python otra con pygame y otra con minidom :D, aprendo rapido ;), bueno, ya cargo archivos y ahora estoy urgando por lo snodos buscando la forma mas comoda de trabajar, lo que me preocupa es pasar esto a la gp2x, por 0.10€ archivos que hay que copiar junto con el juego para que funcione el minidom el la gp2x, 1 2 3 responda otra vez

:Dprograma a estas horas no es bueno :loco:

pezezin
29/01/2006, 08:11
Los archivos que tienes que copiar no sé cuales son, pero minidom es parte de la biblioteca estándar de Python, así que no deberías tener que añadir nada más. Te cuento más o menos como lo uso yo (ojo, sólo lectura de los datos, no me preguntes como modificarlos):


Lo primero es incluir la biblioteca:

from xml.dom import minidom
A continuación, hay que parsear los datos. Para ello tienes dos métodos, dependiendo de si están en una cadena o en un fichero:

datos = minidom.parse (fichero)
datos = minidom.parseString (cadena)
Ya tenemos un árbol XML llamado datos, ahora podemos extraer lo que queramos de él. Si quieres obtener los atributos de la raiz o de cualquier otro nodo, haz algo como:

atributo = datos.firstChild.attributes[nombre del atributo].value
En cambio, si quieres obtener una lista de todos los nodos con un nombre determinado, y procesar sus atributos:

lista = node.getElementsByTagName (nombre de la etiqueta)
for elemento in lista:
atributo = elemento.attributes[nombre del atributo].value
Si lo que quieres es extraer el texto contenido dentro de una etiqueta... bueno, esto es bastante más chungo. Sé que había una manera relativamente sencilla de hacerlo, pero no logro recordarla. Lo mejor que he encontrado es esto:

for nodo in lista[número de elemento].childNodes:
if nodo.nodeType == minidom.Node.TEXT_NODE:
texto = nodo.wholeText


Faltan muchas cosas, pero con eso al menos podrás cargar ficheros en XML y leer su contenido. DOM no es lo más sencillo del mundo, pero menos da una piedra. Ahora, si lo que quieres es que tu código ocupe lo menos posible...

namikata
29/01/2006, 08:17
eso lo llevo bastante bien, al fin y al cabo es un dom estandard y esa es mi especialidad xDD, estoy buscando una forma de utilizar xpath para crear colecciones de nodos y no me quedaria mas que trazar el programa para ver que archivos de la bibliioteca usa y copiarlos junto al juego pero es que no me apetece nada que pereza xDDD, de momento voy a ver si me tiran ben todos los nodos, y dejare el trazar los archivos para mas adelante, a ver si puedo quitarme todo el xml de encima esta noche y asi empiezo ya a programar el menu

muchas gracias, la verdad es que tu ayuda me a venido de perlas por que estaba que me tiraba de los pelos, y no habia leido nada del minidom, creo que mas que nada porque todavia no habia profundizado en xml con python

bueno, a seguir, que ilusion ya funciona xD

namikata
29/01/2006, 09:03
en el dom al que estoy acostumbrado los nodos tienen una propiedad nodeValue con el valor del nodo (depende de la version del dom y del la libreria), en minidom tienen tambien la propiedad pero no devuelve el valor, supongo que por que te da algo mas de control sobre los nodos hijos

en el caso que me concierne, si tengo un nodo llamado version, para acceder a su contenido hago


xmlversion.childNodes[0].data

que es algo similar a lo que me decias tu, la verdad es que no es una buena forma de acceder a un nodo por lo del [0] y ademas sin comprobar si es de texto o no etc, pero en mi caso, que el archivo xml lo creo yo y tengo muy clara su estructura y que no va a cambiar pues me funciona bastante bien xD

lo que si me ha gustado del minidom es que por defecto, me carga el documento en unicode, cosa que no se puede decir de las librerias msxml de microsoft que dan unos dolores de cabeza tremendos

me esta viniendo genial tu ayuda gracias

deberia dormir pero hace tiempo que no me divertia tanto xD

seguire contando por aqui como va el tema, como no hay mucha informacion nunca viene mal un hilo con informacion para los novatillos como yo :D

namikata
29/01/2006, 09:13
seguimos con las cosillas, pensaba que la funcion .getElementById no funcionaba porque no me devolvia nada y habia leido que cascaba, pero esta arreglada y la razon por la que no devuelve nada es porque no hay nada qe le diga a minidom que el atributo "id" es el id del nodo, yo pensaba que lo daba por supuesto, joe que se llaman igual xDD

he estado buscando el metodo setIdAttribute() pero no aparace en minidom, al parecer es un metodo del Dom 3, asi que solucion queda? pues añadir a nuestro xml un DTD (como los odio) en el que se indique el atributo que funciona como id y al cargarlo generara un cache de ids, en fin habra que seguir trasteandoa ver si se puede hacer de otra forma, no me gustaria añadir un DTD al documento, seria "ensuciarlo" :demonio:

namikata
29/01/2006, 09:26
arreglado, al mirar el document element he encontrado el metodo setIdAttribute pero fallaba por que el document element no es un nodo particular del documento, solucion, cargar una lista con los nodos del documento, recorrerla y si el nodo tiene un atributo id, en ese elemento asignar el atributo que queremos usar como id, por ejemplo:


#cargamos la lista de todos los nodos
listaNodos = dom1.getElementsByTagName("*")

#recorremos y activamos el id
for nodo in listaNodos:
if nodo.hasAttribute("id"):
nodo.setIdAttribute("id")

ahora podemos buscar un nodo en concreto directamente utilizando el valor de su atributo id (que debe ser unico en el documento) por ejemplo de la siguiente forma:


dom.getElementById("201")

que nos devuelve el nodo que tiene un atributo id cuyo valor es 201


ni que decir tiene que esta solucion se puede mejorar, si el documento es muy grande, convendria crearle un DTD para evitar recorrer todos los nodos del documento, en mi caso como el documento es pequeño y odio los DTDs pues se va a quedar asi

si tuviesemos acceso a xpath, podriamos utilizar


//*[@id]

para filtrar la lista de nodos, asi conseguiriamos una lista mas pequeña (solo los nodos que tienen id) que se cargaria mas rapido y ademas no tendriamos que preguntar si tiene aributo id

bueno, esto va por buen camino :D

namikata
29/01/2006, 10:07
bueno, pues certifico que lo de de antes funciona correctamente, como prueba, la salida de depuracion del juego:


contacto: namikataATgmailDOTcom
version: 0.0.1
directorioidiomas: idioma
directorioimagenes: datos
directoriosonidos: datos
idiomausuario: es-ES
disparo1: 12
disparo2: 14
rotarI: 10
rotarD: 11
cambiararma: 15
cambiarhabilidad: 13
usarhabilidad: 18
fijar: 9
menu: 8
Configuracion cargada con exito
Iniciando la aplicacion
Pygame iniciado correctamente
Fuentes disponibles
Sonido disponible
Comienzo del bucle principal
Creando pantalla
Cargando fuentes
Cargando graficos
Cargando sonidos
Cargando idioma
Hemos entrado en el menu principal
El usuario quiere salir
Salimos del menu principal, proximo estado: -1
Eliminando graficos
Eliminando sonidos
Fin del bucle principal
Finalizando la aplicacion

pezezin
29/01/2006, 22:27
Si lo que quieres es crear una lista con todos los nodos que tengan un atributo determinado, puedes usar la comprensión de listas:


filtrada = [x for x in lista if x.hasAttribute("nombre del atributo")]

También se podría hacer con "filter", pero no recuerdo como se usa, y de todas maneras la comprensión es más potente. Si lo que quieres es filtrar sólo aquellos en los que el atributo tenga un valor determinado, entonces:


filtrada = [x for x in lista if x.attributes["nombre del atributo"].value == "valor"]

Ojo, esto sólo vale si estás seguro de que todos los nodos de lista tienen el atributo, si hay alguno que no lo tenga, producirá una excepción. Para evitar eso, puedes usar este otro código, algo más lento pero 100% seguro:


filtrada = [x for x in lista if (x.hasAttribute("nombre del atributo") and x.attributes["nombre del atributo"].value == "valor")]

namikata
30/01/2006, 05:06
el resultado final es similar pero estaba pensando en ahorrar recursos, utilizando funciones propias del dom como por ejemplo


dom.selectNodes("//*[@nombreAtributo]")

consigo directamente una lista filtrada sin tener que cargar inicialmente todos los nodos y luego recorrer la lista de nuevo, ademas puedo refinar el filtro para hacerlo mas complejo


dom.selectNodes("//*[@id>15]")
dom.selectNodes("//*[@id]/subnodo/*[name(.)='textos']")

esto evita operaciones innecesarias, sin e,bargo en el juego si voy a necesitar los filtros que me has indicado, y por cierto gracias porque no sabia hacerlo :D poco a poco me vas a ir solucionando el juego (no reparto beneficios, lo aviso por adelantado :lol: ) por que tendre unos 4 grupos permanentes y los reorganizare en listas para optimizar la velocidad todo lo que pueda, ahi me van a venir de lujo los filtros que me has puesto para procesar los filtros

buff, se esta complicando mucho esto eh? que a veces se me va la cabeza, yo no se como puedo estar escribiendo tanto codigo y de momento lo unico que se ve es una pantalla verde :D

en fin, volviendo al tema inicial del post, he revisado el fucionamiento del stick, y la verdad es que utilizar la pulsacion no es una buena idea, se pulsa sin querer como aprietes un poco fuerte y muchas veces no tienes una respuesta fisica si el stick esta denmasiado inclinado, no te enteras de que ya lo has pulsado, asi que haciendo caso a mis queridos comentaristas, utilizare la combinacion de [disparo1 | disparo2] + cambiar habilidad que ademas parece como mas rapida y logica, un boton menos que usamos :D

voy a colgar el documento original (tiene mucho tiempo y esta desfasado pero el control del juego es practicamente identico) del juego para que os podais hacer una idea de como funciona y esas cosas, la cuestion es que no lo vea otra persona y decida hacrlo por su cuenta :D ... bueno, la verdad es que lo haria aunque lo hiciese otra persona :D

namikata
30/01/2006, 05:25
bueno, pues aqui esta el documento del juego, he puesto la version opendocument y la version office por si acaso, la historia y el manejo estan totalmente desfasadas, y el modo de juego necesita una revision que supongo hare esta noche

si allguien quiere utilizar cualquier informacion de la que aparece en el documento es libre de hacerlo, solo pido que no se cobre por nada de lo que yo doy gratis ;)

una vez que los temas legales estan zanjados aqui estan los documentos (la historia es cutre absurda, lo se, que nadie se ria eh? :mad:)

por cierto, a la version opendocument le he tenido que añadir la extension .txt para que me dejase subirla, solo hay que quitarsela y ya esta :D

(si alguien se ofrece con una historia mejor (facil) es bienvenido)

pezezin
30/01/2006, 05:52
Yo debería estar estudiando el modelo relacional, que mañana tengo un examen de bases de datos, pero bueno, voy a echarle un vistazo :D

namikata
30/01/2006, 07:01
noooo!!!

esudia que luego me remuerde la conciencia :P

yo estoy modificando el documento para adaptarlo a la situacion actual, ademas creo que tanto la historia como el manejo del juego, y un poco la dinamica de juego necesitan unos retoques para adaptarlo a la gp2x asi que me llevara un rato

tu a estudiar que si cateas luego es peor :D

namikata
31/01/2006, 00:56
bueno, una vez terminado el documento que ha cambiado bastante (metodos de juego, coste y comportamiento de armas y habilidades, etc.) me he puesto a terminar de cargar el xml necesario hasta ahora, datos de cofiguracion y el idioma necesario para el menu, poco mas, asi que una vez terminado y comproado que funciona, cuelgo aqui el codigo en el que esta hecho lo de la carga de xml y eso

funciona bien en linux, supongo que con pygame en windows tendria que tirar bien, en la gp2x no porque todavia no he sacado las librerias xml necesarias, y son unas cuantas :D

bueno, y a no ser que alguien ponga algunas cosas mas aqui, yo por mi parte doy por finalizado este post sobre pygame y xml

ala, a cascarla!!!

[wei4] [wei2] [wei6] [wei6] [wei6] [wei2] [wei4]

Editado: al final se me olvidaba el adjunto :P

pezezin
31/01/2006, 05:54
Bueno, al final el examen ha salido bien. He estado mirando el código, y se me ocurren varias cosas:


Separa el código en distintos ficheros, uno por clase o como lo veas.
Ten cuidado con las variables globales, pueden dar muchos problemas. Además, si necesitas que una variable sea global y única, es mejor un singleton.
"Fuente" es un anglicismo terrible, queda mejor "tipo de letra" ;)
Veo que en el XML, a cada tipo de etiqueta le asignas un id. A menos que una misma etiqueta pueda aparecer varias veces, es redundante.
No declaras la codificación usada.
Y seguro que algo más que se me olvida...


En fin, cuando quieras me mandas lo que vayas haciendo y lo miro ;)

namikata
31/01/2006, 06:22
me alegro por tu examen, enhorabuena y gracias por los comentarios, veamos...




Separa el código en distintos ficheros, uno por clase o como lo veas.



por supuesto, ese es un tema pendiente, cuando las empece a crrear tuve algunos problemas con los ambitos de ahi que esten todas juntas y haya tantos globales :P la implementacion se puede mejorar un monton




Ten cuidado con las variables globales, pueden dar muchos problemas. Además, si necesitas que una variable sea global y única, es mejor un singleton.



sip, al separar las clases en ficheros revisare todas las variables y reoranizare el codigo para que este bien limpio y se lea adecuadamente, me vendra bien una revision ;) sin compromiso




"Fuente" es un anglicismo terrible, queda mejor "tipo de letra" ;)



mmm deformacion profesional, lo apunto y lo cambiare en los textos traducidos, dento del codigo se tendra que quedar como fuente que sino me lio :)




Veo que en el XML, a cada tipo de etiqueta le asignas un id. A menos que una misma etiqueta pueda aparecer varias veces, es redundante.



tienes toda la razon, pero tengo dudas, a estas alturas todavia no estoy seguro de que no se vayan a repetir nodos, creo que en las traducciones de los textos de los diferentes modos de juego no me quedara mas remedio que repetir bastantes, sino, seria como tu dices, quitar los ids y cargar por el nombre

te agradezco mucho el tiempo que te tomas para revisar mi codigo y mas teniendo en cuenta que es de un novato :P

a ver si para cuando empiece a mostrarnavecitas por la pantala, parece algo mas serio :)

gracias de nuevo

pezezin
31/01/2006, 07:53
He estado pensando que para los ficheros de traducción quizás no haga falta un XML. Podrías usar la biblioteca gettext, o si no quieres cargarlo mucho, un formato del tipo:


[identificador] cadena

Y luego a la hora de cargarlo, leerlo línea por línea, extraer los campos (fácil con una expresión regular) y meterlo en un diccionario. Lo bueno de XML es que el parser ya está hecho, lo malo... que gasta bastante memoria.

namikata
31/01/2006, 21:08
jo, ultimamente me da cosa por que de cada 3 consejos que me das, te digo que 2 no y uno si, espero que no te molestes :(

lo del gettext ni lo sabia, la razon principal por la que uso xml para las traducciones (y para la configuracion) es que voy a validar los 2 archivos (habra mas, por que la definicion de las armas y las pantallas tenia pensado hacerlas en xml tambien) a la hora de cargar contra unos xsd que estoy haciendo en xmlspy, de esa forma puedo evitar realizar un monton de comprobaciones y errores durante la ejecucion, si el archivo carga y es valido, puedo estar seguro de encontrar lo que busco

esi si, si hay alguna forma de hacer lo mismo pero sin consumir tantos recursos n i ser tan lento, yo quiero saberlo!! por que entre que esto tira contra python, si encima le cargo con xml y alguna cosilla mas, ni usando el segundo procesador va a ser suficiente :D
8por lo menos el uso de xml se realiza solo durante la carga, asi que la ejecucion no se ve tan afectada, bueno si, en memoria, pero tengo que optimizar todavia el uso de variables y objetos

hay alguna forma de monitorizar la memoria de la gp2x? me vendria muy bien para saber como la estoy cargando con el programa, tu imagina que con lo que tengo ya (nada) estoy ocupando 20 megas de ram :D

bueno, gracias de nuevo por tu ayuda, estoy aprendiendo mucho, aunque la verdad es que voy leeeeeeeento, y solo programo un poco al dia (y a veces ni eso :\)

bueno, a ver si hoy separo todas las clases, reviso las grobales como me dijiste, y me da tiempo a hacer algo del menu, que tengo ganas de empezar a ver algo :)

pezezin
31/01/2006, 21:29
Pues para ver el consumo de memoria... supongo que lo mejor sería tener el conector EXT->serie, y ejecutar top en una terminal. Si tuviera un cable de esos te diría que tal van ;) Lo XSD no tengo ni idea de como va, pero si te ahorra trabajo... Lo bueno del XML es eso, que hay mogollón de bibliotecas ya hechas.

Por otro lado, he estado reescribiendo la clase cIdioma, reestructurando el XML en secciones con diferentes mensajes, y cargándolo en un diccionario. El resultado es más claro (o eso me parece). Adjunto el código y un XML de prueba ;)

namikata
31/01/2006, 22:54
:rever: :rever: :rever: :rever: :rever:

vaya paliza me acabas de dar xD

muy buenos los dos archivos, asi habrian tenido que ser desde el principio
tengo que tomarme esto con mas calma y pensarlo mejor porque todo el codigo deberia parecerse mas a lo que me has pasado :)

en fin, a ver si esta noche rehago todo el codigo siguiendo tus ejemplos y ya de paso les pongo el xsd para validar

gracias!!!

pezezin
31/01/2006, 23:30
Me alegra que te gusten :D

Aunque un detalle, en el código que te he pasado uso cosas como attributes["id"].nodeValue. Esto es para asegurarme de que el atributo "id" existe, porque de no ser así lanza una excepción. Supongo que si el XSD lo comprueba, ya no será necesario y podrás usar getAttribute("id"), que es más sencillo.

PD: puesto que en este hilo sólo hablamos nosotros dos, podríamos hacerlo por mensajes privados o e-mail ;)