[Python] Hilo general

CiudadanoEj

Buenas, estoy haciendo una practica de la uni en la que he de abrir un archivo .csv y sinceramente he buscado pero no encuentro el error que me da con la función open(no puedo usar pandas ni otros módulos). Me dice lo siguiente:

f = open(sys.argv[1])
TypeError: open() takes 0 positional arguments but 1 was given

Y aqui el codigo:

spoiler

he probado tambien este otro que he visto por internet y nada

spoiler
1 respuesta
Fyn4r

#1381 Estás intentando (supongo) utilizar la función open del "sistema" tras definir tu propia función con ese mismo nombre, la cual no recibe parámetros, de ahí el error.

2 1 respuesta
CiudadanoEj

#1382 dios era eso me gracias (me siento estupido no conseguia verlo XD)

Juker

Hola buenas, acabo de empezar a programar en Python por el trabajo, soy muy nuevo con esto xD y quería pediros ayuda con un programa:
Necesito convertir archivos en PDF a HTML y debido a que es un ordenador del trabajo, solo tengo autorización para usar librerías como pdfminer o PYPDF y la verdad que no las he usado en la vida... Tengo el siguiente código, pero por alguna razón que desconozco no me funciona:

spoiler

Perdón por las molestias, pero llevo ya bastante tiempo intentando hacer esto. Gracias.

1 respuesta
Wei-Yu

#1384 qué tipo de error te da? Debería indicarte la línea donde falla y si pegas aquí el error al menos debería poder alguien ayudarte a entenderlo.

Con respecto al tema de permisos imagino que ya lo habrás mirado y remirado, pero si tienes permisos para instalar algo con pypi (el gestor de paquetes de python) tendrías que poder instalarte cualquier otra lib que pudieras necesitar.

Cuando pegues código intenta conservar el estilo, en especial en python en el que la indentación declara los bloques de código. Piensa que en ese if-else no sabes a primera vista qué entra dentro del else. Se intuye, claro, pero hace más difícil entender el problema que pudieras tener.

1 respuesta
Juker

#1385 El tema está en que no me da ningún error, es solo que no me muetra el resultado en html, de hecho no me muestra nada. El "resultado" que obtengo en jupyter notebook es: <_io.stringIO object at 0x00000021........>

No, los permisos no me los pueden dar para otras librerías. Ya lo intenté pero es imposible.

Perdón por lo del formato, creí que lo había copiado bien.

1 respuesta
Wei-Yu

#1386 puede ser que te falte reasignar la variable de output_string? entiendo que si la metes en el extract_text_to_fp es porque te la rellena por referencia (no recuerdo bien cómo tira python con esas cosas)

Si la función de extract_text_to_fp() devuelve lo que necesitas deberías hacer que la var de output se rellene con eso. Ahora mismo lo que estás imprimiendo es ""el nombre"" del objeto que tienes ahí, que será el stringIO() supongo.

3 meses después
B

Hola, estoy hasta los cojones de Python, pero me han pasado esto. No me lo he leído pero puede que a alguien le resulte interesante

https://github.com/JoseDeFreitas/wtfpython-es

1 comentario moderado
Fyn4r

Por favor, pon el original, no una traducción en la que se puede leer

Puede que ya hallas experimentado

https://github.com/satwikkansal/wtfpython

1 respuesta
B

#1390 joé, ya he dicho que me lo han pasado y que ni lo he leído, pero sí "hallas" jajajaj

1 respuesta
Fyn4r

#1391 Desu te echaría la bronca por pasar recursos que no hayas ESTUDIADO y ENTENDIDO

1 1 respuesta
B

#1392 está liado con lo nuevo kanye, además no se pasa por aquí

Vain92

Buenas.

Voy a hacer una pregunta mega novata, pero estoy teniendo problemas con esto.

Llevo una semanita con python de manera autodidacta y imponiéndome pequeños retos para ir practicando, y ahora estoy haciendo un programa que añade valores a una lista, luego la recorre y luego da varias opciones al usuario (añadir otra entrada, modificar el valor de una entrada, eliminar una entrada o salir directamente del programa imprimiendo la lista definitiva).

En los primeros tres casos, me gustaría que tras ejecutar la función, volviera al punto del código donde se le pregunta al usuario qué quiere hacer.

He probado varias opciones pero me parecen muy liosas, ¿cual sería la mejor opción?

Por otro lado, ¿me recomendáis algún proyectillo medianamente largo para que me tenga que buscar la vida y crearlo yo de 0? De nivel básico obviamente porque llevando una semana, poco sé.

Muchas gracias.

2 respuestas
KooPad

#1394 puedes seguir la estructura de este ejemplo:

def func(opt):
    if opt == 0:
        print("hi")
    else:
        print("hello")

def main():
    while True:
        opt = int(input()) # leer valor
        func(opt)

if __name__ == "__main__":
    main()

En el main tienes un loop infinito que va leyendo de la terminal y llama a la función que recibe como parámetro el input.

Lolerpopler

#1394 Un proyecto basico extendiendo lo que has estado haciendo podria ser usar flask para hacer una api, puedes coger unos formularios web basicos para que los usuarios se registren y guardarlos en una base de datos. Añadir otro endpoint para listar usuarios, etc.
Creo que es un proyecto que casi todo el mundo tiene o ha hecho y que da opciones para usar como plantilla en el futuro

23 días después
xeven

A ver si me podeis echar una mano, llevo ya un tiempo usando python pero hasta ahora no he tenido que hacer nada parecido a esto. Tenemos que cargar un fichero enorme (aprox. 180gb) en una DB basado en un modelo de datos relacional que hemos preparado, ahora mismo hemos preparado un proceso que:
1º Splitea el fichero en partes de 10k
2º Procesa un fichero de 10k, recopila cierta información necesaria de ciertas columnas y cacheamos en memoria ciertas relaciones que posteriormente vamos a usar
3º Procesamos cada linea con la lib 'csv' -> formateamos la linea correctamente -> convertimos la linea en dos entidades (A y B ) y le asignamos ciertas relaciones que hemos cacheado en el paso 2
4º Insertamos A y relacionamos B con A para posteriormente hacer un BULK INSERT.
Esta montado sobre un comando de Django ya que usamos su ORM. Por ahora es usado para definir los modelos y tener asociada cierta logica de negocio, mas adelante se montara una API sobre ello.

Lo que pasa es que es un fichero enorme de 180gb y aproximadamente tardamos 0.3ms por linea que procesamos, y tardamos un total aprox de 50min por fichero. El problema es que son casi 3k de ficheros y tarda la vida. ¿Algun consejo sobre como abordar esto y hacerlo mas eficiente?

PD: Para realizar la carga y que no tarde la vida, lo estamos lanzando en varios servidores para asi procesar varios ficheros en paralelo.

7 respuestas
B

#1397 crea un hilo cabronazo, que es una duda interesante

1 respuesta
Lolerpopler

#1397 habeis probado a usar pandas en vez de la libreria csv? Se que en pandas tambien puedes defiinir el chunksize en el context manager. Probablemente te ahorre el paso de dividir el fichero manualmente, que creo que no es necesario porque cuando lees un fichero puedes cargarlo por chunks (pero aqui no estoy seguro 100%)
Con pandas tambien puedes definir fiiltros para no tener que ir quitandolos manualmente.

Sobre la parte de escribir en la base de datos de la manera mas eficiente no te puedo ayudar mucho.

Puedes utilizar asyncio para poder procesar en paralelo, no se si hay riesgo de colision con lo que tienes en los ficheros, pero tendrias que hacer INSERT IGNORE cuando escribir en la db

1 1 respuesta
B

#1397 habeis perfilado para buscar el bottleneck?

1 respuesta
D
#1397xeven:

¿Algun consejo sobre como abordar esto y hacerlo mas eficiente?

Pues como dicen arriba primero encontrad el cuello de botella...

Si vosotros no sabéis donde esta... Como te vamos a ayudar? No sabemos ni como es la relación, ni los datos, ni los indicies, ni los tiempos de cada paso de la pipeline... Ni siquiera te podemos decir si usar una sql esta bien para el caso de uso que has explicado, que para empezar es la primera decision que habéis tomado, porque no has explicado nada del caso de uso.

A ojo y suponiendo que usas el termino "relaciones" como indices es mejor dumpear y luego indexar. Suponiendo que vuestra tabla esta bien definida (me lo tienes que decir tu) y suponiendo que vuestra pipeline esta bien escrita en stream (que también lo tendrías que haber dicho tu) y que solo bloqueas en IO (me lo tienes que decir tu) y sincronizar tus mini batches (si son realmente necesarios estas prerelaciones, me lo tienes que decir tu).

Suponiendo que lo habéis hecho todo bien y sabéis lo que hacéis. Stremea e inserta en los batches mínimos, sincronizando lo mínimo mejor nada, y luego indices. Pues lo normal no? Existe otra manera de hacer esto?

Son unos 550tb de base de datos cuanto tiempo debería tardar?

No se, nadie aquí te podrá ayudar con esa pregunta. https://xyproblem.info/

PS: En python hay que usar el ecosistema de streaming. porque por defecto nada funcionara en stream y se te bloqueara todo. mirate pyspark y connectores para tu base de datos relacional... y busca tutoriales de big data / streaming python spark "tu base de datos relacional" porque te harán lo que te digo que hay que hacer.

1 respuesta
xeven

Es un proceso que han creado unos compañeros en base a algo que surgió de repente y que prepararon una solución, en un principio la carga no se esperaba que fuera a ser tan grande e imagino que también es probable que algo se haya planteado mal por eso. Me han comentado de echarles una mano y por ahora hasta que no termine unos tareas que tengo abiertas no me meteré en ello. Lo que comento en mi mensaje, es lo que he podido ver por encima en el proceso que han preparado en el tiempo que he tenido y lo que me han contado.

Ahora mismo sobre todo lo preguntaba por recomendaciones o algun consejo por experiencias previas, y asi poder abordarlo mejor.
#1398 Si veo que genera interes pues al final si que hare un hilo pero también necesito recopilar algo mas de información sobre lo que tenemos.
#1399 La parte de splitear el fichero original, no nos preocupa en sí. No es la mas eficiente pero hacemos ciertas validaciones y filtros, y nos resulta comodo generar ficheros de salida. Hasta que lo mire no estoy seguro, pero me apunto el asyncio por si puede sernos util.
#1400 Pues me han comentado alguna cosa y me han enseñado alguna medición, pero creo que no lo han mirado muy bien. Cuando me meta, tenia pensado pensado hacerlo de manera mucho mas detallada.
#1401 Si si, y tenéis toda la razón. Cuando me ponga con ello, os intentare dar mas información.

Ranthas

#1397 Varias cosas

  • Estás haciendo inserciones únicamente en la BD, ¿cierto?. Si es así, cuidado con los índices. Al ejecutar un insert, los índices deben recrearse, por lo que si una tabla tiene demasiados índices, puede perjudicar el rendimiento de las operaciones de escritura.

  • ¿Has controlado los tiempos por separado del tratamiento de la I/O y la base de datos? Si el bottleneck está en la entrada/salida, me temo que poco vas a poder rascar de ahí; como mucho paralelizar el proceso.

  • ¿Han testeado el tamaño del bulk a insertar en BD? Quizás tuneandolo un poco ganen rendimiento en la escritura en BD.

  • Lo mismo para el split del fichero. Quizás con 6k de líneas vaya mejor, o quizás en partes de 12. ¿Han comprobado que 10k es el nº óptimo?

Y por último, te recomiendo para operaciones en bulk depender lo menos posible de los ORM; si no te queda otra que usarlo, te recomiendo buscar en la documentación del mismo algo sobre batching y operaciones en bulk; Hibernate y JPA, por ejemplo, tienen sus propias soluciones y mejoran sustancialmente respecto a usar el ORM a pelo.

JuAn4k4

¿Queréis importar 3k ficheros de 180gb de CSV a la BD? Yo lo haría por pasos, royo ETL. El load lo haces en bulk. Y los dos primeros en paralelo totalmente. Y cada fichero en paralelo también, a no ser que las filas dependan unas de otras.

Paso uno extraer y transformar del CSV a datos a insertar (con relaciones y tal), importante usar cache distribuida para que al paralelizar todos se aprovechen de las queries a las referencias.

Paso dos mover eso a la BD en bulk, o con temp tables o como mejor sea según el motor que useis.

B

#1397 A mi me chirria que para estas operaciones masivas uséis ORM... pero tampoco conozco el ORM que usáis.

Definir los indices y constrains una vez importados los datos puede ser una buena ayuda en el rendimiento. Investiga con un "EXPLAIN".

Estaría bien saber que motor de base de datos estáis usando.

Soltrac

Sin saber mucho más, lo primero que yo haría sería deshabilitar los índices de la base de datos y recrearlos después.

Tiene que haber una mejora significativa seguro.

Luego dependiendo de la base de datos, quizás tengas la posibilidad de hacer bulk inserts q TB te van a dar una buena mejora en la inserción

Retil

Que framework recomendáis para la creación de GUI en python??

1 respuesta
B

#1407 Dependerá de que es lo que quieres hacer... te toca leer algo de documentación para ver las posibilidades y retos que te da una u otra librería

Puedes ver wxPython, pyQT...

1 respuesta
Mandarino

#1397

tardamos un total aprox de 50min por fichero

50 minutos para insertar 10k rows? Me parece una barbaridad. Seguro que estais usando bulkinsert bien y/o el bottleneck es la db?
Si el problema fuera los indices, esos 50min iran incrementando cuantas mas rows haya.

Retil

#1408 he estado probando con Tkinter pero ... no me convenca absolutamente nada, me parece bastante 'arcaico' la verdad. Voy a mirar ahora pyQT a ver que tal