Tutorial de Python 3 y Git II

Esta es la segunda parte del tutorial para el grupo de Python en LinuxCabal A.C.

Autor:Patricio Páez
Contacto:nospam en pp.com.mx
Fecha:2010-06-21
Versión:1

Contenido

1   Preparativos

Empezamos con una carpeta de trabajo con los archivos tools.py y main.py y el repositorio Git con dos o tres versiones ya registradas, y sin cambios pendientes de registrar: git diff no debe mostrar diferencias.

2   Git

2.1   Ramas y fusiones

  1. Cambia a la carpeta del tutorial:

    cd tutorial
    
  2. Muestra cuántas ramas hay:

    git branch
    

    Puedes usar el comando anterior después de los siguientes comandos para observar los cambios.

  3. Crea una nueva rama:

    git branch jonatan
    
  4. Cambia a esa rama:

    git checkout jonatan
    
  5. Realiza en tools.py los siguientes cambios propuestos por Jonatan Rico, remplazando la línea:

    while indice > 3:
    

    por:

    # soporte punto décimal
    punto = cadena.rfind('.')
    indice = indice if punto < 0 else punto
    # soporte signo
    inicio = 1 if cadena[0:1] == '-' else 0 #
    while indice - inicio > 3:
    
  6. Prueba que funcione:

    python3 tools.py
    
  7. Registra los cambios:

    git commit -a -m 'Propuesta de Jonatan'
    
  8. Cambia a la rama principal:

    git checkout master
    
  9. Crea y cambia a una nueva rama:

    git branch pruebas-merge
    git checkout pruebas-merge
    
  10. Muestra las diferencias entre esta rama y la rama jonatan:

    git diff jonatan
    
  11. Junta los cambios de la rama jonatan en la rama pruebas-merge:

    git merge jonatan
    

Cuando hay modificaciones en los mismos renglones de un archivo en ambas ramas y Git no pueda fusionar los cambios, avisará que no se hizo la fusión (unmerged en Inglés) y nos dejará marcas en el archivo para que nosotros editemos, aprobemos o rechacemos lo adecuado y finalmente registremos los cambios con git commit -a.

2.2   Crear parches

  1. Todavía en la rama pruebas-merge, haz un cambio a tools.py.

  2. Genera un parche de ese cambio:

    git diff > uncambio.patch
    

2.3   Guardar cambios

  1. Los cambios de la sección anterior no nos van a servir ahora, pero los guardamos para más adelante:

    git stash save 'Prueba de un cambio'
    git diff
    

    El directorio de trabajo queda limpio.

  2. Lista los diferentes cambios guardados:

    git stash list
    
  3. Si necesitas, los puedes aplicar de nuevo con:

    git stash apply stash@{n}
    

    stash@{0} es el valor por omisión

2.4   Aplicar un parche

  1. Aplica los cambios que guardaste en el parche anterior:

    git apply uncambio.patch
    

3   Python

3.1   Clases

  1. Agrega estos dos bloques a tools.py:

    class Robot:
        "Un robot con nombre, posición y dirección."
    
        def __init__( self, nombre, posicion=(0,0) , direccion='N' ):
            "Constructor"
            self.nombre = nombre
            self.x, self.y = posicion
            self.direccion = direccion
    
        def avanza( self, direccion='' ):
            "Avanza posición del robot y regresa nueva posición.  Opcionalmente, cambia su dirección."
            if direccion:
                self.direccion = direccion
            if self.direccion == 'N':
                self.y = self.y + 1
            elif self.direccion == 'E':
                self.x = self.x + 1
            elif self.direccion == 'S':
                self.y = self.y - 1
            elif self.direccion == 'O':
                self.x = self.x - 1
            return self.x,self.y
    
    class RobotPlus( Robot ):
        "Robot que reporta."
    
        def reporta( self ):
            return 'Soy ' + self.nombre + ' y estoy en (' + str(self.x) + ', ' + str(self.y) + '), ' + self.direccion
    
        def __repr__( self ):
            return self.reporta()
    

3.2   Análisis de las clases

Hemos agregado dos bloques, cada bloque es la definición de una clase. Los nombres de las clases se acostumbran escribir con mayúscula al principio. Igual que las funciones, tenemos una cadena de documentación al inicio de la definición, y después siguen definiciones de funciones, que se conocen como métodos de la clase. Las funciones siempre tienen un parámetro que por convención se llama self y es la clase o instancia a la cual pertenece.

El primer bloque define Robot con dos métodos: __init__ y avanza. El primero es el nombre especial del constructor, que es invocado cuando se crea una instancia de esta clase. En este caso __init__ crea cuatro variables o atributos de instancia. Los parámetros posicion y direccion son opcionales. posicion es una tupla. Las tuplas con secuencias de datos de distintos tipos como las listas, pero no se pueden modificar. Se representan entre paréntesis.

La función avanza modifica los atributos x y y en base al valor de dirección y regresa los nuevos valores como una tupla. Opcionalmente direccion puede modificarse al invocar la función.

La segunda clase RobotPlus es una clase derivada de la anterior, y por herencia tiene también sus métodos. Esta clase agrega un nuevo método reporta que regresa un mensaje informativo de los atributos de la instancia. La función __repr__ sobreescribe el método del mismo nombre predeterminado de todas las clases. Este método es invocado por ejemplo cuando se da el nombre de la instancia en el ambiente interactivo o en la función print().

Para crear una instancia se asigna la clase a una variable:

r1 = Robot( 'Alfa' )
r2 = Robot( 'Beta' )

3.3   Tarea

  1. Modifica Robot para que el movimiento pueda ser en las direcciones a 45 grados: NE, NO, SO y SE.
  2. Modifica Robot para que el incremento de avanza pueda ser distinto de 1.
  3. Agrega un método a Robot que permita desplazarse en x y y a arbitrariamente.