Problema 6.1. Nuestro primer problema es muy simple: Queremos
contar cuántas letras A
hay en una cadena x
.
1. Especificación: Dada una cadena x
, la función retorna un valor contactor que representa cuántas letras A
tiene x
.
2. Diseño: ¿Se parece a algo que ya conocemos?
Ante todo es claro que se trata de un ciclo definido, porque lo que
hay que tratar es cada uno de los caracteres de la cadena x
, o sea que
estamos frente a un esquema:
para cada letra de x averiguar si la letra es "A" y tratarla en consecuencia
Nos dice la especificación que se necesita una variable contador
que
cuenta la cantidad de letras A
que contiene x
. Y por lo tanto
sabemos que el tratamiento es: si la letra es A
se incrementa el
contador en 1
, y si la letra no es A
no se lo incrementa, o sea que
nos quedamos con un esquema de la forma:
para cada letra de x averiguar si la letra es "A" y si lo es, incrementar en 1 el contador
¿Estará todo completo? Alicia Hacker nos hace notar que en el diseño no planteamos el retorno del valor del contador. Lo completamos entonces:
para cada letra de x averiguar si la letra es "A" y si lo es, incrementar en 1 el contador retornar el valor del contador
¿Y ahora estará todo completo? E. Lapurado, nuestro alumno impaciente nos induce a poner manos a la obra y a programar esta solución, y el resto del curso está de acuerdo.
3. Implementación
Ya vimos que Python nos provee de un mecanismo muy poderoso para
recorrer una cadena: una instrucción for
que nos brinda un carácter
por vez, del primero al último.
Proponemos la siguiente solución:
def contarA(x):
for letra in x:
if letra == "A":
contador = contador + 1
return(contador)
Y la probamos
>>> contarA("Ana")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in contarA
UnboundLocalError: local variable 'contador' referenced
before assignment
>>>
¿Qué es lo que falló? ¡falló el diseño! Evidentemente la variable
contador
debe tomar un valor inicial antes de empezar a contar las
apariciones del caracter A
. Volvamos al diseño entonces.
Nota Es muy tentador quedarse arreglando la implementación, sin volver al diseño, pero eso es de muy mala práctica, porque el diseño queda mal documentado, y además podemos estar dejando de tener en cuenta otras situaciones err6neas.
4. Diseño (revisado) Habíamos llegado a un esquema de la forma
para cada letra de x averiguar si la letra es "A" y si lo es, incrementar en 1 el contador retornar el valor del contador
¿Cuál es el valor inicial que debe tomar contador
? Como nos dice la
especificación contador
cuenta la cantidad de letras A
que tiene la
cadena x
. Pero si nos detenemos en medio de la computación, cuando
aún no se recorrió toda la cadena sino sólo los primeros 10
caracteres, por ejemplo, el valor de contador
refleja la cantidad de
A
que hay en los primeros 10 caracteres de x
.
Si llamamos parte izquierda de x
al segmento de x
que ya se
recorrió, diremos que cuando leímos los primeros 10 caracteres de x
,
su parte izquierda es el segmento x[0:10]
.
El valor inicial que debemos darle a contador
debe reflejar la
cantidad de A
que contiene la parte izquierda de x
cuando aún no
iniciamos el recorrido, es decir cuando esta parte izquierda es x[0:0]
(o sea la cadena vacía). Pero la cantidad de caracteres iguales a A
de la cadena vacía es 0
.
Por lo tanto el diseño será:
inicializar el contador en 0 para cada letra de x averiguar si la letra es "A" y si lo es, incrementar en 1 el contador retornar el valor del contador
(lo identificaremos como el esquema Inicialización - Ciclo de tratamiento - Retorno de valor). Pasamos ahora a implementar este diseño:
5. Implementación (del diseño revisado)
def contarA (x):
""" La funcion contarA(x) cuenta cuántas
letras "A" aparecen en la cadena x ."""
contador = 0
for letra in x:
if letra == "A":
contador = contador + 1
return(contador)
6. Prueba
>>> contarA ("banana")
0
>>> contarA ("Ana")
1
>>> contarA ("lAn")
1
>>> contarA ("lAAn")
2
>>> contarA ("lAnA")
2
>>>
7. Mantenimiento:
Esta función resulta un poco limitada. Cuando nos pidan que contemos
cuántas letras E
hay en una cadena tendremos que hacer otra función.
Tiene sentido hacer una función más general que nos permita contar
cuántas veces aparece un carácter dado en una cadena.
Ejercicio 6.4. Escribir una función contar(l, x)
que cuente
cuántas veces aparece un carácter l
dado en una cadena x
.
Ejercicio 6.5. ¿Hay más letras A
o más letras E
en una cadena?
Escribir un programa que lo decida.
Ejercicio 6.6. Escribir un programa que cuente cúantas veces aparecen cada una de las vocales en una cadena. No importa si la vocal aparece en mayúscula o en minúscula.