Mostrando entradas con la etiqueta python-docx. Mostrar todas las entradas
Mostrando entradas con la etiqueta python-docx. Mostrar todas las entradas

jueves, 3 de abril de 2025

Evaluación. Propuestas.

Modelo básico en Python



Dentro de las posibles situaciones en que se puede requerir automatizar la evaluación, voy a considerar en esta entrada la más básica en términos de desarrollo del algoritmo, de ahí su título.


Supongamos las siguientes condiciones como punto de partida: se trata de recoger los datos de una prueba individual aplicada a un alumno de la que no se requiere almacenar más información que la que deriva de un análisis simple de los datos. En esta situación, que es más simple que la que planteamos en el [docap-modelo],  vamos a necesitar un script (python) para la recogida de datos, la corrección de la prueba, el análisis de resultados y su posterior traslado a un documento de texto a modo de informe. Para crear el informe voy a usar la biblioteca python-docx, pero, en función del carácter básico del modelo, me limitaré a sus componentes más básicos. Resumiendo, que a fuerza de ser todo básico, esto es lo mínimo que se puede hacer.

Después de importar la librería python-docx (from docx import Document) adelantándonos a lo que será la fase final del proceso, empezamos por diferenciar las distintas partes de que se compone este proyecto, esquema que nos puede ser de mucha utilidad para otras ocasiones:
  • Procedimientos para la recogida de datos en base a variables y listas de datos. Diferencio el procedimiento de recogida de datos personales del de recogida de respuestas a los ítem. Veremos posteriormente esta diferencia con más detalle.
  • Procedimientos de corrección de la prueba y de análisis (simple) de los resultados.
  • Y procedimientos para la elaboración del informe (soporte documento Word)
Debo explicar que, para facilitar la comparación entre los recursos y también para simplificar la elaboración de estas entradas, he tomado como referencia y ejemplo el docap modelo explicado en [esta entrada], incluyendo el formulario empleado en esa ocasión y su estructura.

Sobre esa base, en la recogida de datos, como dije antes se diferencian dos procedimientos: el que se requiere para los datos de identificación y el necesario para las respuestas a los ítem. Esta diferencia es doble, ya que afecta tanto al sistema de referenciación (variables vs. colecciones de datos) como al procedimiento de recogida (input() vs. ciclo for). Me explico y concreto
  • Para recoger los datos de identificación utilizo variables y hago uso de la función input() (vg. nombre = input('Nombre: '))
  • Pero para recoger las respuestas a los ítem, primero creo una lista vacía (respuestas =[]) que después doto de contenido mediante un bucle (for i in range(0,7):) y la función append() (respuestas.append(item)) que se aplica tras solicitar la entrada de datos, eso sí, también mediante input() (item =input('Ítem ' + str(i+1) + ":  "))
La segunda base (corrección y análisis) también se puede dividir en dos subfases, siendo la primera de ellas la corrección de la prueba y la segunda el cálculo de resultados en función de las referencias usadas (que son las mismas que en el docap). veamos con cierto detalle cada una de ellas, empezando por la primera ya que presenta cierta complejidad.
  • En primer lugar debemos contar con una lista que contenga las respuestas correctas (soluciones =['A','B','C','B','A','C','D']) así declarar una tercera lista donde guardar las puntuaciones que resulten de la corrección de los ítem (pd =[])
  • La puntuación del ítem implica la comparación de la respuesta obtenida anteriormente con la esperada y referenciada en la lista soluciones[].
  • Para realizar esta comparación deberemos formular un segundo bucle (for i in range(0,7):) que contenga un condicional en el cual se comparan ambas listas (if respuestas[i] == soluciones[i]:) y se genera el valor de la puntuación  y su alternativa (p = 1) (else: -> p = 0)
  • Concluimos el proceso con la función append() (pd.append(p)) para dotar de contenido a la lista pd[]
La segunda es mucho más simple y reproduce los mismos cálculos que vimos en OOo Basic: (recuérdese que se trata de un simple ejercicio, por lo que se simplifican en extremo los cálculos y el análisis)
  • Mediante un bucle (for i in range(0,7):) establecemos el sumatorio de la puntuación directa (pdt = pdt + pd[i])
  • Y partiendo de ésta y de los valores media (med = 5.38) y desviación típica (dt = 0.47), calculamos el porcentaje de aciertos (pc = (pdt/7)*100) y la puntuación típica (pz = (pdt - med) / dt)
Finalizamos este script implementado el código que nos permite generar el documento-informe, haciendo uso, en este caso, de la biblioteca python-docx, concretamente las funciones de crear (informe = Document()) y grabar el documento (informe.save('C:/PON_AQUÍ_TUS_DIRECTORIOS/Info'+ nombre +'.docx')), incorporando como contenido un título (informe.add_heading('Prueba de conocimientos básicos', level = 0)), una breve identificación del sujeto (vg. informe.add_paragraph('Datos personales del alumno: ' + nombre + ' ' + apellidos)) y la síntesis de los resultados obtenidos, ésta mediante un listado (vg. informe.add_paragraph('Puntuación directa: ' + str(pdt), style='List Bullet')

Obsérvese que se ha personalizado el identificador del informe empleando el contenido de la variable nombre ('Info'+ nombre +'.docx'). Esto permite generar diferentes informes siempre que no coincidan los nombres de los alumnos, lo que no es suficiente, siendo necesario idear sistemas más complejos para evitar las consecuencias no deseadas que derivan de esa coincidencia. Pero para nuestro objetivo actual me ha parecido que es suficiente.

Documento. Descarga [desde este enlace] el código de este script.



martes, 25 de marzo de 2025

Textos. Python.

Biblioteca python-docx (4). Formatos


En esta entrada sobre el uso de funciones de formato en python-docx trataré una cuestión que se me antoja de suficiente interés como para no prescindir de ella en este breve recorrido por esta biblioteca: el sangrado del texto.


Este interés viene dado, como en los casos anteriores, por la frecuencia con se emplea en el trabajo con textos, especialmente el sangrado de la primera línea del párrafo. Por motivos de procedimiento dejaré esta cuestión para el final, ya que antes es conveniente explicar cómo se procede para sangrar el párrafo, algo que no es de uso frecuente, dicho sea de paso.

Suponiendo que sí lo sea, vamos a sangrar nuestro párrafo (no sólo la primera línea) por la izquierda (también podemos hacerlo por la derecha). Para ello, tras importar las funciones de trabajo con pulgadas (from docx.shared import Inches),  desarrollamos la siguiente secuencia:
  1. Escribimos el párrafo según el procedimiento común (parrafo1 = documento.add_paragraph(txt)), que en este caso emplea la variable txt como parámetro en lugar del texto del párrafo.
  2. Accedemos a la propiedad general de formato del párrafo (formateoIzq = parrafo1.paragraph_format) que referenciamos sobre la variable formateoIzq
  3. Y sobre esta variable accedemos a la propiedad left_indent a la que damos valor Inches(1.5) (en este caso) (formateoIzq.left_indent = Inches(1.5))
En realidad los pasos 2 y 3 son una forma de evitar la escritura de una instrucción larga, pero ésta es válida, y parrafo1.paragraph_format.left_indent = Inches(1.5) es equivalente a las dos anteriores.

Si quisiéramos que el sangrado fuera a la derecha, sería suficiente con sustituir la propiedad left_indent por right_indent. Así de sencillo.

De modo similar, si en lugar de sangrar todo el párrafo sólo quisiéramos sangrar la primera línea, recurriríamos a la propiedad first_line_indent como alternativa a cualquiera de las dos anteriores. Por aclararlo mejor: el tercer paso del proceso se concretaría como formateoL1.first_line_indent = Inches(1) (por claridad del código en el scritp, sustituyo la variable formateoIzq por formateoL1). El valor numérico pasado como parámetro a Inches() puede ser positivo (como en este caso) o negativo (vg. Inches(-1)), lo que modifica el aspecto del párrafo, pero no supone ninguna modificación de la lógica de script.

Documento. Este es el enlace al script explicado en esta entrada; y con esto doy por finalizada la serie de entradas dedicadas a la biblioteca python-docx. Aunque no pretendo haber agotado todo lo que hay que aprender sobre ella, sí creo haber tratado los temas de mayor interés práctico.

Textos. Python.

Biblioteca python-docx (3) Formatos


No soy yo muy partidario de dedicar tiempo a estas cuestiones, teniendo por delante tantas cosas aun por resolver, pero no queda otro remedio que incluir algunas cosas referidas al formato cuando se trata de generar documentos de forma automática. Por ello dedicaré esta entrada a estas cuestiones; las mínimas.


Por empezar por algún lado, y por eso de la frecuencia de uso (y la utilidad), se me ocurre que nos puede interesar aprender a formatear los párrafos centrándolos, justificándolos, o alineándolos a derecha o izquierda.

Para ello lo primero que tenemos que hacer es añadir el acceso a un conjunto de funciones mediante la instrucción pertinente (from docx.enum.text import WD_ALIGN_PARAGRAPH)  y tomaré un texto suficientemente largo para que se puedan observar los diferentes ajustes. Este texto queda asociado a la función add_paragraph() como parámetro (parrafo1 = documento.add_paragraph(texto1)) y se escribe en el texto sin formato de ningún tipo; pero si a continuación añadimos la instrucción parrafo1.alignment = WD_ALIGN_PARAGRAPH.RIGHT, el párrafo pasa a estar alineado a la derecha, así que sólo tenemos que sustituir la palabra RIGHT por sus alternativas (.LEFT - .RIGHT - .CENTER - .JUSTIFY) , para que se justifique de acuerdo a lo ellas.

Esta es, posiblemente, la forma más sencilla de trabajar con formatos en python-docx, ya que otras opciones de formateo del texto exigen mayor complejidad en su codificación. Por ejemplo, algo tan sencillo como escribir en negrita , cursiva o subrayado requieren otro tipo de estrategias basadas en el uso de la función add_run()Supongamos, por ejemplo, que queremos destacar una palabra dentro de un párrafo escribiéndola en negrita. El procedimiento sería el siguiente:
  • Primero escribimos el texto que precede a la palabra a resaltar como párrafo sin formato (parrafo=documento.add_paragraph('En este segundo párrafo vamos a poner palabras en '))
  • Y después, para escribir la palabra (o las palabras) en negrita asociamos a la variable parrafo la función ad_run() incluyendo como parámetro dicha palabra, seguida del atributo booleano .bold con su valor en True (parrafo.add_run('negrita').bold = True). Para cursiva (.italic = True) y para subrayado (.inderline = True), actuaríamos igual; incluso para añadir más texto sin ninguno de estos tres formatos deberemos emplear la función add_run() asociada a la variable parrafo (v.g. parrafo.add_run(' y palabras en '))
Un ejemplo de complejidad de formateo que yo considero extremo en cuanto a complejidad (por comparación con lo simple que resulta "manualmente") es definir el tamaño y el tipo de fuente, siendo como es una funcionalidad que podemos considerar básica en el uso de un procesador de texto. En este caso...
  • Primero debemos importar un conjunto de funciones específicas .docx (from docx.enum.style import WD_STYLE_TYPE) requiriendo haber importado previamente el manejo de valores de tamaño de fuente (from docx.shared import Pt)
  • Después debemos asociar a una variable (v.g. styles) el manejo de las funciones de estilo asociadas al documento que referenciamos mediante la variable documento a la que previamente se asoció el objeto creado con la función Document() (styles = documento.styles)
  • Sobre la variable styles llamamos a la función add_style() que recibe dos parámetros: el primero un string con la denominación que vamos a emplear (vg. 'Calibri_12') y un segundo parámetro con referencia al atributo WD_STYLE_TYPE.CHARACTER (todo ello queda asociado a la variable -vg- charstyle -> charstyle = styles.add_style('Calibri_12', WD_STYLE_TYPE.CHARACTER))
  • Después accedemos al objeto charstyle.font, que a su vez asignamos a la variable obj_font
  • Y sobre ella al atributo tamaño (obj_font.size = Pt(12)) y nombre de la fuente (obj_font.name = 'Calibri')
Una vez que ya tenemos creado este conjunto de características puedes usarlo para añadirlo como segundo parámetro de la función add_run() asociada a la variable parrafoX para que el texto que se escriba quede formateado según la fuente y el tamaño que definiste antes. Esto se realiza en dos pasos:
  • Se asocia el añadido de la párrafo al documento a una variable (parrafo1 = documento.add_paragraph())
  • Y sobre ella se aplica la función add-run() con dos parámetros: el texto a escribir y el atributo style al que se asigna el identificador del formato que se estableció según el procedimiento anterior (parrafo1.add_run(texto1, style = 'Calibri_12'))
Este procedimiento es especialmente interesante cuando se va a trabajar con varios estilos de letra (fuente y tamaño), aunque se puede simplificar cuando el modo de proceder va a ser más sencillo, accediendo al atributo fuente del objeto run (run = parrafo1.runs[0] -> font = run.font -> font.name = 'Calibri' + font.size = Pt(12)). Todo este código queda en el script que acompaña esta entrada comentado para que no interfiera en el funcionamiento del algoritmo de base.

DocumentoNo sé si larga, pero algo liosa sí que ha sido esta entrada, así que va siendo hora de finalizarla con la ya esperable referencia al script asociado.
 

domingo, 23 de marzo de 2025

Textos. Python.

Biblioteca python-docx (2) Tablas y gráficos


Aclarar antes de nada que estoy empleando el término gráfico como sinónimo de imagen, con independencia de que esta imagen represente un paisaje, una persona o un gráfico de barrar. Dicho esto, en esta entrada trataré sobre estos potenciales componentes de un documento de texto por ser elementos que se pueden necesitar para la elaboración de los documentos que solemos crear como SEO. La finalidad de tratar estos temas es, como en otras ocasiones, proveer de recursos para la intervención profesional de los SEO; muy lejos de la de hacer a un OE experto en el manejo de Python-docx.


Desde esta orientación eminentemente práctica, empecemos por aprender a incluir gráficos (imágenes) en nuestro documento. Para ello, y dando por resueltos los procesos previos de creación del documento y la inclusión de los contenidos ya conocidos por la entrada anterior,  para incluir una imagen en un texto es suficiente con hacer uso de la función add_picture(), que precisa obligatoriamente un único parámetro; un string con la dirección de la imagen, incluyendo nombre y extensión, si bien cuando la imagen está en el mismo directorio que el script, es suficiente con el nombre y extensión.

Es posible pasar otros dos parámetros o sólo uno de ellos, con la indicación dimensional (height y/o width) y el o los valores necesarios para dimensionar la imagen en pulgadas (v.g. width=Inches(1.25)). Así es en nuestro este caso (documento.add_picture('Aprendizaje.jpg', width=Inches(1.25))) y por ese motivo necesitamos indicar al inicio del script que también precisamos importar el manejo de Inches (from docx.shared import Inches)

Sigamos ahora con las tareas necesarias para implementar una tabla en el documento, empezando por los datos que ésta va a contener, los cuales son tratados en nuestro documento de ejemplo como registros de una base de datos, motivo por el que creamos una tupla de tuplas que contiene tantos registros como deseemos y cada uno de ellos tantos elementos como columnas va a tener nuestra tabla.

registros = (('3', 'Entrevistas', 101),('4', 'Reuniones', 42),('5','Evaluaciones', 36))

No es precisamente la forma más sencilla de trabajar (y crear) una tabla, pero así aprendemos cómo podemos manejar el acceso a sus celdas para introducir los datos que deseamos contengan.

Pero crear la tabla es en realidad mucho más sencillo, siendo suficiente con emplear la función add_table(), que requiere dos parámetros integer: las columnas y las filas (tabla = documento.add_table(rows=1, cols=3))

Las complicaciones empiezan cuando decidimos que nuestra tabla tiene que tener un encabezado que clarifique su lectura. En ese caso (que es opcional, recuerdo) se requiere crear una variable (encabezado) que referencie la siguiente expresión (encabezado = tabla.rows[0].cells). Gracias a ella podemos acceder a las celdas (.cells) primera fila (rows[0].cells) de la tabla creada (tabla.rows[0].cells). Sobre esta variable iremos identificando cada una de las celdas del encabezado e incluyendo en ellas el texto del mismo (vg encabezado[0].text = 'Identificador')

Para incluir ahora el contenido de nuestros registros en la tabla, en este caso (y es un buen ejemplo de cómo podemos actuar) utilizamos un bucle for de cierta complejidad en cuanto a formulación, pero sumamente funcional (for id, cont, num in registros:). Básicamente lo que hace este bucle es recorrer nuestra base de datos (registros), elemento por elemento (id, cont, num in registros:) para posicionarlos según los criterios establecidos (vg, primero (primera celda de la fila) ... row_cells[0].text = id, después...) según la estructura a la que anteriormente se ha accedido, asociándola a la variable row_cells gracias a la función add_row() (row_cells = tabla.add_row().cells). 

Obsérvese que esta instrucción (row_cells = tabla.add_row().cells) es muy similar, pero en realidad muy diferente de la que nos sirvió para crear el encabezado (encabezado = tabla.rows[0].cells), por lo que no deben confundirse.

Este uso del bucle for puede que nos resulte un poco complicado en estos momentos (aun estamos empezando a programar en Python), así que necesitamos conocer otra forma de utilizar una tabla, como, por ejemplo, para una función muy común en la composición de un texto: posicionar texto (una serie de párrafos) de forma tabular. Para estos casos podemos trabajar con un código más sencillo. Veamos:
  • Creamos la tabla igual que antes (tabla2 = documento.add_table(rows = 2, cols = 2))
  • Accedemos a la primera fila (celdas0 = tabla2.rows[0].cells), como ves con el mismo procedimiento que antes usamos para crear el encabezado
  • Y posicionamos el contenido textual en las celdas de esa fila (v.g. celdas0[0].text = "Primera")
Deberemos repetir el procedimiento para cada una de las filas (celdas1 = tabla2.rows[1].cells) y sus respectivas celdas (celdas1[0].text = "Segunda"), ya que por algo es un procedimiento manual. Pero estoy seguro que dentro de poco sabremos implementar un bucle para agilizar el procedimiento, no tan elegante y complejo como el presentado antes, pero suficiente para nuestros fines.

Documento. Desde este enlace puedes ver (y descargar) el script que contiene el código de esta entrada.

Textos. Python.


Biblioteca python-docx (1) 





Elementos comunes


Gracias a esta biblioteca podemos automatizar desde Python la creación de documentos, lo que no es equivalente a automatizar esos mismos documentos en lo que se refiere a su contenido. Esta diferencia es importante, sobre todo para no generar falsas expectativas. A pesar de esta limitación, no deja de ser un paso importante, aunque deberá complementarse con otros procedimientos para alcanzar el objetivo de la automatización documental.


Lo que se pretende explicar en estas entrada (esta es la primera) se limita a los procedimientos más básicos, sin menoscabo de que posteriormente retomemos estas cuestiones para avanzar en su desarrollo. En lo que a esta entrada toca, el contenido se limitará a la creación del archivo y la escritura de título y contenido textual, incluyendo los listados.

Ya sabemos por una [entrada anterior], para trabajar con python-docx necesitamos haber instalado previamente esta biblioteca, cosa que hacemos desde Símbolo del sistema mediante pip install python-docx. Después, para incorporar las funciones a los script deberemos utilizar instrucciones, especialmente la siguiente, que permite crear documentos de texto (Word - Writerfrom docx import Document. No es la única necesaria, pero para los objetivos de esta entrada sí.

Empezamos por crear (documento = Document()) y guardar (documento.save('documento.docx')) el documento. La primera al inicio del script y la segunda al final.

Lo propio de un documento es que tenga título, así que utilizaremos la siguiente expresión basada en la función add_heading(), que requiere dos parámetros, el primero es la expresión textual del título (se puede sustituir por una variable string) y el segundo es una variable numérica (level = 0) que representa el nivel del título y que puede expresarse directamente como número (documento.add_heading('TÍTULO del documento', level = 0)documento.add_heading('TÍTULO del documento', 0) son equivalente)

La escritura de texto (mediante párrafos) es sumamente simple gracias a la función add_paragraph() cuando dicho gráfico no presenta ningún tipo de característica de formato. El parámetro de dicha función es el texto a introducir, o en su caso, la variable que lo referencia (parrafo1 = documento.add_paragraph('Párrafo simple...). Se puede implementar directamente, sin ser referenciado previamente a una variable, como es este caso).

Aunque no es caso, dado el escaso contenido actual de nuestro documento, podríamos necesitar, en un momento dado, provocar un salto de página. Para ello disponemos de la función add_page_break(), que carece de parámetros, y que va asociada, al igual que las anteriores al objeto document() creado previamente (documento.add_page_break()).

Antes de finalizar esta entrada, veremos cómo construir un listado, lo que en realidad consiste en implementar un segundo parámetro a la función add_paragraph() vista antes; se trata del parámetro style, variable string que tiene asociado la denominación del elemento gráfico del listado (documento.add_paragraph('Primer elemento de la lista', style='List Bullet')) (style='List Number' como alternativa).

Documento. [Este enlace] te da acceso al script explicado en esta entrada.

sábado, 22 de marzo de 2025

Textos. Python.


Biblioteca python-docx





Cuando lo que se necesita es automatizar la creación de un documento MS-Word (lo que también equivale a decir accesible desde LO-Writer), python-docx es una opción excelente: gratuita, de fácil acceso, sencilla de manejar y muy funcional.


Ya explicaré con más detalle por qué y cómo usar (a nivel básico) esta biblioteca, así que aquí sólo quiero adelantar lo elemental y necesario, que es lo que sigue.

La biblioteca python-docx no viene instalada por defecto (ya se sabe que la versión básica de Python es muy ligera y simple), así que necesitaremos instalarla desde Símbolo del sistema mediante la instrucción pip install python-docx

Para usarla en los script deberemos llamar específicamente a aquellos módulos que pensemos utilizar, siendo el más básico (e imprescindible) form docx import Document que nos permite crear un documento ejecutar sobre él las principales acciones, incluyendo la de guardarlo. Otro módulo de interés y uso frecuente es el que nos permite trabajar con formatos (from docx.enum.text import WD_PARAGRAPH_ALIGMENT).

Para finalizar esta breve introducción, de forma complementaria a lo que se explica en Documentos, te sugiero la atenta lectura de la documentación oficial de la biblioteca. Te dejo algunos enlaces de interés:

Textos. Python

Ofimática con Python


Dentro de las muchas utilidades que nos ofrece Python, las más próximas a los objetivos nucleares de este blog son las que tienen que ver con la ofimática. Aunque existen diferentes enfoques, mi opción actual tiene que ver con la creación automatizada de los principales documentos ofimáticos en términos de uso por parte de los SEO: documentos de texto, hojas de cálculo y presentaciones.



Aunque LibreOffice (LO) presenta la opción de crear y trabajar con script Python "internos", esto es, script con igual funcionalidad que los creados en OOo Basic, hasta donde yo sé, Python no cuenta con bibliotecas que permitan crear documentos LO "externamente", esto es, sin que sea necesario trabajar desde un servicio de la suite. Microsoft Office (MSA) sí, lo que constituye una ventaja a su favor. No obstante es factible crear documentos MSA y seguir trabajando con la suite LO, ya que ésta accede sin dificultad a los documentos creados para la primera.

Dentro de los productos ofimáticos, los de mayor uso (y funcionalidad) para los SEO son los documentos de texto, seguidos a mucha distancia y escasa entre ellos, por las hojas de cálculo y las presentaciones (tipo Power Point). Python cuenta con bibliotecas específicamente desarrolladas para automatizar la creación de estos documentos en soporte MSA.

Podemos automatizar la creación de documentos de texto (Word - Writer) mediante las utilidades que ofrece la biblioteca python-docx, crear hojas de cálculo (Excell - Calc) mediante openpyxl y generar automáticamente presentaciones mediante python-pptx (Power Point - Impress)
 

jueves, 23 de mayo de 2024

Textos. Python

Documentos específicos mediante Python


Python nos ofrece también la posibilidad de crear mediante script documentos genuinamente específicos de servicios ofimáticos. Esto es posible mediante el uso de bibliotecas de módulos o paquetes de funciones que previamente deben ser instalados e importados. Me refiero concretamente a la creación desde script Python de documentos Word, Excel o Acrobat. Los dos primeros son accesibles desde LibreOffice gracias a la compatibilidad que esta suite mantiene con MSO, por lo que crear un documento Word o Excel es equivalente a crear un documento accesible desde LO-Writer y LO-Calc respectivamente. Y lo es en sentido pleno: LO puede trabajar con esos documentos como si fueran propios.


Así que mantengo como icono de esta entrada el mismo que en las anteriores referidas al uso de Python como herramienta para el trabajo con recursos ofimáticos, aunque en este caso una representación más adecuada del planteamiento de trabajo sería la siguiente:

Ésta no es una representación totalmente satisfactoria del modo 1A2, ya que no lo es al completo, al faltar formatos como .pdf, pero también otros que no explicité en el esquema inicial (como .cvs, por ejemplo), ni lo es en sentido estricto, ya que en esta entrada me voy a limitar a exponer cómo desarrollar la rama superior de esta representación (documento de texto), dejando para una posterior entrada el trabajo sobre  la rama inferior (hoja de cálculo) Esta división, que facilita la coherencia con otra documentación, está justificada por la complejidad de la temática que aborda, que exige realizar cuanto menos un primer acercamiento a temas como el uso de bibliotecas externar en Python, incluyendo su instalación y uso dentro de los script a crear. También parece una exigencia lógica que deriva de la complejidad de la propia biblioteca que facilita a Python el trabajo con documentos Word.

En efecto, para desarrollar esta línea de trabajo (1A2) es necesario, en primer lugar, entender que Python, tal y como se instala en origen ofrece nada más que la punta de un iceberg de posibilidades, siendo posible (y necesario) implementar bibliotecas, paquetes de funciones o módulos, nuevas clases... (a gusto del consumidor) para desarrollar procesos específicos de trabajo, como es el caso de la creación de soportes ofimáticos (en este caso documentos MSO-Word).

Este proceso tiene cierta complejidad, aunque esta suficientemente simplificado gracias a los recursos disponibles en Python. A mí me ha servido parta entenderlo, además de la lectura de documentación, la explicación que proporciona Errodinger en este vídeo. Considero que es una buena síntesis de las opciones disponibles y de cómo proceder. No es el único recurso disponible, pero sirve para empezar.



En síntesis, la opción básica de instalación es el comando pip install NombreLibreria aplicado desde el cmd, tal y como te muestro en este vídeo que grabé mientras instalaba la librería para trabajar con documentos .docx. Para su visualización recomiendo la opción Pantalla completa


La instrucción completa es pip install python-docx, a escribir tras la cadena que genera Símbolo del sistema (consola o cmd) C:\Users\NombreUsiario>

Una vez instalada la librería python-docx, existen dos formas de saber si forma parte de las librerías instaladas, podemos utilizar indistintamente pip freeze o pip list (ambas desde Símbolo de sistema,cmd o consola) que listan todas las librerías, paquetes (de módulos) o clases instaladas y su versión (1)

Además, y ahora desde el IDE, podemos comprobar si un paquete está correctamente instalado (esto es, si funciona) utilizando la instrucción import NombreLibreria: si funciona correctamente no obtendremos ninguna respuesta (el intérprete queda a la espera), pero si no funciona obtendremos un mensaje de error. Por ejemplo, import doc devuelve...

Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    import doc
ModuleNotFoundError: No module named 'doc'

        Otra instrucción que nos interesa conocer, también a aplicar desde IDE, es dir(NombreLibreria), que nos devuelve el conjunto de funciones o métodos de que dispone la librería en cuestión. Por ejemplo, dir(docx) devuelve...

        ['Document', 'ImagePart', 'RT', 'TYPE_CHECKING', 'Type', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', 'annotations', 'api', 'blkcntnr', 'dml', 'document', 'drawing', 'enum', 'exceptions', 'image', 'opc', 'oxml', 'package', 'parts', 'section', 'settings', 'shape', 'shared', 'styles', 'table', 'text', 'types']

        Saber cuáles son los componentes de la librería es útil como síntesis, pero no  es suficiente cuanto estamos iniciando el aprendizaje del funcionamiento de un paquete, así es conveniente disponer de información más detallada, sobre componentes, funcionamiento y ejemplos. Para ello es recomendable consultar los siguientes enlaces (2):

        Pasemos ahora a la crear un documento Word. Únicamente es una ejemplificación de esta opción para constatar su funcionalidad tal y como se representa en este esquema del modo externo (modo 1)


        El script ha sido creado desde el IDE estándar de Python y modificado desde bloc de notas. Con esto quiero significar que, al menos para elaborar recursos básicos no es necesario trabajar con IDE complejos ni especializados. Este es el script...

        from docx import Document #-> Acceso a la librería docx para importar el método Document

        document = Document() # -> Creamos un documento mediante la función Document()

        # Escritura del encabezado del documento mediante la función add_heading()

        document.add_heading('Escritura de texto en formato Word. Modo 1A2')

        # Siguen a continuación tres modos de escribir contenido (párrafos)

        paragraph = document.add_paragraph('Primer párrafo: Texto escrito directamente mediante asignación de contenido a variable.')

        p = document.add_paragraph('Segundo párrafo: Texto plano seguido de texto en ')
        p.add_run('negrita').bold = True
        p.add_run(' y texto en ')
        p.add_run('itálica.').italic = True

        texto_parrafo3=input("Escribe el tercer párrafo")
        paragraph = document.add_paragraph(texto_parrafo3)

        # Finalizamos  guardando el documento creado mediante la función save()

        document.save('textopruebaword.docx')

        ... y este el resultado (captura de pantalla del documento Word). Te recomiendo que descargues el script Python, analices y repliques el proceso. Aunque no es obligatorio, te sugiero que guardes el script en la unidad D:
         

        Con lo anterior he desarrollado el proceso representado en el esquema precedente hasta el punto en que se crea un documento Word. Aquí puede finalizar el proceso, pero también podemos continuarlo accediendo al documento desde LO-Writer.


        Efectivamentea diferencia de los modos 1A1 y 2B, en 1A2 el uso de LibreOffice no es necesario salvo como recurso para visualizar el contenido del documento y como alternativa a MSO-Word, dada la posibilidad que ofrece LO por su compatibilidad con las extensiones MSO. 

        También es posible implementar macros OOo Basic, pero a diferencia del modo 1A1, considero que esta opción sólo se debe contemplar de forma excepcional, ya que deberíamos ser capaces de generar un documento final mediante Python.

        NOTAS

        (1) Eso en Windows; para Linux y Mac ver enlace
        (2) Conforme vayamos incorporando otras bibliotecas iré ampliando el listado de enlaces a la documentación de las mismas.