Autor Tema: Función recursiva que devuelve algo inesperado

0 Usuarios y 1 Visitante están viendo este tema.

19 Marzo, 2015, 02:26 am
Respuesta #20

energy

  • Experto
  • Mensajes: 561
  • Karma: +0/-0
  • Sexo: Masculino
m=[]
def posiciones(linea,palabra1,palabra2,inic):
    l1=linea.find(palabra1,inic)
    l2=linea.find(palabra2,inic)
       
    if l1==-1 or l2==-1:
        return m
    else:
        m.append(linea[l1:l2+len(palabra2)])
        inic=l2+len(palabra2)-1
        return posiciones(linea,palabra1,palabra2,inic)
def limpia(lista):
    nuevalista=[]
    for i in m:
        nuevalista.append(clean(i))
    return nuevalista
def encuentrainiciocopiar(lineas,etiqueta1,etiqueta2):
    lineaquemiro=1
    x=0
    for linea in lineas:
        if linea.find(etiqueta1)!=-1:
            x=lineaquemiro
        lineaquemiro+=1
    y=0
    lineaquemiro2=1
    for linea in lineas:
        if linea.find(etiqueta2)!=-1:
            y=lineaquemiro2
        lineaquemiro2+=1
    return x,y
def enlistar(url,etiqueta1,etiqueta2,etiqueta3,etiqueta4):
    texto=urllib.urlopen(url)
    lineas=texto.readlines()
    i,j=encuentrainiciocopiar(lineas,etiqueta1,etiqueta2)
    print i
    for linea in lineas:   
        while lineas[linea]>=i and lineas[linea]<=j:
            posiciones(linea,etiqueta3,etiqueta4,0)
    return m

Mi problema ahora es que quiero que mire de la linea i hasta la j pero como me refiero a la posicion de la línea, porque me da que es un string en vez de un entero

19 Marzo, 2015, 02:36 am
Respuesta #21

luis

  • Aprendiz
  • Mensajes: 304
  • Karma: +1/-0
  • Sexo: Masculino
desde mi punto de vista, esa variable global es un problema. ¿qué te aporta?

si en ella quieres almacenar la salida de la función posiciones, entonces es claramente una variable local a posiciones.

19 Marzo, 2015, 02:38 am
Respuesta #22

energy

  • Experto
  • Mensajes: 561
  • Karma: +0/-0
  • Sexo: Masculino
Mm pero si yo le quito el if o el while funciona perfectamente, lo que quiero ver es como me refiero a el número de línea dentro de esa lista (y ademas si la meto como tu dices la m dentro de la fncion al ser recursiva se quedará la lista vacia, por eso la puse como variable global.)

19 Marzo, 2015, 03:00 am
Respuesta #23

luis

  • Aprendiz
  • Mensajes: 304
  • Karma: +1/-0
  • Sexo: Masculino

cada vez que usas una variable, deberías saber para qué la usas sin necesidad de depender de todo el código (por supuesto que hay excepciones a esa regla general; pero creo que no hay ninguna si el código tiene menos de mil líneas y usa menos de un giga de memoria)

creo que intentas codificar sin entender la relación entre el código y el problema, y creo que el uso de objetos bien controlados, como las variables locales, son una ayuda fundamental en ese intento. por ejemplo, limpia tiene un argumento que no se usa; si funciona bien, entonces la función está mal escrita.

más aún, si una función recursiva devuelve una variable global tiendo a pensar que está mal escrita, o que anda de casualidad. y más aún; estoy seguro que esa variable global es innecesaria.

no tengo problema en intentar ayudarte, pero...  debo insistir, procura en un primer intento colocar la variable m como local a posiciones; o mejor aún, intenta describir qué computa posiciones.

19 Marzo, 2015, 02:27 pm
Respuesta #24

energy

  • Experto
  • Mensajes: 561
  • Karma: +0/-0
  • Sexo: Masculino
Si sé, que sería mejor devolver otra cosa que no fuera la variable global, y eso quiero en cierta medida, pero no se donde incluirla para que en la función recursiva no me vacie la lista cada vez que es llamada la función. Si me ayudaras lo vería.

Y con respecto a lo otro, si pongo:

if linea>=i and linea<=j:
esa condición parece ser que nunca se me cumple, estoy refiriendome bien?, es decir en un bucle for que recorra una lista de lista tal que: for linea in lineas, linea va tomando valores numericos o no me puedo referir asi?

19 Marzo, 2015, 07:15 pm
Respuesta #25

luis

  • Aprendiz
  • Mensajes: 304
  • Karma: +1/-0
  • Sexo: Masculino

no se si pueda ayudarte, pero para intentarlo necesito ver de a una las funciones. y repito lo que te decía

intenta describir qué computa posiciones.

me temo que eso aún no lo tienes claro.

saludos

luis

19 Marzo, 2015, 08:31 pm
Respuesta #26

energy

  • Experto
  • Mensajes: 561
  • Karma: +0/-0
  • Sexo: Masculino
Vale, ya conseguí meterla como variable local, contar que lineas, está todo eso arreglado, es una ventaja y avancé mucho en mi práctica, pero ahora el problema es este:

Posiciones 2 lo que hace es que dada una linea, una etiqueta inicial y otra final, una posición inicial y una lista, mete lo que haya entre esas dos etiquetas (todo a partir del inicio, es decir, busca a partir de la posición inicial que queremos) en una lista, en nuestro caso vacia.

La duda realmente es, que ya me funcionan todas las anteriores:

def paginaweb(url,lista):
.......x1=enlistar(url,'<thead>','</thead>','<th>','</th>',[])
.......texto=urllib.urlopen(url)
.......lineas=texto.readlines()
.......i,j=encuentrainiciocopiar(lineas,'<tbody>','</tbody>')
.......cuentl=0
.......for linea in lineas:
..........cuentl+=1
..........if cuentl>=i and cuentl<=j:
..........x,y=encuentrainiciocopiar2(lineas,'<tr>','</tr>',i)
..........enlistar(url,'<tr>','</tr>','<td>','</td>',[]):

la duda que tengo es, mi penultima función que devolvería tantas listas que serían iguales a tantas lineas como quisieramos que tuviera nuestro archivo de texto. Entonces la primera linea esta clara, busca etiquetas thead y copia lo que hay entre las th, luego abro la web, leo las lineas, miro en que posiciones estan los tbody, mi contador de linea para saber en que linea estoy empieza en 0, y el problema viene en el bucle for, si estamos entre las lineas que estan los tbody ok queremos copiar solo entre esas, pero además tengo que poner otra condición que sería que estuviesemos entre los tr, pero como por cada dos tr van dos posiciones hice una función que devolviese el número de linea que estan, en este caso los tr a partir de una posición inicial que ahora queremos que irá variando. Entonces quiero copiar lo que hay entre esos dos tr de etiquetas td me parece que son, el problema es si debería anidar otro bucle o como se pondrían las condiciones.

Un saludo!

19 Marzo, 2015, 10:58 pm
Respuesta #27

luis

  • Aprendiz
  • Mensajes: 304
  • Karma: +1/-0
  • Sexo: Masculino
Posiciones 2 lo que hace es que dada una linea, una etiqueta inicial y otra final, una posición inicial y una lista, mete lo que haya entre esas dos etiquetas (todo a partir del inicio, es decir, busca a partir de la posición inicial que queremos) en una lista, en nuestro caso vacia.

ok, ahora para entender un poco mejor. en un post pusiste que con la entrada

Código: [Seleccionar]
posiciones('<th>Tipo</th><th>Localizacion</th><th>Uso</th><th>Ministerio</th><th>Superficie</th>','<th>','</th>',0)
tenía que devolver
Código: [Seleccionar]
['<th>Tipo</th>',
 '<th>Localizacion</th>',
 '<th>Uso</th>',
 '<th>Ministerio</th>',
 '<th>Superficie</th>']

¿por qué no devuelve
Código: [Seleccionar]
['<th>Tipo</th>']?

y en otro lugar, dijiste una cosa bien distinta

lo suyo sería que en m me metiera
Código: [Seleccionar]
m=['<th>Tipo</th>,<th>Localizacion</th>,<th>Uso</th>,<th>Ministerio</th>,<th>Superficie</th>']

¿qué es lo que debe devolver?: ¿un string o una lista de strings?

por otra parte, qué esperas que devuelva la siguiente entrada:

Código: [Seleccionar]
posiciones('</th><th>Localizacion</th>','<th>','</th>',0)
¿o acaso todas las entradas tienen igual cantidad de pal1 que de pal2?

¿y con la siguiente entrada?

Código: [Seleccionar]
posiciones('<th><th>A</th><th>B</th>C</th>','<th>','</th>',0)
¿o acaso no hay anidamientos de etiquetas?

carezco de la imaginación suficiente para entender adecuadamente el problema en la forma en que lo has planteado hasta ahora. si puedo ayudarte, quisiera ir de a una función por vez, y todavía no entiendo esta de la que te pregunto.

saludos

luis