23 de marzo de 2015

Curso de Python para biólogos - Lección 5. Funciones y ejercicios prácticos

Hoy descansaremos un poco y sólo explicaremos un nuevo concepto teórico, pero muy importante, las funciones en Python. Tras ello se propondrán varios ejercicios para aplicar los conocimientos adquiridos en las lecciones previas (1, 2, 3 y 4).

Funciones en Python

Una función es un bloque de código que toma ciertos datos o variables como argumentos y devuelve otros datos o variables como resultado. Aunque no nos hayamos dado cuenta, ya hemos usado funciones anteriormente: print(), input(), int(), str(), len(), type(), min(), max()...dichas funciones vienen por defecto con Python y alguien las ha escrito previamente para que nosotros las podamos usar. La importancia fundamental de las funciones es que nos permiten escribir un código una sola vez y utilizarlo todas las veces que sea necesario sin volver a escribirlo, lo cual nos ahorra tiempo y simplifica los programas.

Las funciones se especifican con 'def' seguido del nombre de la función y entre paréntesis tantas variables como argumentos utiliza, estas variables guardarán los argumentos que demos al llamar a la función. No hay que olvidar los dos puntos al final de esta primera línea y escribir el bloque de código de la función tabulado (4 espacios). Al final de la función el resultado de la misma se devuelve con el comando 'return'. Para ejecutar o llamar una función simplemente hay que escribir su nombre y entre paréntesis sus argumentos. El resultado/s de las funciones los podemos guardar en variables o usarlos directamente.

Veamos en el primer ejemplo cómo escribir una función que realiza la suma de dos números y la devuelve como resultado. En el segundo ejemplo, la función recibe un nombre y devuelve una frase dando la bienvenida.

Ejercicio 1: Calcular el factorial de un número

El factorial de un número se define como el producto de todos los números enteros positivos desde 1. El ejercicio propuesto consiste en escribir una función que lo calcule usando un bucle 'while' que vaya restando (o sumando) número a número y guardando el resultado de la multiplicación por el anterior. No vale mirar en Google y usar funciones ya escritas.

Ejercicio 2: Contar el número de nucleótidos en una secuencia de DNA

Ahora escribiremos una función que cuente el número de pares de bases de una secuencia de DNA tomada como argumento de la función. Creo que este problema será más sencillo que el anterior, el código de la función puede ocupar tan sólo una línea, pero sugiero utilizar el bucle 'while' para leer letra a letra y aprender más.

Ejercicio 3: Encontrar un codón de inicio de la traducción en una secuencia de DNA

El ejercicio consiste en encontrar el codón de inicio de la traducción, osea la palabra 'ATG', en una secuencia de DNA. La función puede ser muy sencilla utilizando expresiones regulares, pero como no las hemos estudiado todavía, propongo reutilizar el código del Ejercicio 2 que debería leer letra a letra la secuencia e ir extrayendo palabras de 3 letras en cada iteración del bucle. Comprobar si la palabra es 'ATG' con una sentencia condicional, si lo es retornar la posición como resultado de la función, y si no seguir hasta terminar de leer toda la secuencia.

Ejercicio 4: Calculando una secuencia consenso

El último ejercicio de hoy consiste en escribir una función que tome como argumentos 3 secuencias de DNA (preferiblemente de la misma longitud, para evitar problemas y errores, si no calcular el consenso hasta la longitud de la secuencia más corta) y devuelva una única secuencia que contenga en cada posición el nucleótido más frecuente o en su defecto la letra 'N'. Este ejercicio es el más complejo y requiere utilizar bucles 'while', sentencias condicionales...


Buena suerte y nos vemos en la próxima lección.

19 de marzo de 2015

Curso de Python para biólogos - Lección 4. Entrada de datos y bucles while

En esta nueva lección aprenderemos a pedir datos al usuario desde nuestro programa y a realizar nuestros primeros bucles. Como veremos, un bucle consiste en repetir un bloque de código varias veces sin tener que volver a escribirlo.

Entrada de datos desde la línea de comandos

A veces necesitaremos introducir datos en nuestro programa de forma interactiva, lo que significa que preguntaremos o pediremos al usuario cierta información (por ej. linux siempre nos pregunta antes de instalar un nuevo programa y debemos responder 'yes' o 'no'). En Python se utiliza la función 'input', dicha función devuelve el texto introducido por el usuario antes de pulsar Enter. El texto tendrá formato de cadena (string), por lo que no podrá ser utilizado directamente en caso de ser un número, habrá que convertir la cadena en número.

Conversión entre diferentes formatos de datos

Muchas funciones y métodos de Python sólo aceptan un tipo de datos, por ejemplo 'print' requiere cadenas o las operaciones aritméticas requieren números. Los tipos de datos que conocemos son: números, cadenas, listas y diccionarios. Simplificando, en Python existen 2 clases de números, los enteros (int) y los decimales (float). Por ello es importante conocer cómo convertir una cadena (devuleta por la función 'input' por ejemplo) en un número antes de realizar operaciones aritméticas, o convertir un número en una cadena antes de imprimirlo.
Si intentamos elevar al cuadrado un número introducido mediante 'input' nos dará error, porque antes deberemos convertir la cadena devuelta por 'input' en un tipo de número (int o float).
Si el texto devuelto por 'input' contiene decimales, al intentar convertirlo en número entero nos devolverá un error. La solución es convertirlo a decimal primero. Pero cuidado, operar con números enteros es diferente que con números decimales, y los resultados pueden variar mucho.

Validación de datos con 'try' y 'except':

Como hemos visto en los ejemplos anteriores, muchas veces tenemos errores al intentar operar con los diferentes tipos de datos. Una forma de evitar problemas es detectar los errores con la sentencia 'try:' y evitar que se ejecute el código que origina el error para ejecutar un código alternativo especificado por 'except:'. Se podría traducir cómo: "en caso de error... hacer lo siguiente...".
 Notar cómo siempre hay diferentes maneras de hacer lo mismo...
Pero 'try' y 'except' no son milagrosos, no permiten por ejemplo corregir errores en la sintaxis de nuestro código, como puede ser olvidarnos un paréntesis o unas comillas.

Bucles 'while':

Por fin vamos a adentrarnos en el fascinante mundo de los bucles. Un bucle es un bloque de código que es ejecutado varias veces, pero sólo hay que escribirlo una vez :)

La particularidad de un bucle 'while' es que es ejecutado indefinidamente (bucle infinito) mientras la condición que le sigue es cierta (True). Como en el caso de las sentencias condicionales con 'if', el código a ejecutar mientras se cumpla la condición debe ser tabulado 4 espacios para ser reconocido por Python. Veamos unos ejemplos.
Empecemos a aplicar los conocimientos adquiridos y veamos cómo usar sentencias condicionales (if...elif...else...) dentro de un bucle, la tabulación será muy importante...

Ejercicio1. Programa para adivinar un número:

Para terminar la lección haremos dos ejercicios muy interesantes. El primero será escribir un código que genera un número aleatorio entre 1 y 100, y nos preguntará sucesivante por el número hasta que lo adivinemos. Las primeras líneas (from random import randint y number=randint(1,100)) son necesarias para generar el número aleatorio guardado en la variable 'number' pero serán explicadas en próximas lecciones.
Pero, qué pasa si nos equivocamos y no escribimos un número? El programa devolverá un error a no ser que nos preparemos para ello:

Ejercicio2. Cantar una canción

En el último ejercicio de hoy, crearemos un código que nos pida escribir una canción línea a línea y después la mostrará en pantalla 2 veces, imprimiendo línea por línea con un bucle 'while'.
  
Próxima lección: bucles 'for' 




9 de marzo de 2015

Curso de Python para biólogos - Lección 3. Data comparison and conditional statements

Comenzamos la semana con una nueva lección de Python, todavía no quedan un par de lecciones de conceptos básicos antes de empezar a hacer algún pequeño programa para resolver problemas biológicos. En la presente lección explicaremos cómo se pueden comparar datos y condicionar la ejecución del código de acuerdo a dichas comparaciones.



Expresiones booleanas

Una expresión booleana es una comparación entre 2 valores o variables que devuelve un resultado de cierto (true) si ambos valores son iguales o ambas variables contienen el mismo valor y falso (false) si son diferentes. True y false son los dos únicos valores de otro tipo de datos llamado booleano (pero no queremos explicar más tipos de datos, con los ya vistos es suficiente: números, cadenas, listas y diccionarios).

Operadores de comparación y lógicos

Se denominan operadores de comparación a las expresiones mostradas en la imagen (==, !=, <, >, <= y >=), permiten realizar comparaciones de dos valores o variables con 2 únicos posibles resultados: true o false.
Los comparadores lógicos son 'and', 'or' and 'not' y permiten combinar diferences comparaciones. En la tabla se muestran los posibles resultados. 'and' da como resultado true si todas las comparaciones son ciertas y false si una de ellas es falsa. 'or' devuelve true si al menos una de las comparaciones es cierta y false si todas son falsas. 'not' cambia el resultado de una comparación de true a false o al contrario.
 Veamos unos ejemplos:

Sentencias condicionales

Una sentencia condicional decide si se ejecuta o no el código indentado que le sigue a continuación, si la comparación es cierta el código se ejecuta, si es falsa no sucede nada. Las sentencias condicionales se escriben con el operador 'if' seguido de una comparación y termina con dos puntos ':'. En las siguientes líneas se escribe el código indentado con espacios o tabulador (recomendado 4 espacios). El código indentado sólo se ejecutará si la comparación da como resultado true.
Las sentencias condicionales se pueden hacer más completas añadiendo condiciones con el operador 'elif'. Si la primera condición (con 'if') no se cumple, se pasará a comprobar si se cumple la segunda (con 'elif') y así sucesivamente hasta que se agoten las condiciones. Si todas las comparaciones con 'if' y 'elif' son falsas, entonces se ejecutará el código especificado por el operador 'else'.
Para usar las sentencias condicionales con listas, o con valores de diccionarios (recordar dict.values() devuelve una lista de los valores asociados a las claves y dict.keys() devuelve una lista de todas las claves) existe la expresión if in :. Dicha expresión permite buscar un valor en una lista y si lo encuentra ejecuta el código indentado. Es una expresión muy útil que usaremos en futuras lecciones.

Condicionales anidados

Para terminar por hoy veremos une ejemplo donde hay una combinación de comparaciones y operadores lógicos muy larga y que hace confuso el código (lo que también propicia errores al escribirlo, por ejemplo si nos dejamos un paréntesis). El mismo código se puede escribir introduciendo unas sentencias condicionales dentro de otras, el código es más largo, pero también más claro y conciso. Cada sentencia condicional que se escribe debe ser indentada, si escribimos una sentencia condicional dentro de otra deberemos indentar el doble de espacios.

Próxima lección

En la próxima lección veremos como pedir al usuario que introduzca datos y cómo realizar bucles 'while'.


21 de febrero de 2015

Curso de Python para biólogos - Lección 2. Nuevos tipos de datos: listas, diccionarios y matrices

Volvemos con una nueva lección...
por motivos de tiempo, esta vez voy a incluir las diapositivas en inglés, aunque traduciré las explicaciones ;)

También sería gratificante que si seguís el curso y os parece útil hiciérais algún comentario para ver si alguien lo usa o es un tutorial más de Python en internet...

En esta nueva lección introduciremos dos tipos más de datos: las listas y los diccionarios. Recordad que en la lección anterior vimos los números y las cadenas de texto, además de aprender a instalar Python en Windows y a ejecutar comandos en una consola




¿Qué es una lista?

Una lista es un listado de valores, y se introducen separados por comas y entre corchetes. Dichos valores suelen ser números o cadenas, pero también pueden ser otros tipos de datos como veremos posteriormente. En Perl las listas se llaman arrays o arreglos.
Para referirnos a un elemento de la lista, deberemos conocer su posición. Dicha posición se llama índice (index) y las posiciones de los elementos en las listas comienzan en 0 (como en las cadenas). Al igual que las cadenas, las listas pueden ser troceadas, pero además los elementos de una lista también pueden ser modificados.

¿Cómo modificar una lista?

Las listas poseen un conjunto de métodos o funciones que permiten hacer diversas cosas con ellas, por ejemplo insertar elementos, eliminarlos, extraerlos, ordenarlos, contarlos... Dichos métodos se aplican escribiendo el nombre de la lista sequido de un punto, el método y entre paréntesis sus parámetros si es que los requiere (el paréntesis es obligatorio pero puede estar vacío).
 Veamos unos ejemplos:
 Pero cuidado, a cada método hay que darle los parámetros adecuados entre paréntesis:
Veamos la diferencia entre el método 'pop' que extrae un elemento indicando su posición y lo borra de la otra forma de modificar el elemento sin borrarlo. También los métodos 'append' e 'insert':
Podemos borrar elementos de una lista con la función 'del', pero cuidado porque podemos borrar la lista completa... ('del' no es un método por ello no requiere punto ni paréntesis)

Copia por valor y por refencia

Creo que este concepto merece pararnos y explicarlo más en detalle. Normalmente estamos acostumbrados que cuando copiamos algo sea una copia por valor, es decir, que si modificamos la copia no se modifique el original. Pero éste no es el comportamiento por defecto de Python, por motivos de eficiencia Python siempre copia por referencia los datos si no se indica lo contrario. La copia por referencia es una copia de las posiciones en memoria de los datos, de forma que si modificamos posteriormente la copia también se mofica el original porque guardan los datos en el mismo lugar de la memoria.
Para hacer copia por valor de una lista deberemos utilizar el método 'copy'. Si usamos el símbolo '=' se realizará una copia por referencia.

¿Qué es un diccionario?

Un diccionario se parece a una lista, pero en vez de ordenar sus elementos o 'valores' e identificarlos por su posición o índice, un diccionario no ordena sus elementosy los identifica por la llamada 'clave'. La clave es normalmente un texto que nos ayuda a localizar su contenido asociado en el diccionario, este contenido es el valor. Los diccionarios en Perl se llaman hashes o arreglos asociativos.

Un diccionario se define entre llaves, y en su interior se incluye una lista de pares clave:valor separados por comas.
Los pares clave:valor de un diccionario NO están ordenados y  no podemos referirnos a ellos mediantes índices, la única forma de llamar a un valor del diccionario es conociendo su clave asociada. De la misma forma que con las listas, el comando 'del' permite borrar pares clave:valor del diccionario, o el diccionario completo.

¿Cómo modificar un diccionario?

Al igual que las listas, los diccionarios tienen un conjunto de métodos que nos permiten modificarlos.
Los métodos 'keys' y 'values' devuelven una lista de las claves o valores respectivamente, el método 'items' devuelve una lista de pares (clave, valor). Los métodos 'get', 'pop', 'clear' y 'copy' funcionan de forma similar a como lo hacen con las listas. Realicemos unos cuantos ejemplos:

Funciones para cadenas, listas y diccionarios

Existen un conjunto de funciones u operaciones comunes para estos tres tipos de datos, se listan a continuación:
 
Permiten conocer su longitud (o número de elementos o pares clave:valor), el tipo de datos guardado en una variable o convertir un tipo de datos en otro tipo diferente:
 

Listas anidadas o listas de listas

Una lista anidada, del inglés nested list, es una lista formada por varias listas, si éstas contienen sólo números podríamos pensar como si fuera una matriz:
Pero además de incluir en una lista otras listas, podemos incluir otros tipos de datos como un diccionario. En este caso no podremos acceder a los datos del diccionario usando índices.
  
Diccionarios anidados

Al igual que en el caso de las listas, podemos crear diccionarios de diccionarios (anidados). También podemos mezclar listas en diccionarios y otros tipos de datos.

Próxima lección

La cosa se va complicando, números, cadenas, listas, diccionarios... mix!!! y además cada tipo de datos tiene asociado unos métodos y operaciones para modificarlos. En el próximo capítulo la cosa se complica y aprenderemos a comparar los datos y poner condiciones al comportamiento de un programa.