domingo, 15 de septiembre de 2024
LENGUAJE
LENGUAJE.
Componentes básicos.
En síntesis la programación o computación (y de ahí le viene el nombre) consiste en la ejecución de cómputos sobre datos para la obtención de unos resultados, sean éstos los que sean. Esto, que es otra forma de formular el esquema anterior, supone y pone en evidencia la importancia de disponer de datos o valores, bien sean que los incorporemos como parte del programa, o bien que cedamos al usuario (en parte) su introducción mediante algún tipo de interfaz de entrada.
viernes, 13 de septiembre de 2024
TEXTOS. Cadenas.
Variables alfanuméricas o cadenas.
var1 = "1"
print(type(var1))
<class 'str'>
input ("Nombre: ")Nombre: Javier'Javier'
... en el modo directo (desde el Shell) se producirá la ejecución de la instrucción, a la que responderemos (Nombre: Javier) y obtendremos como resultado nuestra respuesta entrecomillada ('Javier'), clara indicación de que el "programa" nos está devolviendo un dato de tipo string.
Pero si la empleamos indirectamente, esto es, asociada a una variable (vsNombre = input("Nombre: " )), también en el Shell, obtendremos como respuesta de ejecución la petición realizada (Nombre:), quedando el programa a la espera de nuestra respuesta (igual que antes), pero a diferencia del procedimiento anterior, una vez que respondemos a la petición de entrada de datos, el programa finaliza o queda a la espera de las siguientes instrucciones, esto es, no produce ninguna salida informativa como sí hizo antes.
Es este el momento en el que entra en acción la función output (salida) print() (print (vsNombre)), que produce aparentemente la misma salida, pero con una diferencia: ahora el string de respuesta no aparece entrecomillado (Javier). Esta pequeña gran diferencia está informando de que la respuesta no es informativa del sistema, es la continuación del programa mostrando la salida esperada en función del procesamiento del dato entrante que previamente hemos suministrado, procesamiento que ha realizado la función print().
Digo pequeña diferencia porque únicamente aparenta ser una cuestión de forma (con vs. sin comillas), pero en realidad es una diferencia grande, dado que afecta a la lógica del funcionamiento del código: quedar a la espera de una nueva instrucción implica solicitar continuidad del procesamiento, que en este caso se concreta como función de salida (print()) (6). Podemos considerar la combinación input() - variable - print() como la base del proceso de programación, esto es, de generación de un procedimiento basado en un algoritmo.
Otras formas de construir estos pequeños "programas" (7), empleando únicamente ambas funciones, es informar primero (mediante print()) de la demanda que sigue, y que se canaliza a través de input(), para devolver finalmente el resultado mediante (de nuevo) la función print():
print("Por favor, dime tu nombre:")
Por favor, dime tu nombre:
vsNombre = input()
Javier
print(vsNombre)
Javier
De estas diferentes formas de trabajar con los procesos de entrada y salida, el más común es el primero, pero todos ellos no dejan de ser variaciones sobre el mismo procedimiento de escaso interés práctico; lo importante es que sobre ellas construiremos el trabajo con los textos, según iremos viendo en las entradas que siguen en esta sección.
jueves, 12 de septiembre de 2024
LENGUAJE
Lógica de programación
- Que existe y se conoce un problema, luego hay un conocimiento "experto" previo y una situación real que se problematiza.
- Que se procede mediante un lenguaje formalizado, dotado de forma y regido por una lógica propia, no siempre equivalente (al menos en lo formal) a otros lenguajes y a otras lógicas. Un lenguaje que, en consecuencia, es necesario comprender y "hablar".
LENGUAJE.
¿Por qué Python para orientadores?
martes, 10 de septiembre de 2024
Python Lenguaje
Funciones para segmentar cadenas
Enumero aquí las principales funciones, ejemplificando su modo de uso, empezando por len().
La función o método len() permite conocer el número de caracteres que contiene una cadena; esto es, devuelve el entero de dicho valor,. En este recuento incluye los espacios que separan las palabras (en caso de tratarse de un string con varias palabras) y los signos de puntuación, que son considerados por len() también como caracteres.
print(len('Hola')) -> 4
print(len('Ho la')) -> 5
print(len('¡Hola!')) -> 6
Este método (len()) también evalúa variables que referencian string
print(len('Maria') -> 5
nom = 'Maria'
print(len(nom)) -> 5
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 mediante el cual 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 la lista de las palabras que forman la frase.
El resultado 'normal' del método split() nos da acceso a una lista que va a sernos de mucha utilidad cuando queramos modificar el contenido de esa lista. Utilizaremos para ello lo que sabemos respecto al manejo de listas: acceso a elementos, sustracció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()
El 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.
TEXTOS. Cadenas.
Concatenar cadenas
No es esta la primera vez que hablo de cadenas y de las formas de concatenación disponibles en Python, pero la revisión de lo hecho y el estudio del tema me han convencido de la necesidad de tratar de nuevo esta cuestión, profundizando más en ella y analizando con cierto detalle los diferentes modos en que se planea este procedimiento de generación de código. La importancia que tiene en procesos de automatización documental justifica sobradamente que preste especial atención al tema.
Tampoco es sobre Python el único lenguaje respecto al cual trato el tema de la concatenación, ya que también dediqué alguna que otra entrada para tratar el tema tanto respecto a las funciones nativas de LibreOffice-Calc como en el lenguaje OOo Basic. De hecho, si vuelvo ahora sobre esta cuestión en Python es precisamente a consecuencia de haber trabajado sobre el mismo tema tomando como referencia el servicio LO-Calc.
Es posible que, al retomar el tema, se produzcan repeticiones de contenido que tal vez depure en una posterior revisión del conjunto de las entradas, pero que ahora sólo puedo lamentar como consecuencia lógica del paso del tiempo y de la complejidad de la temática. Te ruego disculpas, lector, por la molestia que esta repetición te pueda suponer.
Como vimos, en OOo Basic se utilizan dos formas básicas y se puede decir que intercambiables de concatenar cadenas: mediante + y & podemos concatenar tantos segmentos de texto y/o variables como deseemos, sin más límite que la extensión del párrafo que queramos crear y la inteligibilidad del código resultante, a cual, al ser un proceso repetitivo puede ser poco elegante, pero no necesariamente disfuncional o ininteligible.
Recuerdo que en su momento recomendé utilizar en OOo Basic & para concatenar string (y variables string) y reservar + para la operación de sumar, como forma de facilitar la lectura del código, pero se trata de una opción y preferencia personal, sin que exista (que yo sepa) motivación técnica específica para defender esta opción.
Vimos en una entrada anterior que en Python también podemos concatenar cadenas de forma directa mediante , y +, pero presentan limitaciones y restricciones que no se observan en OOo Basic, por lo que son fórmulas no recomendables en cuanto la combinación de cadenas adquiere cierto grado de complejidad, siendo para ello suficiente con que queramos combinar string literal con variables.
Dado que Python es un lenguaje en desarrollo, las versiones que se han ido creando con el paso del tiempo han ido incorporando soluciones diferentes y dejando atrás como obsoletas las que se mostraron limitadas, aunque no por ello dejan de estar disponibles, como pasa con los modelos básicos anteriores.
El último desarrollo en estas funcionalidades son las llamadas cadenas f, de las cuales ya te hablé en esta entrada, pero es posible que dejara por el camino procedimientos interesantes y aun vigentes que surgieron en su momento como respuesta a las demandas del procedimiento. Trataré en esta entrada de tapar estos huecos.
Todo esto es para confirmar que el tema de la concatenación de cadenas ya ha sido tratado en este blog, pero, una vez dicho, paso a indicar que, lo que sigue constituye una reformulación sistemática y ampliada de lo que esas entradas pueden haber recogido, a la vez que una continuidad y conclusión de lo explicado respecto a LibreOffice y OOo Basic en otro blog.
Así que paso a exponer paso a paso el análisis de las diferentes formas de concatenar cadenas en Python. Tomo como referencia lo que expone Alfredo Sánchez Alberca en su material on-line Aprendiendo con Alf, al que remito y del que me declaro deudor.
Expongo en primer lugar diferentes formas de uso de conectores [, y +], que son las formas equivalentes a lo que en OOo Basic son [& y +] respectivamente.
Primera formulación. Concatenación de dos literales con separación de coma (,).
print("Hola","Javier") -> Hola Javier
Segunda formulación. Concatenación de literal y variable con separación de coma (,).
nom = "Javier"
print("Hola",nom) -> Hola Javier
Tercera formulación. Concatenación de dos variables con separación de coma (,).
sal = "Hola"
nom = "Javier"
print("Hola",nom) -> Hola Javier
Cuarta formulación. Concatenación de dos literales con separación de signo (+).
print("Hola"+"Javier") -> HolaJavier
Quinta formulación. Concatenación de literal y variable con separación de signo (+).
print("Hola"+nom) -> HolaJavier
Sexta formulación. Concatenación de dos variable con separación de signo (+).
print(sal+nom) -> HolaJavier
NOTA 1 -> Ambas fórmulas funcionan igual (salvo en determinados casos) siendo los contenidos string, con la única diferencia que el uso de coma (,) genera un espacio de separación entre los componentes, mientras que el uso del signo más (+) no lo genera. Este caso es necesario implementarlo como parte del literal o como cadena formada por un espacio (' ' o " ") y posicionada entre los demás componentes.
Séptima formulación. Concatenación de literal string y literal numeral con coma (,)
print("Número",123) -> Número 123
Octava formulación. Concatenación de literal string y literal numeral con signo (+)
print("Número"+123) -> [TypeError: can only concatenate str (not "int") to str]
print("Número" + str(123)) -> Número 123
NOTA 2 -> Uno de los casos en los que (,) y (+) no funcionan igual es cuando queremos combinar texto y números dentro de la concatenación. En ese caso mientras que podemos hacerlo sin problemas si usamos (,) (como en Séptima), no funciona si usamos (+) (como en Octava). En ésta opción debemos convertir el número antes a string mediante la función str().
En segundo lugar vamos a explicar el uso de la primera fórmula de formateo de cadenas que se empleó en Python desde sus primeras versiones como lenguaje de programación. Se base en el uso del signo %s, siendo % el operador que hace de marcador y s la referencia a la cadena que se anexa. %s que se sitúa necesariamente dentro de la cadena en la posición en la que se desea ubicar el segundo segmento de la cadena y se puede utilizar tantas veces como sea necesario en combinaciones complejas. En estos casos la concatenación utiliza también los signos de las configuraciones ya vistas, especialmente el signo [,].
Al igual que los concatenadores [, y +] presenta también varias formulaciones, que enumeraré siguiendo el orden ya establecido.
Novena formulación. Literal cadena con unión de segundo elemento (cadena).
print('Hola, me llamo %s' % 'Javier') -> Hola, me llamo Javier
Décima formulación. Literal cadena con unión de segundo elemento (número).
print('Número %s' % 123) -> Número 123
Undécima formulación. Literal cadena con unión de variable.
nom = 'Javier'
print('Hola, me llamo %s' % nom) -> Hola, me llamo Javier
NOTA 3 -> En los tres casos el funcionamiento el correcto y el uso y posicionamiento del %s sigue el mismo patrón (se sitúa al final del primer literal), lo es debido al tipo simple de concatenación, pero no responde a una exigencia de la sintaxis de código.
Décimo segunda formulación. Fórmulas mixtas y complejas.
A. print('Hola %s' % nom,',buenos días') -> Hola Javier, buenos días
B. print('Hola %s','buenos días' %nom) -> TypeError: not all arguments converted during string formatting
C. print('Hola %s', buenos días', %nom) -> Hola Javier, buenos díasD. print('Hola %s' % nom,',buenos días') -> Hola Javier, buenos días
E. annos = 24
print('Hola %s' % nombre, ', tienes %s' % annos , 'de edad (eso quisieras)') -> Hola Javier, tienes 24 años de edad (eso quisieras)
F. print('Hola %s, tienes %s' % nom % annos, 'de edad (eso quisieras)') ->TypeError: not enough arguments for format string
NOTA 4 -> Lo que revela esta formulación (y sus variantes) es que es posible concatenar más de una cadena (o componente, ya que también es válido para números y para variables) siempre que se respete la sintaxis de %s que obliga a:
- Posicionar el marcador en la posición requerida por la formulación deseada de la cadena resultante de la concatenación (A)
- Uso de tantos marcadores como sea necesario en función de lo deseado (C, E)
- Pero con restricción de posicionamiento: cada uso de %s debe posicionarse tras la cadena afectada (B,D) y señalar sin ambigüedad a un contenido a anexar, no admitiendo dos marcadores dentro de una subcadena ni dos referencias sucesivas (F)
- La posición de los valores en la cadena-base se identifican con {}
- Esta cadena se sitúa al inicio de la secuencia
- El texto de reemplazo va precedido de la id de a función format()
- ... y se puede hacer por posición de forma implícita o explicitando los valores posicionales...
- ... o bien utilizando la forma diccionario clave:valor
Primera forma.
print('Me llamo {}, vivo en {} y estudio {} en {}'.format('Elvira','Oviedo','Veterinaria', 'León.))
-> Me llamo Elvira, vivo en Oviedo y estudio Veterinaria en León.
Segunda forma.
print('Dame {}, el {} y los {}'.format('la llave inglesa', 'destornillador', 'alicates'))
print('Dame{2}, la {0} y el {1}'.format('llave inglesa', 'destornillador', ' los alicates'))
NOTA 5 -> Las llaves {} indican la posición de los valores de .format(). Tanto en la primera forma como en la primera línea de código de la segunda, aunque no se especifica nada dentro de las llaves, es el orden mismo en que aparecen los valores .format() el que sirve para indicar la posición que ocuparán en el texto. LO que hago con la segunda línea de código de la segunda forma es alterar ese orden indicando dentro de las llaves un número-índice, que es la posición de las entradas en .format().
El texto resultante de 2.1 será Dame la llave inglesa, el destornillador y los alicates y el de 2.2 Dame los alicates, la llave inglesa y el destornillador.
Tercera forma. Uso de variables.
nombre = 'Julia'
localidad = 'Gijón'
estudios = 'Albañilería'
print('Me llamo {}, vivo en {} y estudio {}'.format(nombre,localidad,estudios))
print('Me llamo {1}, vivo en {2} y estudio {0}'.format(nombre,localidad,estudios))
NOTA 6 -> En esta tercera forma sustituimos los valores directos por variables (lo que nos permite, por cierto. modificar interactivamente el contenido) y después empleamos las variables como contenido de .format(). las dos expresiones permiten comprobar que el uso de variables no modifica las propiedades y el modo de funcionar del procedimiento.
Cuarta forma. Clave:Valor
print('Me llamo {nom}, vivo en {local} y estudio {estud}' .format (nom=nombre, local=localidad, estud=estudios))
NOTA 7 -> Sobre la misma base de contenido que en 3, ahora en 4 expongo la forma más evolucionada del procedimiento: una clave identifica y se diferencia del valor o contenido que no es otro que el nombre de las variables. Esa clave es la que se escribe dentro de las llaves, en sustitución y como alternativa del valor-índice empleado en formas previas. La ventaja de esta fórmula es que se asocia al uso de diccionarios.
Finalmente, la cuarta opción ya ha sido específicamente tratada en una entrada de este blog, por lo que no me detendré demasiado en ella. Se trata de las llamadas cadenas f (f-string o formatos literales), que se caracterizan porque su sintaxis incluye F o f al inicio de la cadena, en literales, antes de las comillas. Veamos un ejemplo:
nom1 = 'Juana'
nom2 = 'Lucas'
print(f'Una niña llamada {nom1} juega con un niño llamado {nom2}')
print(f'{nom1}') -> Juana
NOTA 7 -> f-string y .format() son incompatibles, esto es: no se pueden usar en la misma concatenación. En el ejemplo anterior, tercera línea, tanto si eliminamos f como si añadimos format() para identificar la segunda variable o cualquier otra, se produce un funcionamiento anómalo. Obsérvese en la cuarta línea cómo se utiliza f-string cuando iniciamos la cadena con una variable: necesitamos incluirla en una cadena literal, esto es: dentro de comillas (' '/" ") e identificada como tal variable entre llaves. Cualquier otra sintaxis provoca error o respuesta no deseada.
Contamos aun con una última forma de concatenar variables con cadenas, aunque esta quinta opción es en realidad una opción que podemos considerar complementaria de las anteriores, ya que no forma parte de los recursos comunes del lenguaje y precisa importar una librería específica llamada Template y las funciones asociadas a string.
from string import Template
print(Template('Me gusta estudiar $leng').substitute(leng='Python'))
print(Template('Me gusta $accion $leng').substitute(accion='estudiar', leng='Python'))
NOTA 8 -> Puedes observar en estos dos ejemplos la sintaxis del procedimiento, en cierto modo recuerda al uso de funciones y más específicamente a .format():
- Primero llamamos a la función Template()
- Después incluimos dentro de cadena los marcadores, que se identifican mediante la expresión $NomVar.
- Y finalmente, mediante la función .susbtitude(), como parámetros de ellas en, y en formato clave:valor, damos contenido a las variables.