Foros del Web » Programando para Internet » Python »

problema script sencillo

Estas en el tema de problema script sencillo en el foro de Python en Foros del Web. Estoy aprendiendo python y he echo un script sencillo para calcular los números amigos (pareja de números la suma de los divisores propios de uno ...
  #1 (permalink)  
Antiguo 19/02/2011, 06:35
 
Fecha de Ingreso: febrero-2011
Mensajes: 6
Antigüedad: 13 años, 9 meses
Puntos: 0
Pregunta problema script sencillo

Estoy aprendiendo python y he echo un script sencillo para calcular los números amigos (pareja de números la suma de los divisores propios de uno es igual al otro numero). Se que estos números tienen una formula para calcularlos pero lo he hecho manual para aprender bucles, ... Bueno no me lio el scrit hace tres cosas:

- Mira si el número esta en num_ya y sino calcula números amigos entre los dos que lo damos y los escribe en numeros (lo hace bien)
- Para controlar el tiempo que tarda y en caso de error, ... saber por donde va aunque sea mas o menos, cada 100 números revisados escribe el número revisado en ese momento y la hora en num_control (lo hace bien)
- Cuando calcula suma de divisores de un posible miembro de números amigos y el resultado es imposible que de la otra parte de la pareja lo escribe en num_ya para evitar calculos inútiles más adelante (lo hace bien)

Todo lo que quería lo hace bien pero me lanza al final por pantalla los números que ha encontrado para escribir en num_ya pero además ordenados no como los ha escrito. No se porque hace esto me gustaría que no lo mostrara. Creía que era por no poner un return a la función pero he probado y también lo hace. No hay nada en el código que le diga que me muestre por pantalla excepto el print y menos que se guarde nada en memoria y luego lo ordene (que yo sepa).

ejemplo: ./numeros_amigos.py 221 4 (empieza a calcular en 4 hasta 220)

Código Python:
Ver original
  1. #!/usr/bin/env python
  2.  
  3. import sys
  4. import time
  5. import os
  6.  
  7.  
  8. def grep_w(arch, busq):
  9.     """Realiza grep -w de busq (cadena) en arch (archivo) y devuelve si
  10.    lo encuentra"""
  11.     s_busq = str(busq)
  12.     return os.system("grep -w " + s_busq  + " " + arch)
  13.  
  14. def escribir_cont(arch, que):
  15.     """Escribe que (cadena) al final de arch (archivo)"""
  16.     with open(arch, "a") as fil:
  17.         fil.write(que)
  18.  
  19. def suma_div(num):
  20.     """Suma todos los divisores propios de num y devuelve el resultado"""
  21.     suma = 0
  22.     for part in range(1, num):
  23.         resto = num % part  #Es un tanto porciento
  24.         if resto == 0:
  25.             suma += part
  26.     return suma
  27.  
  28. def num_amigos():
  29.     """Realiza las operaciones para encontrar los numeros amigos y lo guarda en
  30.    numeros. Tambien crea num_control cada 100 comprobaciones y num_ya con los
  31.    numeros no comprobados que no podrian ser amigos"""
  32.     n_final = int(sys.argv[1]) #Recoge primer argumento
  33.     n_ini = int(sys.argv[2]) #Recoge segundo argumento
  34.     contador = 1
  35.     for i in range(n_ini, n_final):
  36.         if grep_w("num_ya", i) == 256: #Sino lo encuentra
  37.             sumadiv = suma_div(i) #Suma todos los divisores
  38.         pareja = sumadiv  #Tenemos el otro numero a comprobar
  39.         if i < pareja: #Si es menor porque sino ya se ha comprobado
  40.             if grep_w("num_ya", i) == 256: #Sino lo encuentra
  41.                 sumadiv = suma_div(pareja) #Suma todos los divisores
  42.                 comparar = sumadiv #Obtenemos lo que debería ser el primero (i)
  43.                 if i == comparar: # Si cumple son amigos
  44.                     escribir_cont("numeros", str(i) + " , " + str(pareja)) #Escribe en numeros la pareja
  45.                 elif i > comparar: #Si cumple pareja ya no puede ser y luego no se comprueba
  46.                     escribir_cont("num_ya", pareja) #Escribe pareja
  47.         intermedio = 100 * contador + n_ini #Para comprobar cuando pasan 100 comprobaciones
  48.         if i == intermedio: #Si cumple han pasado 100
  49.             contador += 1 #Aumenta el contador
  50.             hora = time.strftime("%H:%M:%S") #Hora actual
  51.             escribir_cont("num_control", str(intermedio) + " a la " + str(hora)) #Escribe numero actual y la hora
  52.     mens = n_final - 1
  53.     print "Se han verificado los numeros amigos hasta el " + str(mens) #Muestra que ha acabado
  54.  
  55.  
  56. num_amigos()

Última edición por neburel; 19/02/2011 a las 10:28
  #2 (permalink)  
Antiguo 19/02/2011, 11:16
AlvaroG
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: problema script sencillo

¿Quién es "sumadiv" en caso de que el programa no ingrese al bloque if que comprueba la salida de grep?

Los números que ves en la pantalla son parte de la salida del comando ejecutado por os.system, es decir la salida de grep.


Saludos.
  #3 (permalink)  
Antiguo 21/02/2011, 08:11
 
Fecha de Ingreso: febrero-2011
Mensajes: 6
Antigüedad: 13 años, 9 meses
Puntos: 0
Respuesta: problema script sencillo

Muchas gracias el problema al fin esta solucionado. El script tenia un par de fallos de identación para que funcione correcto que cometí al comentarlo todo para que fuera mas fácil de leer pero para el caso ya valía. Ahora me surgen dos duditas a ver si alguién me las puede resolver:
- He usado grep porque quería una busqueda exacta (-w) sino en python el grep normal es muy facil con un simple for. Probé antes con re.search() pero no encontré una regular expresión que me lo hiciera. ej: encontre que me encontrara "es" y no "esta" "es." ... pero cuando esta al principio de la línea o al final de ella no lo encontraba. Como sería?
- Otra cosa es la depuración para solucionar problemas como el anterior. En bash con -x te muestra todo ej: i=2, 2<5, ... y ves por donde anda. Probé con pdb con python -m pdb script.py
y el script anterior después de darle a c me mostró el resultado que me daba nada más. Supongo que seré yo, algún sitio que lo expliquen para tontos porque he encontrado muy poca cosa.

Gracias anticipadas, Saludos
  #4 (permalink)  
Antiguo 21/02/2011, 21:04
AlvaroG
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: problema script sencillo

Bueno, en primer lugar respecto a grep, según el manual la opción -w exige que la concordancia sea con "palabras completas", tomando como caracteres que forman una palabra a las letras, los números y el guión bajo.
Sabiendo esto, una expresión regular posible sería
Código:
[^a-z0-9_]es[^a-z0-9_]
No sé si exista un modificador específico para lograr este efecto, pero la expresión regular anterior debería funcionar igual que
Código:
grep -w es
Con respecto al depurador, el comando c es para continuar hasta el siguiente breakpoint, por lo que es normal que haya ejecutado el programa hasta el final si no tenías ninguno. Usa s para ejecutar la siguiente línea de código (entrando en llamadas a funciones) o n para ejecutar la siguiente línea del archivo actual (sin entrar en llamadas a funciones)


Saludos.
  #5 (permalink)  
Antiguo 22/02/2011, 05:35
 
Fecha de Ingreso: febrero-2011
Mensajes: 6
Antigüedad: 13 años, 9 meses
Puntos: 0
Respuesta: problema script sencillo

Gracias por responder otra vez ;). Lo del depurador lo probaré, en cuanto a la regular expresión no me funciona. Yo había probado \W que viene a ser lo mismo pero también mayúsculas [^a-zA-Z0-9_]. Pero mira te pongo un ejemplo de un archivo que he echo para hacer pruebas:

esto como
claro es así
es
es
es
es

La tercera línea no tiene espacios ni al principio ni al final, la cuarta no lleva espacios al final y si uno al principio, la quinta no tiene al principio y si uno al final y la sexta uno a cada lado. Con esto los únicos positivos son: la 2, 4 y 6

Saludos
  #6 (permalink)  
Antiguo 22/02/2011, 17:16
AlvaroG
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: problema script sencillo

El problema es que olvidé considerar el caso en el que lo buscado esté al principio o al final de la línea. (además de haber olvidado \W )

La expresión falla porque busca específicamente por un caracter que no sea una letra, un número o un guión.
Ya que existe \W y me había olvidado, me puse a buscar otros modificadores para hacer lo mismo, y encontré que el que buscás es \b
Código:
\bes\b
debería funcionar perfectamente.


saludos.
  #7 (permalink)  
Antiguo 25/02/2011, 02:01
 
Fecha de Ingreso: febrero-2011
Mensajes: 6
Antigüedad: 13 años, 9 meses
Puntos: 0
Respuesta: problema script sencillo

Asi lo entiendo yo y lo he leído. pero no se que me pasa cogiendo el ejemplo de archivo anterior que lo cree para hacer pruebas he creado el siguiente script y no entiendo el motivo no da positiva ninguna linea
Código Python:
Ver original
  1. import re
  2.  
  3. def buscar(que, arch):
  4.     """Busca que (cadena) en arch (archivo)"""
  5.     with open(arch, "r") as fil:
  6.         for line in fil:
  7.             print re.search('\b' + que + '\b', line)
  8.  
  9. buscar("es", "prueba")
En cambio con otras combinaciones me da resultados parciales como te comente en mi anterior respuesta.
  #8 (permalink)  
Antiguo 25/02/2011, 08:56
AlvaroG
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: problema script sencillo

haciendo algunas pruebas me di cuenta de que el problema está en que python interpreta el \b como una secuencia de escape, para evitar eso agrega una r a cada '\b' (esto hace que el intérprete tome la cadena de forma literal)
Código Python:
Ver original
  1. re.search(r"\b" + que + r"\b", line)
Saludos.
  #9 (permalink)  
Antiguo 25/02/2011, 13:04
 
Fecha de Ingreso: febrero-2011
Mensajes: 6
Antigüedad: 13 años, 9 meses
Puntos: 0
Respuesta: problema script sencillo

Te agradezco tus respuestas rápidas pero tu código no me devuelve ningún positivo tampoco. No se ya he probado de todo un poco :(
  #10 (permalink)  
Antiguo 25/02/2011, 18:45
 
Fecha de Ingreso: febrero-2011
Mensajes: 6
Antigüedad: 13 años, 9 meses
Puntos: 0
Respuesta: problema script sencillo

Perdón muchas gracias por la respuesta si que funcionaba pero tenía un problema en mi pc.

Saludos

Etiquetas: sencillo
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 11:04.