Mostrando entradas con la etiqueta Función. Mostrar todas las entradas
Mostrando entradas con la etiqueta Función. Mostrar todas las entradas

lunes, 6 de mayo de 2024

Usos. Documentos prescriptivos.

Campos calculados

Entiendo por campo calculado aquel que resulta de la aplicación de al menos una operación aritmética. Este tipo de campo es más propio de un docap de evaluación y está muy escasamente representado en los documentos prescriptivos, pero no ausente.



En efecto, tanto el dictamen como el informe contiene uno de esos campos, el mismo en realidad: el del cálculo de la edad del sujeto.


En la segunda tabla (1. Datos personales del alumno o alumna) del dictamen encontramos este tipo de campo. Como recordarás, en un primer momento lo tratamos como campo simple (introducir el dato directamente mediante InputBox()), trasladando al usuario la realización del calculo con o sin la ayuda de alguna herramienta de cálculo(1); pero en esta entrada vamos aprender a ejecutar el cálculo desde un script, lo que equivale a tratar dicho campo como campo calculado.

Como en todo cálculo son necesario datos y operadores, lo que nos lleva al necesario conocimiento de ambos en el lenguaje OOo Basic (en esta [entrada] sobre variables y operadores numéricos). Aquí encontramos los datos en dos campos: el tercero de la primera tabla (Fecha del dictamen) y en el tercero de la segunda (Fecha de nacimiento), ya que el cálculo de la edad resulta de:

Edad = Fecha del dictamen - Fecha de nacimiento

Este es un cálculo sencillo en cuanto a operaciones, pero no carente de cierta complejidad al constar una fecha de diferentes unidades de tiempo (año-mes-día). El procedimiento de la operación queda expresado (frecuentemente) en las carátulas de las pruebas de evaluación...


... que es una forma gráfica de expresar la siguiente igualdad:

e(a:m:d) = f(a*x + m*y + d) - i(a*x + m*y + d)
  • siendo e = edad, f = fecha final o actual e i = fecha inicial o de nacimiento
  • siendo a = años, m = meses y d = días
  • Siendo x = 365 e y = 30 (esto es, año standard de 365 días y mes ajustado a 30 días) 
Aunque en un campo calculado el procedimiento a seguir está en función de las operaciones (cálculos), en términos generales, y no con independencia de la complejidad del cálculo, se nos presentan dos posibilidades:
  • Incorporar el cálculo al script principal
  • O extraerlo del script principal y derivarlo a una función a la que asociar a una variable del script principal.
Ambas opciones son válidas en cualquier caso, pero la primera es aceptable cuando las operaciones son pocas (al menos pocas) y la segunda es aconsejable cuando debemos aplicar un número de operaciones que pueden afectar a la inteligibilidad del script principal.

Volviendo al cálculo de la edad, que es al que nos enfrentamos en el caso de los documentos prescriptivos tratados (dictamen e informe), el modo en que planteemos el script va a depender de la forma en que nos planteemos resolver el cálculo. De hecho podemos utilizar al menos tres procedimientos diferentes.
  • El primero y más sencillo consiste, básicamente y en primer lugar, en calcular la diferencia (en días) entre la fecha final y la inicial mediante la fórmula...
Edad = FechaFinal - FechaInicial

... factible siempre y cuando FechaFinal y FechaInicial hayan sido definidas como variables tipo Date, lo que requiere el uso de la función de conversión CDate() a la solicitud de datos al usuario mediante InputBox().

  • El segundo es más complejo puesto que no realizamos el cálculo de forma directa, sino que descomponemos cada una de las variables de fecha haciendo uso de tres funciones disponibles en Calc (year(), Month() y Day()) que devuelven respectivamente el año, mes y día de una fecha expresado en formato fecha (v.g., dd/mm/aaaa)
La primera fórmula es, en principio, perfectamente asumible desde el script principal (por lo que no sería necesario derivar el cálculo a una función), pero la segunda ya resulta suficientemente compleja como para que valoremos la pertinencia de usar una función.

No obstante, en ambas opciones, y hasta ese momento solamente hemos obtenido el número de días transcurridos desde la fecha inicial (nacimiento) hasta la actual...

iDias = fFinal - fInicial

... pero no la edad del sujeto tal y como se expresa normalmente (años, meses y, en su caso, días). Para ello necesitamos conocer, como los valores meses transcurridos y los años transcurridos (2) como paso previo para saber la edad.

iMeses = iDias\30
iAnnos = iDias\365

A partir de estos cálculos podremos obtener los valores edad en años y en meses. En realidad el de los años (de edad) resulta de la operación previa (iAnnos = iDias\365), pero el de meses (de edad) requiere restar el total de meses menos los que suponen los años.

iMesesEdad = iMeses -(iAnnos*12)

Es para el cálculo de los días de la expresión edad donde podemos optar por dos formas diferentes de realizar el cálculo:
  • Operando con los datos disponibles: iDiasEdad = iDias - ((iAnnos*365)+(iMesesEdad*30))
  • Utilizando el operador aritmético Mod para calcular el resto de la división de los días transcurridos entre 30: iDiasEdad = iDias Mod 30
Dado que con ambas operaciones se obtiene el mismo resultado, parece lógico que optemos por el operador Mod.

La tercera opción, que se ajusta claramente al uso de una función, reproduce el procedimiento empleado en el cálculo manual de la edad que vimos representado en la última imagen. Incluye el uso de funciones de identificación de años, mes y días de ambas fechas (funciones Calc Year(), Month() y Day()) y procedimientos de corrección para casos particulares. Pero detengo aquí la explicación porque esta función ya ha sido explicada en esta [entrada correspondiente] a la que remito para más detalle (3)

Analizo a continuación una de las formulaciones dentro de las posibles antes comentadas.

 Sub Edad2

'Variables

Dim oMarca As Object
Dim mMarcadores(2) As String
Dim mDatos(2) As String
Dim fDictamen As Date, fNacimiento As Date
Dim sEdad As String
Dim i As Integer

'Asignación de contenido

mMarcadores() = Array("d0","d1","d2")
fDictamen = CDate(InputBox("Fecha del dictamen:","DICTAMEN DE ESCOLARIZACIÓN"))
fNacimiento = CDate(INputBox("Fecha de nacimiento:","ALUMNO/A. DATOS PERSONALES"))
sEdad= EdadA(fNacimiento,fDictamen)
mDatos(0) = CStr(fDictamen)
mDatos(1) = CStr( fNacimiento)
mDatos(2) = sEdad

'Escritura de datos en el documento

For i=LBound(mMarcadores()) To UBound(mMarcadores())
oMarca = ThisComponent.getBookmarks().getByName(mMarcadores(i))
oMarca.getAnchor.setString(mDatos(i))
Next

End Sub

'Función para cálculo de edad

Function EdadA(fInicial As Date, fFinal As Date) As String

'Calculo de duración de los periodos temporales (en días, meses y años)

Dim iDias As Integer, iMeses As Integer, iAnnos As Integer

iDias = fFinal - fInicial
iMeses = iDias\30
iAnnos = iDias\365

'Cálculo de valores

Dim iMesesEdad As Integer, iDiasEdad As Integer

iMesesEdad = iMeses -(iAnnos*12)
iDiasEdad = iDias - ((iAnnos*365)+(iMesesEdad*30))

'Expresión edad

Dim sEdad As string

sEdad = CStr(iAnnos) & " años, " & Cstr(iMesesEdad) & " meses y " & CStr(iDiasEdad) & " días."

EdadA = sEdad

End Function

  • Dividimos el procedimiento en dos partes: un script (principal) y una función (para el cálculo de la edad). 
  • Desde el script se llama a la función para asignar el resultado obtenido mediante la variable sEdad
  • El script es el responsable de la asignación de datos y de su escritura en el documento.
  • En él, por claridad expositiva, diferencio entre las variables para asignación de datos...
Dim fDictamen As Date, fNacimiento As Date
Dim sEdad As String

  •  ... una matriz para su escritura en el documento (Dim mDatos(2) As String) (4) y una segunda para contener los nombres de los marcadores. De este modo podemos resolver la escritura de los datos en los marcadores del documento de forma eficiente mediante un bucle.

For i=LBound(mMarcadores()) To UBound(mMarcadores())
oMarca = ThisComponent.getBookmarks().getByName(mMarcadores(i))
oMarca.getAnchor.setString(mDatos(i))
Next
  • Centrándonos en la función, primeramente calculamos la diferencia en días entre los valores pasados como atributos desde el script.
  • Primero creo tres variables para el cálculo del tiempo transcurrido desde la fecha de nacimiento hasta la actual (Dim iDias As Integer, iMeses As Integer, iAnnos As Integer) y realizo los cálculos pertinentes, empezando por el datos de los días (iDias = fFinal - fInicial) y, a partir de éste, los de los meses (iMeses = iDias\30) y años (iAnnos = iDias\365)
  • El valor años es útil directamente, pero no así el de los meses y días transcurridos. Por ello necesitamos dos variables (Dim iMesesEdad As Integer, iDiasEdad As Integer) que nos permitan asignar a ellas el resultados de las operaciones requeridas.
  • El cálculo del valor meses de edad (iMesesEdad = iMeses -(iAnnos*12)) requiere descontar del total de meses los contenidos en los años de vida del sujeto...
  • Y el cálculo de los días de la edad, como explicamos antes, puede ser resultante de dos operaciones diferentes: en este script utilizo la forma básica, que no la mejor (iDiasEdad = iDias - ((iAnnos*365)+(iMesesEdad*30))), como ya expliqué antes.
  •  Finalmente componemos la expresión que informa sobre la edad del sujeto sobre una variable (Dim sEdad As string) y creo dicha expresión mediante la concatenación de variables y cadenas de texto (sEdad = CStr(iAnnos) & " años, " & Cstr(iMesesEdad) & " meses y " & CStr(iDiasEdad) & " días."
  • Finalmente se asigna al identificador o nombre de la función (EdadA) la variable anterior (EdadA = sEdad), con lo que se entrega al script que llama esta función el dato (string) asociado (el contenido de sEdad)
Para facilitar el análisis de las diferentes opciones dejo [acceso] al sencillo docap resultante.

NOTAS

(1) Además de no ser un cálculo de especial dificultad, que bien puede resolverse manualmente, existen en la Web calculadoras de edad, como la que pone a disposición de todos la editorial Pearson. También podemos crear una [calculadora de edad] mediante las funciones integradas en Calc.

(2) Obsérvese que el operador utilizado en ambos cálculos es el de la división entera (\), no el de la división general (/).

(3) En realidad la diferencia pequeña diferencia entre las dos primeras opciones y la tercera tampoco no es tan importante para el objetivo que se plantea en los documentos prescriptivos, especialmente si limitados los datos de edad a años y meses, datos normalmente suficientes para los objetivos que se persiguen en ambos documentos. Únicamente en caso de nuevas escolarizaciones (en 1º de E. Infantil) y cuando el número de días se aproxima al mes se puede considerar de cierta relevancia el número de días de edad; en el resto de las circunstancias, conocer los años y meses de edad será suficiente.

(4) En realidad nos podríamos ahorrar las variables y utilizar los elementos de la matriz mDatos() para asignar directamente los valores. Con ello nos ahorraríamos algunas líneas de código (la reasignación de los datos de las variables a los elementos de la matriz, por ejemplo), pero deberíamos hacer otros cambios en el script y en la función. En este caso deberíamos optar por declarar la matriz de tipo Variant o de tipo String, pero de tomar esta segunda decisión, tendríamos que modificar la categoría de las variables argumento de la función y realizar dentro de ésta un cambio de tipología (de String a Date) mediante la función CDate(). Como podemos ver, se comprueba de nuevo esa máxima de que en programación existen múltiples soluciones posible.

jueves, 2 de mayo de 2024

Usos. Documentos prescriptivos.

 Tablas. Campos condicionados

Otro tipo de campo frecuente en las tablas del dictamen y del informe es el que denomino aquí campo condicionado. Estos campos se caracterizan por ser dependientes de otro campo con el que se encuentra conceptualmente relacionado.


Veamos primero un ejemplo de este tipo de campos en el dictamen:


Los campos del apartado 5 del dictamen (también los del 6. Recursos de apoyo especializado) son de tipo condicionado, ya que el campo de la columna Sí/No condiciona su correspondiente de la columna Breve descripción: si contestamos en el primero deberemos incluir información en el segundo; en caso contrario el campo asociado quedará vacío (1)

También se presenta este tipo de campos en el modelo de informe, como comprobamos en la captura que sigue:


En este caso se trata de una tabla en la que se registra la presencia vs. ausencia de Medidas de Atención a la Diversidad (MAD). Su funcionamiento es igual al de la tabla anterior (dictamen): si la respuesta al ítem es , se deberá aportar información en el campo asociado de la columna 4. En caso contrario (No) su campo asociado quedará vacío.

Paso ahora a explicar el código necesario. Como ejemplo trabajaré con la tabla 5 del dictamen desarrollando una de las dos opciones, la menos eficiente, por lo que recomiendo una lectura atenta de todo lo que sigue.

Sub DictamenMod2

Dim oMarcador As Object
Dim sAjustesOrganizativosA As String, sAjustesOrganizativosB As String

sAjustesOrganizativosA = InputBox("¿Son necesarios ajustes organizativos y metodológicos?","DICTAMEN. 5. Adapciones que precisa","Sí-No")

 If sAjustesOrganizativosA= "Sí" Then

sAjustesOrganizativosB = InputBox("Describe las medidas organizativas, metodolóogicas y curriculares de acceso que consideras necesario.","DICTAMEN. 5. Adaptaciones que precisa")

ElseIf  sAjustesOrganizativosA= "Sí" Then

 sAjustesOrganizativosB = ""

Else

MsgBox("No has dado respuesta a lo demandado en el campo Ajustes organizativos del aparado 5 del DICTAMEN o la respuesta no se acepta como válida") 

   End If 

oMarcador = ThisComponent.getBookmarks().getByName("mcr0")
oMarcador.getAnchor.setString(sAjustesOrganizativosA)
oMarcador = ThisComponent.getBookmarks().getByName("mcr1")
oMarcador.getAnchor.setString(sAjustesOrganizativosB)

End Sub

  • Necesitamos crear la misma estructura que usamos en el caso de campos simples, incluyendo la creación de marcadores en el documento. 
  • Además de la variable object (oMarcador) que nos permite acceder a los objetos marcador del documento (mcr0 mcr1) Declaramos dos variables de contenido por aspecto: una para el campo condicionante (sAjustesOrganizativosA ) y otra para el condicionado (sAjustesOrganizativosB):
Dim oMarcador As Object
Dim sAjustesOrganizativosA As String, sAjustesOrganizativosB As String
  • Dar contenido a la variable condicionante se ajusta al modelo de campo básico, por lo que se le puede tratar mediante la misma fórmula...
sAjustesOrganizativosA = InputBox("¿Son necesarios ajustes organizativos y metodológicos?","DICTAMEN. 5. Adapciones que precisa","Sí-No")

... pero esto genera un posible error por omisión (respuesta vacía) o por separarse (en forma o en contenido) de las dos únicas opciones válidas (Sí/No). Para controlar estos posibles errores se pueden usar diferentes opciones y aunque estos errores sean excepcionales, su solución no es simple (2).

Otra posible formulación pasa por emplear la función MsgBox(), lo que nos obliga, a su vez una nueva variable Integer (Dim iR as Integer) a asociar a la función MsgBox(). Esta opción evita posibles errores por parte del usuario, aunque obliga también a modificar la estructura condicional, condicionando un script alternativo:

 Dim oMarcador As Object

Dim sAjustesOrganizativosA As String, sAjustesOrganizativosB As String

Dim iR As Integer

iR = MsgBox ("¿Son necesarios ajustes organizativos y metodológicos?",4,"DICTAMEN. 5. Adaptaciones que precisa")

 If iR = 6 Then

sAjustesOrganizativosA = "Sí"
sAjustesOrganizativosB = InputBox("Describe las medidas organizativas, metodolóogicas y curriculares de acceso que consideras necesario.","DICTAMEN. 5. Adapciones que precisa")

Else

 sAjustesOrganizativosA = "No"
 sAjustesOrganizativosB = ""

 End If 

Como podemos comprobar, esta segunda opción simplifica el script y lo hace más resisten a errores de uso (en realidad los reduce a cero), por lo que es preferible al primer script (3).

  • Finalmente, la escritura en el texto se mantiene en la formulación ya explicada en la entrada anterior sobre campos simples, aunque ahora son necesarias dos fases de escritura, que aquí se resuelven meramente por repetición del mismo procedimiento (4):

oMarcador = ThisComponent.getBookmarks().getByName("mcr0")
oMarcador.getAnchor.setString(sAjustesOrganizativosA)
oMarcador = ThisComponent.getBookmarks().getByName("mcr1")
oMarcador.getAnchor.setString(sAjustesOrganizativosB)

NOTAS

(1) Este segundo campo también sería condicionado si el contenido a introducir fuera uno u otro según la respuesta dada al campo condicionante. El ejemplo que presento aquí es la formulación más simple de este tipo de campos, pero también el único que se presenta en el informe y en el dictamen.

(2) En este caso se incluye en InputBox() las dos opciones de respuesta como tercer parámetro de la función; también se incluye la opción Else en el condicional If con un mensaje de advertencia. En el modelo propuesto podría añadirse a continuación de Else volver a interrogar sobre la variable sAjustesOrganizativosA y repetir el análisis que realiza el condicional, dando así una segunda opción. Como se puede ver, la solución no es sencilla, aunque en realidad es posible que estas circunstancias adversas se produzcan excepcionalmente.

(3) En principio, cuando nos encontremos con un campo de dos opciones siempre es preferible utilizar la función MsgBox() en lugar de InputBox(); no ahorraremos posibles errores y obtendremos un código más limpio y funcional. MsgBox() funciona en realidad como Boolean, pero su configuración de respuesta en OOo Basic nos obliga a asociarla a una variable numérica, ya que sus comandos (aquí el parámetro 4, que muestra las opciones - No) devuelven respectivamente los valores 6 y 7.

(4) Cuando el número de variables y marcadores a usar se multiplique será necesario trabajar con una matriz para agrupar las variables y un bucle para el proceso de escritura. Para los objetivos de esta entrada ambos resultan innecesarios. 

miércoles, 27 de diciembre de 2023

Usos. Datos.

 Calc. Funciones propias (3). Números



Calc dispone de dos funciones para controlar si un dato es numérico o no lo es.  Estas funciones son ESNUMERO() y N(). La primera función devuelve VERDADERO si un dato es numérico y FALSO si no lo es.

Los datos numéricos que lo parecen, pero que no lo son, son los que resultan de escribir números como palabras, como, ñor ejemplo, cuando escribimos un numero dentro de una cadena ('"tengo 24 años"), pero también cuando utilizamos controles de formulario como Cuadro de texto para introducir datos numéricos y los asociamos a celdas.

Cuando usamos estos controles de formulario como forma de entrada de datos y asociamos la entrada a una celda, si en el cuadro de texto escribimos un texto no se produce ningún problema, pero si escribimos números, el resultado esperado puede no corresponderse con lo que obtenemos, presentando un comportamiento irregular.

  • Si aplicamos la función ESNUMERO() a esa celda, nos devolverá FALSO, 
  • pero si en otra celda recogemos el resultado de aplicar un operador aritmético al valor de la celda asociada al control, la función ESNUMERO() devuelve VERDADERO.
  • Ahora bien, si ese dato está incluido en un conjunto de datos, unos numéricos y otros string, y aplicamos funciones que suponen trabajar con el conjunto, como SUMA()PROMEDIO() y otras, ESNUMERO() devuelve VERDADERO, pero el cálculo excluye los valores no numéricos.

Lo que sucede en estos casos es que las citadas funciones (SUMA() y PROMEDIO()) realizan los cálculos respectivos sobre el conjunto de datos que sí son número sin tomar en cuenta los valores que se presentan como tales pero que no los son, como es el caso de los que proceden de los controles del formulario.

Si utilizamos controles de formulario como recurso de entrada de datos en sustitución de la entrada directa en celdas, y mediante funciones específicas trasladamos sistemáticamente estos valores a una tabla sobre la que realizamos cálculos, no es difícil imaginar el efecto que el comportamiento observado anteriormente va a tener en los resultados que obtengamos de tales cálculos. 

En estos caso, para evitar estos errores sugiero recurrir a multiplicar el valor original por 1 (D2*1), lo que convierte el dato en un número reconocido como tal por ESNUMERO() y por las funciones de cálculo del conjunto, como SUMA() y PROMEDIO().

Calc dispone de la función N(), que transforma un carácter en número, pero que puede ser que devuelva 0, convertido eso sí, en un valor numérico, tal y como revela ESNUMERO(), por lo que altera obviamente, nuestro cálculo.

domingo, 17 de diciembre de 2023

Python. Lenguaje.

Funciones para segmentar cadenas

Siguiendo con el interesante mundo de las cadenas en Python, después de la revisión de opciones de concatenación que hice en una entrada anterior, deseo en ésta revisar las principales funciones de que disponemos para manejar y formatear el contenido de las cadenas. La importancia de estos contenidos deriva de la propia del uso de cadenas en la automatización de documentos.

 


Enumeraré aquí las principales funciones, ejemplificando su modo de uso. Tiempo habrá de utilizarlas en la creación de un recurso concreto. 

Función len(cadena)...


... permite conocer el número de caracteres que contiene una cadena esto es, devuelve el entero de dicho valor, incluyendo los espacios en blanco que separan sus componentes en caso de estar formada por varias palabras. También se consideran como caracteres los signos de puntuación.

print(len('Hola'))        -> 4
print(len('Ho la'))       -> 5 
print(len('¡Hola!'))      -> 6

len() también evalúa variables que contienen o referencian string...

nom = 'Maria'
print(len(nom))        -> 5

... y en su uso admite concatenación con literales y variables

cad1 = 'Los verdes prados de Oviedo'
print('La cadena ' , cad1 , ' tiene ' , len(cad1), ' caracteres')

... así como diferentes procedimientos de concatenación

print(f'La cadena {cad1} tiene {len(cad1)} caracteres')
print('La cadena {} tiene {} caracteres'.format(cad1,len(cad1)))

Si len() permite identificar el número de elementos de una cadena es porque una cadena se comporta como una lista de caracteres, motivo por el que cada carácter tiene asociado un índice en el string, índice por el que es posible acceder al carácter. Así, por ejemplo, para cad1...

print(cad1[0])         -> L (primer elemento del string asignado a cad1)
print(cad1[-1])        -> o (último elemento del string asignado a cad1)

NOTA 1 -> Obsérvese  que, en orden directo, la matriz de elementos se inicia en 0 y que los índices negativos permiten acceder a los elementos de la cadena en orden inverso. 

NOTA 2 -> Esta cualidad de la cadena como lista de caracteres y el uso de funciones de formato pueden ser de gran interés para la manipulación de segmentos de cadena. Tendremos ocasión de verlo con más detalle en una entrada que complemente a esta.

Ahora ya sabemos que una cadena se puede descomponer en una lista de caracteres, que la función len() nos permite conocer cuántos son estos y que podemos acceder a cada uno de ellos solicitándolos por su índice. 

Estos conocimientos son muy interesantes y es posible darles utilidad en el desarrollo de algoritmos de automatización de documentos. Pero no son las únicas utilidades que pueden tener utilidad en este ámbito de uso... ni en otros. Me estoy refiriendo en concreto a la utilidad que pueden tener dos métodos de trabajo con los componentes de una cadena: split() y join() 

Método split()... 

... permite identificar los segmentos de una cadena, no los caracteres que la componen, sino las subcadenas en que se divide. Su sintaxis básica es la siguiente:

 cadena.split(sep,maxsplit)    donde...

    • cadena es la cadena o variable string sobre la que se aplica split()
    • sep es el argumento que identifica el carácter por el que se divide la cadena. Por defecto es el espacio (' ').
    • mxsplit es el argumento que establece el número de veces en que deseamos dividir la cadena (o número de apariciones de sep que deseamos utilizar como referente para separar las subcadenas). Por defecto su valor es -1, que indica que deseamos utilizar todas las apariciones del carácter sep  

 Veamos algunos ejemplos utilizando cad1="Los verdes prados de Oviedo" 

divide_cadena = cad1.split()
print(divide_cadena)                  (1)  -> ['Los', 'verdes', 'prados', 'de', 'Oviedo']
 
divide_cadena = cad1.split(' ',2)
print(divide_cadena)                  (2)  -> ['Los', 'verdes', 'prados de Oviedo']

 divide_cadena = cad1.split('d',-1)

print(divide_cadena)                  (3)  -> ['Los ver', 'es' pra', 'os de Ovie', 'o']

  • La formulación 'por defecto'  (1) divide la cadena en las palabras que forma la frase.
  • Cuando modificamos el parámetro mxsplit (2) obtenemos un número diferentes de secuencias. Concretamente 2 divide la cadena en tres partes: las resultantes de las dos primeras apariciones de sep (' ') ['los'] y ['verdes']  y el resto de la cadena ['prados de Oviedo']
  • Si utilizamos otro criterio para sep (en 3 -> 'd'), manteniendo mxsplit por defecto (-1), obtenemos segmentos identificados en función de la aparición del carácter sep

Por eso dije subcadenas y no palabras, aunque es posible que, al menos inicialmente el uso más frecuente sea el establecido por defecto, esto es: la creación de una lita de las palabras que conforman la frase.

El resultado 'normal' del método split() nos da acceso a una lista que va a sernos de mucha utillidad cuando queramos modificar el contenido de esa  lista. Utilizaremos para ello lo que sabemos respecto al manejo de listas: acceso a elementos, sustración, adición y sustitución de elementos... Pero es posible que esto sea tema para tratar en otra entrada, así que mejor completamos la actual hablando del método join()

Método join()...

... sirve para invertir los efectos del método split(), esto es, para unir los elementos diferenciados de una lista en una única cadena. Veamos cómo:

divide_cadena = cad1.split()             1-> Divide la cadena cad1 y asigna divide_cadena
unir_cadena=' '.join(divide_cadena)  2-> Une divide_cadena y asigna a unir_cadena
print(divide_cadena)                        3-> ['Los', 'verdes', 'prados', 'de', 'Oviedo']
print(unir_cadena)                           4-> Los verdes prados de Oviedo

Si en vez de 2 escribimos el método join() precedido de '__' , obtendremos en 4 el siguientes resultado: Los__verdes__prados__de__Oviedo.

viernes, 15 de diciembre de 2023

Usos.Datos.

Calc. Funciones propias (2). Concatenar  cadenas.

Las funciones de concatenación pertenecen al conjunto de funciones de texto.

- Función CONCATENAR(). Es la más antigua y simple de las funciones de concatenación de Calc. Permite combinar varios elementos de texto en uno único. Admite entrada directa o referencias a celdas y convierte valores numéricos a cadenas de texto. No admite conjunto de celdas como referencia.

-> Sintaxis: =CONCATENAR(Texto1;Texto2;...TextoN)

No maneja espaciado entre elementos (TextoX), así que es necesario implementar estos separadores en el diseño del texto o incluyendo referencias a cadenas vacías (" ")

Ej. 

=CONCATENAR(
B4;
" ";
B5;
" ";
B6;
            B9
) 

Da como resultado la cadena PPPP LLLL MMMM AAA, en función del contenido de las respectivas celdas. Obsérvese que la separación entre B4,B5 y B6 se establece mediante cadenas vacías intermedias. El espacio entre B6 y B9 se establece en el diseño de B6, dejando un espacio en blanco al final de la cadena.

- Función CONCAT(). Es posterior a CONCATENAR() e incluye la posibilidad de aceptar conjunto de celdas (rango) como parte constituyente de  los elementos concatenado.

-> Sintaxis: CONCAT(Texto1;Texto2;...TextoN) (La misma que CONCATENAR())

Presenta las mismas limitaciones que CONCATENAR() en el manejo de espacios entre cadenas, por lo que son válidas las mismas soluciones.

Dado que acepta intervalos de celdas como elementos, gestiona los posibles vacíos en el intervalo como omisión de dicho elemento (no deja huella de la celda vacía)

Ej. 

=CONCAT(
B4;
B5;
B6;
B$9:B$13
)

Da como resultado la cadena  PPPPLLLLMMMM  AAAAIIIIUUU en ausencia de separadores entre cadenas. Obsérvese que genera una separación entre los elementos (referencias) individuales y el grupo o intervalo. Dentro de este dos de las celdas están vacías siendo omitido este vacía en la cadena resultante.

- Función UNIRCADENAS(). Permite combinar varios elementos en uno sólo, acepta intervalos de celdas y los trata del mismo modo que CONCAT(), aunque a voluntad del usuario, y utiliza delimitadores para separar los elementos.

-> Sintaxis: =UNIRCADENAS(Delimitador;OmitirCadenasVacías;Texto1;Texto2;...TextoN)

Ej.

=UNIRCADENAS(
"--";              -> Delimitador entre componentes
1;                 -> 1 = V -> No se tomarán en cuenta las celdas vacías
1234;           -> Literal numérico
;                  -> Simula cadena vacía
"adbd";        -> Literal string
B10;            -> Referencia a celda individual (contenido CCCC)
B4:B6          -> Referencia a intervalo de celdas (Contenido PPPP()MMMMM.B5 vacía)
)

Da como resultado la cadena  1234--adbd--CCCC--PPPP--MMMM. Obsérvese que efectivamente se omite el espacio de la cadena vacía (la situada entre los literales numérico y string), así como la celda vacía B5. Si el valor del parámetro 2 (OmitirCadenasVacias fuera 0 (F), la cadena resultante sería la siguiente: 1234----adbd--CCCC--PPPP----MMMM. El separador -- permite apreciar claramente las diferencias.

Aunque UNIRCADENAS() nos ofrece mayor control sobre cómo se presenta la cadena resultante respecto a CONCAT() (y mucho más aun que CONCATENAR()), el resultado puede no ser del todo satisfactorio. Por este motivo es conveniente utilizar otras funciones de formateo de como la que indico en esta entrada, pero que aquí omito por no ser contenido de esta entrada.