Tutorial de Python 3 y Git

El siguiente es un breve tutorial dirigido a novatos en Python, así como a quienes ya conocen Python 2 y quieren explorar la versión 3. Se preparó para el inicio del grupo de Python en LinuxCabal A.C.

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

Contenido

1   Preparativos

2   Primer programa

  1. Crea una carpeta para el tutorial y entra en ella:

    mkdir tutorial
    cd tutorial
    
  2. Empieza un documento tools.py vacío con el editor.

  3. Copia y pega el texto siguiente:

    def ponComa( numero ):
        '''Regresa numero como cadena con comas.
    
        numero es un entero
        no maneja signo ni punto decimal.'''
    
        cadena = str( numero )
        indice = len(cadena)
        while indice > 3:
            indice = indice - 3
            cadena = cadena[ :indice ] +  ',' + cadena[ indice: ]
        return cadena
    
    if __name__ == '__main__':
        for datoDePrueba in [ 0, 12, 123, 1234, 12345, 123456, 1234567 ]:
            print ( datoDePrueba , ponComa( datoDePrueba ) )
    
  4. Salva el archivo.

  5. Corre el interpretador de Python 3 con tools.py como parámetro para que lo ejecute:

    python3 tools.py
    0 0
    12 12
    123 123
    1234 1,234
    12345 12,345
    123456 123,456
    1234567 1,234,567
    

    Observamos siete renglones en los que aparece un número seguido del mismo número pero con las comas separadoras de millares insertadas. Lo explicaremos en la sección siguiente.

  6. Crea un repositorio vacío en esta carpeta para ir guardando las versiones del tutorial, usando Git:

    git init
    Initialized empty Git repository in tutorial
    
  7. Revisa el estado actual de la carpeta:

    git status
    # On branch master
    #
    # Initial commit
    #
    # Untracked files:
    #   (use "git add <file>..." to include in what will be committed)
    #
    #   tools.py
    nothing added to commit but untracked files present (use "git add" to track)
    
  8. Pide a Git que dé seguimiento a tools.py con add, y observa cómo cambia el estado de la carpeta:

    git add tools.py
    
    git status
    # On branch master
    #
    # Initial commit
    #
    # Changes to be committed:
    #   (use "git rm --cached <file>..." to unstage)
    #
    #   new file:   tools.py
    #
    
  9. Realiza el primer depósito de cambios (check in o commit en Inglés) al repositorio:

    git commit -m 'Commit inicial'
    [master (root-commit) b7952a6] Commit inicial
     1 files changed, 18 insertions(+), 0 deletions(-)
     create mode 100644 tools.py
    
  10. Ahora Git reportará que no hay cambios pendientes. El directorio de trabajo, como Git llama a la carpeta, está igual que la versión en el repositorio:

    git status
    # On branch master
    nothing to commit (working directory clean)
    

Corrimos ya un programa en Python 3, iniciamos nuestro control de versiones de Git en la carpeta y depositamos los cambios hechos. Veremos ahora qué hace tools.py.

3   Análisis de tools.py

El programa tools.py incluye varios aspectos esenciales del lenguaje Python:

 1     def ponComa( numero ):
 2         '''Regresa numero como cadena con comas.
 3
 4         numero es un entero
 5         no maneja signo ni punto decimal.'''
 6
 7         cadena = str( numero )
 8         indice = len(cadena)
 9         while indice > 3:
10             indice = indice - 3
11             cadena = cadena[ :indice ] +  ',' + cadena[ indice: ]
12         return cadena
13
14     if __name__ == '__main__':
15         for datoDePrueba in [ 0, 12, 123, 1234, 12345, 123456, 1234567 ]:
16             print( datoDePrueba , ponComa( datoDePrueba ) )

El programa consta de dos partes:

  1. La que empieza con def en el renglón 1 y llega hasta el renglón 12, es una función de usuario.
  2. La que empieza en el if del renglón 14 y llega hasta el renglón 16, es un bloque de prueba de la función.

Los bloques de comandos están delimitados por la indentación. Pueden haber renglones vacíos para mayor claridad, no interrumpen un bloque. Un bloque termina cuando se regresa a una indentación menor. Los comandos no necesitan ; al final, aunque puede usarse por ejemplo para tener dos o más comandos en un mismo renglon. Veamos ahora renglón a renglón la primera parte:

 1     def ponComa( numero ):
 2         '''Regresa numero como cadena con comas.
 3
 4         numero es un entero
 5         no maneja signo ni punto decimal.'''
 6
 7         cadena = str( numero )
 8         indice = len(cadena)
 9         while indice > 3:
10             indice = indice - 3
11             cadena = cadena[ :indice ] +  ',' + cadena[ indice: ]
12         return cadena

1: Se empieza a definir ponComa con numero como único parámetro.

2 al 5: Tenemos la cadena de documentación de la función. Es una cadena de varios renglones delimitada por triples comillas o apóstrofes en cada extremo. El primer renglón resume la finalidad de la función y lo que regresa. Los renglones siguientes dan más detalles y podrían mostrar ejemplos del uso. Sirve para ayuda interactiva y documentación automática.

7 y 8: Se crean las variables cadena e indice mediante asignaciones. No es necesario declarar las variables antes. str y len son funciones básicas. str regresa numero convertido en cadena, len regresa la cantidad de caracteres de cadena como un entero. Hay más funciones básicas como parte del módulo __builtins__ que se importa automáticamente. Los nombres de variables y funciones pueden tener _ y se toman en cuenta mayúsculas y minúsculas. cadena e indice son variables locales.

9: Tenemos un ciclo while y su expresión condicional, seguido de su bloque de dos renglones.

10: Se decrementa indice.

11: Se recalcula cadena. Hay concatenación de cadenas con +, y slicing: obtención de subcadenas mediante la notación cadena[ i:f ] 'desde i hasta f'. Si falta i es desde el inicio, si falta f es hasta el final. i o f negativos cuentan desde el final de la cadena. Las cadenas sin renglones se delimitan con un solo apóstrofe o comilla en los extremos como 'hola' o "mundo". Todas las cadenas son secuencias de caracteres Unicode.

12: Salida de la función con return, regresando el valor de cadena. Pueden haber dos o más return en una función. Una rutina es simplemente una función que no tiene return y regresa None, o bien que tiene uno o más return pero sin expresión.

Ahora la segunda parte:

14     if __name__ == '__main__':
15         for datoDePrueba in [ 0, 12, 123, 1234, 12345, 123456, 1234567 ]:
16             print( datoDePrueba , ponComa( datoDePrueba ) )

14: tenemos un condicional if y su condición, seguido de un bloque de dos renglones. La expresion '__name__' == '__main__' hace que el bloque se ejecute cuando el programa se corre independientemente, pero no cuando es importado por otro programa.

15: el ciclo for toma uno por uno los elementos de la lista de siete enteros que está representada a la derecha entre paréntesis cuadrados [ y ], asigna el elemento a la variable de ciclo datoDePrueba y ejecuta el bloque. Las listas son secuencias o conjuntos ordenados de cualquier tipo datos: cadenas, otras listas, flotantes, funciones, etc. Tienen métodos para agregar, modificar, ordenar o eliminar elementos, y se obtienen sublistas mediante slicing como con las cadenas. El ciclo for puede usar también una cadena, en ese caso tomará uno por uno los caracteres de ésta.

16: la función básica print envía a la salida estándar los valores de sus argumentos separados por un espacio, que son el valor de datoDePrueba y y la cadena que regresa la función ponComa.

Hemos visto una buena cantidad de puntos esenciales de un programa en Python. Para más detalles consulta la documentación oficial de Python 3.

4   Documentación

  1. Agrega una cadena de documentación de módulo a tools.py, mediante una cadena de varios renglones al inicio, antes de la definición de la función de usuario:

    '''Herramientas para PythonCabal
    
    Rutinas para todo el grupo
    '''
    

    Igual que con las cadenas de documentación de funciones, el primer renglón es un resumen del módulo y los siguientes renglones pueden detallar más cómo se usa, incluso tener ejemplos.

  2. Pide a Git que muestre las diferencias entre la versión del repositorio y la del directorio de trabajo, renglón a renglón:

    $ git diff
    diff --git a/tools.py b/tools.py
    index 719e828..451e102 100644
    --- a/tools.py
    +++ b/tools.py
    @@ -1,3 +1,8 @@
    +'''Herramientas para PythonCabal
    +
    +Rutinas para todo el grupo
    +'''
    +
    
     def ponComa( numero ):
         '''Regresa numero como cadena con comas.
    

    Se indican empezando con + los renglones que han sido agregados. Si se borraron renglones, empezarían con -

  3. Corre la herramienta pydoc con ./tools.py como parámetro para ver la documentación automática en estilo de páginas man:

    $ pydoc ./tools.py
    Help on module tools:
    
    NAME
        tools - Herramientas para PythonCabal
    
    FILE
        /home/pp/ejemplogitborrar/tools.py
    
    DESCRIPTION
        Rutinas para todo el grupo
    
    FUNCTIONS
        ponComa(numero)
            Regresa numero como cadena con comas.
    
            numero es un entero
            no maneja signo ni punto decimal.
    
  4. Ahora genera tools.html mediante la opcion -w de pydoc y muestra el documento con un navegador:

    $ pydoc -w ./tools.py
    
  5. Realiza un segundo depósito de los cambios:

    git commit -m 'Agregar documentacion del módulo tools.'
    

El documento HTML deberá ser similar a éste:

tools-html.png

5   Usando un módulo

Ahora usaremos tools.py como módulo, desde otro programa. No hay que cambiarle nada a tools.py.

  1. Crea un archivo vacío main.py con el editor.

  2. Copia y pega el siguiente programa de Python:

    #! /usr/bin/python3
    
    from tools import ponComa
    
    for n in range(60):
        print( n, ponComa( 2**n ) )
    
  3. Salva el archivo.

  4. Ejecuta este segundo programa:

    python3 main.py
    0 1
    1 2
    2 4
    3 8
    4 16
    5 32
    6 64
    7 128
    8 256
    9 512
    10 1,024
    11 2,048
    12 4,096
    13 8,192
    14 16,384
    15 32,768
    16 65,536
    17 131,072
    18 262,144
    19 524,288
    20 1,048,576
    21 2,097,152
    22 4,194,304
    23 8,388,608
    24 16,777,216
    25 33,554,432
    26 67,108,864
    27 134,217,728
    28 268,435,456
    29 536,870,912
    30 1,073,741,824
    31 2,147,483,648
    32 4,294,967,296
    33 8,589,934,592
    34 17,179,869,184
    35 34,359,738,368
    36 68,719,476,736
    37 137,438,953,472
    38 274,877,906,944
    39 549,755,813,888
    40 1,099,511,627,776
    41 2,199,023,255,552
    42 4,398,046,511,104
    43 8,796,093,022,208
    44 17,592,186,044,416
    45 35,184,372,088,832
    46 70,368,744,177,664
    47 140,737,488,355,328
    48 281,474,976,710,656
    49 562,949,953,421,312
    50 1,125,899,906,842,624
    51 2,251,799,813,685,248
    52 4,503,599,627,370,496
    53 9,007,199,254,740,992
    54 18,014,398,509,481,984
    55 36,028,797,018,963,968
    56 72,057,594,037,927,936
    57 144,115,188,075,855,872
    58 288,230,376,151,711,744
    59 576,460,752,303,423,488
    

    Observamos ahora, en forma similar a cuando ejecutamos tools.py, renglones en los que aparece un número seguido de otro número que va duplicándose cada vez, en el cual vemos las comas separadoras de millares insertadas. Los números del lado izquierdo van desde 0 hasta 59. En seguida lo explicaremos.

  5. Indica a Git que dé seguimiento a main.py y realiza un tercer depósito de cambios:

    $ git add main.py
    $ git commit -m 'Agregar programa que importa el módulo.'
    
  6. Haz ejecutable el archivo main.py y prueba ejecutarlo sin tener que escribir python3 al principio:

    $ chmod u+x main.py
    $ ./main.py
    
  7. Crea un enlace simbólico en la carpeta bin del usuario y prueba correrlo más fácilmente:

    $ ln -s ~/tutorial/main.py ~/bin/main
    $ main
    

6   Análisis de main.py

Este segundo programa nos expone otros aspectos de Python.

1  #! /usr/bin/python3
2
3  from tools import ponComa
4
5  for n in range(60):
6     print( n, ponComa( 2**n ) )

Veamos renglón a renglón:

1: Indicamos al shell de GNU/Linux el interpretador para este archivo, en este caso la ruta al interpretador de Python 3.

3: Hacemos accesible la función ponComa del archivo tools.py mediante from ... import. Al archivo tools.py se le llama módulo y para importar se escribe simplemente tools.

5: El ciclo for toma uno a uno el valor que regresa range, lo asigna a n y ejecuta el bloque. range es una función básica que regresa un iterador, un objeto que en este caso va proporcionando uno a uno los enteros desde 0 hasta 59.

6: La función print envía a salida estándar n, y 2 elevado a la n con las comas separadoras de millares. Se está invocando la función del módulo tools, como si fuera una función definida en main.py.

Otras observaciones:

Los enteros cubren un rango sin límite, tanto en la escritura de enteros como en el resultado de expresiones enteras. El resultado 1000000000000000000000000 + 1 es 1000000000000000000000001. En el renglón 6, 2**n cuando n es 32 o mayor resulta en un entero sin problemas.

Podemos también usar import tools en el renglón 3, pero entonces deberemos usar tools.ponComa en el renglón 6.

range tiene parámetros opcionales: inicio e incremento. Usándolos puede generar diferentes secuencias numéricas variando el inicio, el fin, y el incremento o decremento.

print tiene parámetros con nombre: sep='', end='n' y file=sys.stdout. Son parámetros opcionales que tienen valor predeterminado, y en esta caso permiten cambiar el separador, el terminador y redirigir la salida a un archivo.

Cuando importamos el módulo tools, el bloque de prueba del módulo no se ejecuta, como se comentó en Análisis de tools.py.

7   Historial de versiones

El repositorio Git tiene ya guardadas tres versiones del tutorial. Podemos mostrar todas y saber qué cambió en cada paso.

  1. Listado simple: solamente el comentario, la fecha y el autor:

    $ git log
    
    commit abc5ef53c939cac99e2fc424bce92a85c70dd3f6
    Author: Juan Pérez <jperez@dominio.com>
    Date:   Fri Jun 11 13:21:39 2010 -0500
    
        Agregar programa que importa el módulo.
    
    commit a759985b9ea48b52aa2926ec11c23cd4dbc4470d
    Author: Juan Pérez <jperez@dominio.com>
    Date:   Fri Jun 11 13:19:59 2010 -0500
    
        Agregar documentacion del módulo tools.
    
    commit b7952a632b67405a42257426fe52bda6f24fe763
    Author: Juan Pérez <jperez@dominio.com>
    Date:   Wed Jun 9 18:21:45 2010 -0500
    
        Commit inicial
    
  2. Agrega el parámetro --stat para mostrar la cantidad de renglones agregados y borrados para cada archivo modificado:

    $ git log --stat
    
    commit abc5ef53c939cac99e2fc424bce92a85c70dd3f6
    Author: Juan Pérez <jperez@dominio.com>
    Date:   Fri Jun 11 13:21:39 2010 -0500
    
        Agregar programa que importa el módulo.
    
     main.py |    7 +++++++
     1 files changed, 7 insertions(+), 0 deletions(-)
    
    commit a759985b9ea48b52aa2926ec11c23cd4dbc4470d
    Author: Juan Pérez <jperez@dominio.com>
    Date:   Fri Jun 11 13:19:59 2010 -0500
    
        Agregar documentacion del módulo tools.
    
     tools.py |    5 +++++
     1 files changed, 5 insertions(+), 0 deletions(-)
    
    commit b7952a632b67405a42257426fe52bda6f24fe763
    Author: Juan Pérez <jperez@dominio.com>
    Date:   Wed Jun 9 18:21:45 2010 -0500
    
        Commit inicial
    
     tools.py |   18 ++++++++++++++++++
     1 files changed, 18 insertions(+), 0 deletions(-)
    
  3. Agrega el parámetro -p (de patch) para que se muestre el detalle de los cambios renglón por renglón:

    $ git log -p
    
    commit abc5ef53c939cac99e2fc424bce92a85c70dd3f6
    Author: Juan Pérez <jperez@dominio.com>
    Date:   Fri Jun 11 13:21:39 2010 -0500
    
        Agregar programa que importa el módulo.
    
    diff --git a/main.py b/main.py
    new file mode 100755
    index 0000000..329c902
    --- /dev/null
    +++ b/main.py
    @@ -0,0 +1,7 @@
    +#! /usr/bin/python3
    +
    +from tools import ponComa
    +
    +for n in range(60):
    +    print( n, ponComa( 2**n ) )
    +
    
    commit a759985b9ea48b52aa2926ec11c23cd4dbc4470d
    Author: Juan Pérez <jperez@dominio.com>
    Date:   Fri Jun 11 13:19:59 2010 -0500
    
        Agregar documentacion del módulo tools.
    
    diff --git a/tools.py b/tools.py
    index 719e828..451e102 100644
    --- a/tools.py
    +++ b/tools.py
    @@ -1,3 +1,8 @@
    +'''Herramientas para PythonCabal
    +
    +Rutinas para todo el grupo
    +'''
    +
    
     def ponComa( numero ):
         '''Regresa numero como cadena con comas.
    
    commit b7952a632b67405a42257426fe52bda6f24fe763
    Author: Juan Pérez <jperez@dominio.com>
    Date:   Wed Jun 9 18:21:45 2010 -0500
    
        Commit inicial
    
    diff --git a/tools.py b/tools.py
    new file mode 100644
    index 0000000..719e828
    --- /dev/null
    +++ b/tools.py
    @@ -0,0 +1,18 @@
    +
    +def ponComa( numero ):
    +    '''Regresa numero como cadena con comas.
    +
    +    numero es un entero
    +    no maneja signo ni punto decimal.'''
    +
    +    cadena = str( numero )
    +    indice = len(cadena)
    +    while indice > 3:
    +        indice = indice - 3
    +        cadena = cadena[ :indice ] +  ',' + cadena[ indice: ]
    +    return cadena
    +
    +if __name__ == '__main__':
    +    for datoDePrueba in [ 0, 12, 123, 1234, 12345, 123456, 1234567 ]:
    +        print ( datoDePrueba , ponComa( datoDePrueba ) )
    +
    

8   Ambiente interactivo

  1. Corre el intepretador de Python 3 sin parámetros:

    python3
    
    Python 3.1.1+ (r311:74480, Nov  2 2009, 14:49:22)
    [GCC 4.4.1] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>>
    

    El interpretador avisa con >>> que está esperando un comando.

  2. Importa el módulo tools:

    >>> import tools
    
  3. Para usar la función tenemos que incluir el nombre del módulo:

    >>> tools.ponComa( 12345678 )
    '13,245,678'
    

    En este ambiente no es necesario usar print() para mostrar el resultado.

  4. Para salir:

    *Ctl-D*
    

9   Conclusión

Para conocer mejor el lenguaje y sus características, nada mejor que practicar con proyectos sencillos al principio y poco a poco aumentar la complejidad. Si vives en Guadalajara, asiste al grupo PythonCabal para que conozcas a otros entusiastas de Python y participes en proyectos.

Dive into Python 3 es un tutorial de Mark Pilgrim más detallado que éste, que menciona las diferencias con Python 2.

Conocimos apenas lo básico de Git, para más detalles consulta los tutoriales en la página oficial de Git.