En esta primera parte de la lección, y antes de ver la nueva instrucción iterativa "for in", vamos a profundizar un poco más sobre un tema fundamental en la programación, como lo son las cadenas de caracteres o "strings". ¿Qué es lo nuevo que vamos a ver sobre "strings"? Empezaremos viendo el operador de indexación que nos permitirá acceder a los caracteres individuales que componen una cadena, procederemos a tratar el tema de subcadenas y, por último, trataremos el tema de inmutabilidad. El operador de indexación es el que nos permite acceder a cada uno de los caracteres que componen una cadena. El índice del elemento o del carácter al que queremos acceder debe encerrarse entre corchetes. Si "a" es una cadena, "a" sub "i" es el carácter que ocupa la posición "i" más uno. El primer elemento tiene como índice cero. Eso quiere decir que el primer elemento o el primer carácter de nuestra cadena ocupa la posición cero de la misma. El siguiente estará ubicado en la posición uno, el siguiente en la posición dos y así sucesivamente. Analicemos estos ejemplos de indexación. Supongamos que tenemos la cadena de caracteres "hola, mundo". Si accedemos al carácter que está en la posición cero o en el índice cero, obtendremos la letra "h". Si accedemos a la posición uno, obtendremos el carácter "o". Podemos asignar, también, el "string" a una variable y acceder a los caracteres de dicha variable. Por ejemplo, si vamos a la posición dos obtendremos la "l", si vamos a la posición uno ya sabemos que ahí está la "o". Podemos, también, usar variables como índices para acceder a los caracteres de una cadena. Por ejemplo, creamos la variable "i" a la cual asignamos el valor tres. Si nos referimos a "a" sub "i", donde "a" es nuestra cadena caracteres e "i" es la variable cuyo valor es tres, obtendremos el carácter "a" que se encuentra en la posición tres de nuestra cadena. El último carácter de la cadena, en este caso el punto, se encuentra ubicado en la posición "len" menos uno, esto debido a que la primera posición de la cadena es la cero y, por consiguiente, la última será la longitud de la cadena menos uno. Por consiguiente, si intentamos acceder al elemento que se encuentra en la posición "len" de "a", vamos a generar un error, Python nos protestará. El error es de tipo "IndexError" y el mensaje indica que el índice de la cadena está fuera del rango de valores válidos. Es importante notar que los caracteres de control, como el "backslash n", solo ocupan una casilla dentro de nuestra cadena caracteres. Y también es importante notar que podemos utilizar índices negativos. Los valores negativos acceden a los caracteres de derecha a izquierda. El último carácter de la cadena tiene índice menos uno, el penúltimo menos dos y así sucesivamente. Miremos estos ejemplos. Si accedemos a la posición menos uno, obtendremos el último carácter de la cadena. Este mismo resultado lo obtenemos accediendo a la posición longitud menos uno. Si intentamos extraer el carácter que está en la posición menos tres, encontraremos la "d" y en la posición "a" menos la longitud encontramos el primer carácter de nuestra cadena. Habiendo entendido el operador de indexación y sabiendo que los caracteres ocupan una posición en la secuencia de caracteres de un string, podemos explicar el método "find". En este método, la clase String recibe una cadena y nos dice si esta aparece o no en la cadena sobre la cual se invoca. Por ejemplo, veamos la cadena "Un ejemplo = A" que estamos guardando en la variable "c", queremos buscar si el símbolo de igualdad o el carácter de igualdad se encuentra en dicha cadena. Para eso invocamos al método "find". ¿Cómo funciona este método? Si se encuentra la cadena recibida por parámetro, nos devuelve la posición donde inicia esa cadena. El carácter igual se encuentra, entonces, en la posición 11 de nuestra cadena. Contemos: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 y 11. Perfecto. Podemos, también, buscar subcadenas, no simples caracteres. Así, la subcadena "ejem" empieza en la posición tres de "c", cero, uno, dos y tres, muy bien. Y la subcadena "sa" no se encuentra en nuestro string y, por consiguiente, el método "find" nos devuelve menos uno. Hablemos ahora de subcadenas. Este operador, llamado también "slicing" por su origen en inglés, nos permite extraer un pedazo o una subcadena dentro de la cadena principal; ¿cuál?, el que se encuentra entre las posiciones "n" y "m" menos uno. Veamos algunos ejemplos. Guardamos en una variable "s", la cadena "Piratas del Caribe" y en una nueva variable, "x", extraemos los caracteres que van de la posición cero a la posición seis, porque recuerden que para uno antes de este valor. Por consiguiente, obtenemos la palabra "Piratas"; cero, uno, dos, tres, cuatro, cinco y seis. Ahora, a otra variable, "y", asignamos el resultado de extraer, de nuestra cadena "s", los caracteres que se ubican entre la posición ocho y la diez, esto nos da "d". Y por último, en Z, guardamos los caracteres entre la posición 12 y la 17 y obtenemos "Caribe". Si omitimos el primer índice, en el operador de "slicing", estamos extrayendo la subcadena que empieza en el inicio de la cadena principal. Es así como extrayendo desde nada dos puntos tres, de nuestra cadena manzana, obtenemos la subcadena "man". De igual manera, si omitimos el segundo índice después de los dos puntos, lo que estamos indicando a Python es que queremos extraer la subcadena que empieza en el primer índice y va hasta el final de la cadena. En este ejemplo, obtendríamos la subcadena "zana". Y si omitimos los dos índices, por defecto nos va a entregar, Python, el string completo. Investiga por tu cuenta cómo funciona la extracción de subcadenas cuando especificamos un paso de avance y descubre con qué valores quedan las variables cadena uno, cadena dos y cadena tres en este ejemplo. Investiga bien y responde a la pregunta. Las cadenas de caracteres son inmutables. Esto quiere decir que no podemos cambiar una cadena existente. Si queremos modificar una cadena, debemos crear una nueva copia que sea una modificación de la original. Veamos este ejemplo. Si asignamos la cadena "Hola mi jente" a la variable "saludo" y nos damos cuenta de que hemos cometido un error, escribimos con gente con "j", quisiéramos poder ir a la posición ocho de nuestra cadena y escribir allí el carácter "g", pero Python no nos lo permite. Vamos a encontrar un error de este tipo. Afortunadamente, existe una solución que consiste en extraer de nuestra cadena original los caracteres que van desde la posición cero hasta las siete, es decir, hasta antes de la "j", le concatenados el string "g" y concatenamos desde la posición nueve hasta el final. Como resultado, reemplazamos la "j" por la "g" y obtenemos "Hola mi gente" escrito correctamente. Veamos un ejemplo sencillo, en el cual pondremos en práctica el concepto de indexación dentro de una cadena. Nuestra función "ocurrencias_caracter" tiene como objetivo contar las ocurrencias, es decir, las veces que aparece un carácter recibido por parámetro, dentro de una cadena, igualmente recibida por parámetro. Esa función devuelve un entero, que es la cantidad de veces que el carácter aparece en la cadena. Empecemos. Declaramos una variable "ocurrencias", que inicia en cero, en la cual vamos a estar guardando las veces que el carácter aparece en la cadena. Inicializamos una variable "i", que será nuestro índice para recorrer la cadena en la posición cero. Mientras no hayamos llegado al final de la cadena, esto es, mientras "i" sea inferior a la longitud de la cadena, vamos a comparar cada uno de los caracteres con el carácter recibido por parámetro. ¿Cómo lo hacemos? Preguntamos: si el carácter de la posición "i" dentro de nuestra cadena es igual al carácter recibido por parámetro, incrementamos la cantidad de ocurrencias. Debemos incrementar igualmente nuestro índice "i", garantizando de esa manera, por una parte, que estamos avanzando carácter por carácter dentro de nuestra cadena y que el ciclo llegará a su fin, una vez el índice sea igual a la longitud de la cadena, es decir, cuando la hayamos recorrido completamente. Terminamos retornando el valor de nuestra variable "ocurrencias". Aquí podemos ver varios ejemplos del resultado de la ejecución. Si pedimos a la función que nos busque el carácter "a", esta nos devolverá cinco, pues el carácter aparece cinco veces en "La Casa Blanca". Si mandamos contar las veces que aparece la "B" mayúscula, encontraremos el valor de uno. La "b" minúscula no aparece nunca y la "A" mayúscula, tampoco.