1. No desesperes. La magia en la programación no existe. Si el código falla, es porque algo hemos hecho mal.
  2. Lee detenidamente el error que Python devuelve (presta atención a las últimas líneas donde se detalla línea en la que falla, método o algoritmo donde se produce y descripción del error). Un ejemplo:
    Traceback (most recent call last):
      File "", line 1, in 
      File "presupuesto.py", line 158, in 
        presupuesto = ModeloDePresupuesto()
      File "presupuesto.py", line 152, in __init__
        self.set_datos_basicos() 
      File "presupuesto.py", line 45, in set_datos_basicos
        self.seleccionar_plan()
      File "presupuesto.py", line 59, in seleccionar_plan
        elegir_plan = int(elegir_plan)
    ValueError: invalid literal for int() with base 10: ''
    >>> 
  3. Intenta resolverlo tu mismo ¿cómo?
    1. lee la descripción del error y piensa como se produjo (es decir, cuál fue el paso previo)
    2. verifica la línea de código donde se produjo el error ¿sintaxis?
    3. Compara el código con el del ejemplo. ¿Lo ves igual? Entonces no pierdes nada, copiándolo textualmente de nuevo.
    4. ¿Sigue fallando? busca el error en Internet (¿Google?)
  4. Si no logras resolverlo, busca ayuda: aquí, en foros o listas de correo, PERO, previamente ten en cuenta:
    1. Copia el error completo, tal cual se muestra y colócalo como referencia en tu post
    2. Copia tu código en algún sitio que te permita compartir y corregir código públicamente, como por ejemplo http://pastebin.lugmen.org.ar/
    3. Coloca en tu post, un enlace hacia el código del Pastebin

Pero ¿por qué tanto lío si es más sencillo preguntar y listo?. Créeme: no lo es. Podrá ser simple preguntar sin intentar resolverlo, pero será complejo cuando comiences a leer las posibles soluciones, pues pueden no estar basadas en la verdadera causa (nadie está allí para conocer tu código ni como se produjo el error). Y por otro lado, si no intentas resolverlo tu mismo, te será más difícil aprender.

Ahora sí, retomemos nuestro código!

Definición de funciones en Python

def set_cliente(self):

Una función (o método) es la forma de definir una determinada acción que realiza un objeto.

Definir Funciones

Para definir una función, se escribe:

def nombre_de_la_funcion(parámetros):
    # aquí escribimos el código que realiza la acción que definimos

Los parámetros son datos contenidos en variables (una o más), que la función necesitará para realizar la acción. No siempre son necesarios. En nuestro caso, el parámetro self indica que la función requerirá de los atributos contenidos en la clase (los que ya vimos recientemente).

Por ejemplo: self.empresa está llamando al atributo “empresa” de la clase.
Mientras que mediante: self.empresa = 'Maestros del Web', le estoy asignando el valor “Maestros del Web” al atributo empresa de la clase (recuerda que un atributo es una variable).

Referencia a propiedades

Cuando necesito recurrir a un atributo de la clase, dentro de una función, escribo self.nombre_del_atributo

Todo el código contenido dentro de una función (es decir, el que esté debajo de la definición de la función, con tabulado), se llama algoritmo, y es el que indicará a la función, qué es lo que debe hacer.

Interactuando con el usuario mediante raw_input

    def set_cliente(self): 
        self.empresa = raw_input('\tEmpresa: ')
        self.cliente = raw_input('\tNombre del cliente: ')

raw_input() es una función. Pero no la definimos nosotros, sino que es una función nativa de Python.

La acción que realiza raw_input('Texto que le mostraré al usuario'), es:

  1. Muestra al usuario el texto que se encuentra entre comillas, dentro de los parántesis (es decir, que este texto es un parámetro requerido por la función)
  2. Espera que el usuario escriba algo
  3. Luego, almacena lo que el usuario escribió. En nuestro caso, será almacenado en los atributos de la clase, empresa y cliente.

Float() otra función nativa (propia) de Python

 
		importe = raw_input('\tImporte bruto: $') 
		self.importe = float(importe)

Hemos almacenado en la variable “importe” un dato ingresado por el usuario:

importe = raw_input('\tImporte bruto: $')

Luego, asignamos esa variable (importe) como valor del atributo importe, pero esta vez, es el atributo importe de la clase:

self.importe = float(importe)

Funciones nativas

Float() al igual que raw_input() es una función nativa de Python. Su acción consiste en convertir en número flotante (es decir, con decimales), el número que le sea pasado como parámetro.

Operadores matemáticos: Sumar, restar, dividir y multiplicar con Python

        self.monto_iva = self.importe*self.alicuota_iva/100 
        self.neto = self.importe+self.monto_iva 

Podemos realizar sumas, restas, multiplicaciones y divisiones con Python. Y podemos almacenar los resultados de nuestras operaciones matemáticas en variables, incluso aquellas que sean atributos de la clase.

Podemos realizar operaciones matemáticas con números: 1+1 y también con variables cuyos valores sean números: variable_1+variable_2

Operadores matemáticos

Para sumar, utilizamos +
Para restar utilizamos
Para dividir flotantes utilizamos /
Para dividir enteros utilizamos //
Para multiplicar utilizamos *
Para obtener el resto de una división utilizamos %
Para exponenciar utilizamos **

El operador matemático suma (+)

        txt = '\n'+self.divline+'\n' 
        txt += '\t'+self.encabezado_nombre+'\n' 

El operador matemático + no solo sirve para sumar números. También sirve para concatenar cadenas de texto (es decir, unirlas). Fíjate esta línea:

txt = '\n'+self.divline+'\n'

Estoy diciendo que la variable txt es igual a:
la cadena de texto ‘\n’ (\n significa salto de línea)
más el texto contenido en el atributo divline de la clase
más nuevamente, una cadena de texto ‘\n’

Luego, mira la línea que le sigue:

txt += '\t'+self.encabezado_nombre+'\n'

Estoy diciendo aquí, que a la variable txt de antes, le agregue ahora, todo lo demás:
La cadena de texto ‘\t’ (\t significa tabular)
el texto contenido en el atributo encabezado_nombre de la clase
más finalmente, la cadena de salto de línea ‘\n’

Dando formato a cadenas de texto

        txt += '\tImporte: $%0.2f | IVA: $%0.2f\n' % (self.importe,
                                                      self.monto_iva) 

¿Haz visto lo difícil de entender que parece este código? Pues ¡Piérdele el miedo! Es mucho más sencillo de lo que parece.

Python nos da la posibilidad de utilizar comodines en nuestras cadenas de texto, para poder reemplezar datos, que necesiten un formato especial.

El comodín es el signo del porcentaje %.

A este comodín, le segurirá un patrón, que identifique el tipo de dato (formato) que queremos darle al dato.

Por ejemplo: %0.2f, está indicando que en ese lugar (en vez del comodín y el patrón), debe ir un número flotante con dos decimales. Es decir que el patrón 0.2f significa número con dos decimales.

Hasta allí, entonces, asignamos comodines y patrones. Pero luego, hay que decirle a Python qué datos debe formatear. Para ello, luego de la cadena de texto, escribimos un comodín % segudio de un espacio, y entre parantésis y separados por coma, las variables que contienen los datos a reemplazar.

Veámoslo con otro ejemplo:

a = 10
b = 5
resultado = "%0.2f y %0.2f son dos números flotantes" % (a, b)

Eso, sería como haber escrito esto:

resultado = "10.00 y 5.00 son dos números flotantes"

Imprimiendo texto en la pantalla

print txt

Cuando quieres mostrar texto en la pantalla, solo debes escribir print y lo que desees mostrar.

Pueden ser tanto los datos contenidos en una variable (como en nuestro código) o directamente un dato, como en los siguientes ejemplos:

print 25
print "Cadena de texto"

Creación de objetos

# Instanciar clase 
presupuesto = ModeloDePresupuesto()

¿Recuerdas cuando hablamos de la diferencia entre clases y objetos? Decíamos que una clase es un “modelo” que sirve como base para crear un objeto.

Pues bien. Es hora de crear nuestro nuevo objeto: un nuevo presupuesto.

Crear objetos

Para instanciar una clase y crear un nuevo objeto se escribe:

nombre_del_objeto = NombreDeLaClase()

Con lo anterior, hemos iniciado un nuevo objeto que será creado según el modelo NombreDeLaClase.

Método constructor de la clase: __init__

    # Método constructor 
    def __init__(self): 

def __init__(self): es la definición de una función, al igual que todas las anteriores ¿lo notas?

Pero el nombre de la función __init__, Python lo reserva para los métodos constructores.

Un método constructor de una clase, es una función que se ejecuta automáticamente cuando crea un objeto.

Estos métodos son sumamente útiles, cuando (como en nuestro caso), necesitamos automatizar todas las tareas.

Anteriormente, vimos como crear el objeto. Si no hubiésemos generado un método __init__, lo que vimos al comienzo cuando ejecutamos presupuesto.py en la consola, no hubiese sido posible, ya que tendríamos que haberle dicho manualmente a nuestro objeto, que realice cada una de las acciones, por ejemplo:

presupuesto.set_cliente() para que realice la acción de crear los datos del cliente
presupuesto.calcular_iva() para que calculara el importe de IVA
Y así con cada acción definida en la clase.

Pero, el método __init__ nos facilita la vida. Pues allí dentro, os encargamos de llamar a todas las funciones (acciones) en el orden correcto, ahorrándonos mucho tiempo:

    def __init__(self): 
	# en las siguientes líneas, imprimo texto en pantalla
        print self.divline
        print "\tGENERACIÓN DEL PRESUPUESTO" 
        print self.divline 
        self.set_cliente() # aquí seteo los datos del cliente
        self.set_datos_basicos()  # aquí los del presupuesto 
        self.calcular_iva() # calculo el iva
        self.calcular_neto() # calculo el importe total
        self.armar_presupuesto()

Finalmente, llamé a la función que se encarga de convertir a texto todo el presupuesto.

Llamar función dentro de otra

Para llamar a una función y que ésta, se ejecute en el interior de otra, se utiliza self.nombre_de_la_funcion()

Chuleta de los Capítulos I y II

Nuevo desafío

En el capítulo de hoy, nos extendimos en cuestiones teóricas sobre referencias del lenguaje que utilizamos en nuestro primer ejemplo. Aprendimos muchas cosas nuevas como:

  • Definir funciones
  • Utilizar funciones nativas de Python
  • Operadores matemáticos
  • Dar formato a cadenas de texto
  • Entre otras…

Pero algo muy importante que aprendimos es a perderle el miedo a los errores de código y tratar de resolverlos. Y si quieres convertirte en verdadero profesional, te invito a sumarte a un nuevo desafío. A continuación, encontrarás un código fuente. Este código, utiliza algunas cosas que ya hemos aprendido. Además, no te diré donde, pero tiene algún que otro error.

El reto de hoy

  1. Copia el siguiente código en un archivo, con el nombre que se te ocurra
  2. Ejecútalo en una terminal (ya sabes como)
  3. Ve si puedes encontrar el (o los) error(es) y corregirlo(s)
  4. Si encuentras el(los) error(es), NO lo postees así das tiempo a los demás a hacer lo mismo. Pero, puedes contar que los encontraste y dar pistas para ayudar a otros.
  5. Si NO encuentras los errores, puedes postear preguntando a quienes sí los hayan encontrado

Si aprendes a trabajar en equipo, colaborando con tus pares (ya sea ofreciendo o pidiendo ayuda) y evitando la competencia, estarás listo para afrontar verdaderos desafíos laborales, que harán que tu carrera se destaque.

Aquí, el código fuente

# -*- coding: utf-8 -*- 

class Modelo:

    def __init__(self):
        self.divisor = 23
        valor = raw_input("Elige un número entero entre 0 y 100: ");
        resultado = self.devolver_resultado(valor)
        print "%d/%d es %d" % (valor, self.divisor, resulatdo)

    def devolver_resultado(self, numero):
        """Divide el núemro por el divisor y devuelve un entero"""
        resultado = numero//self.divisor
        return resultado

obj = Modelo()

RECUERDA: Si encuentras el error (o los errores), no lo postees hasta que al menos 5 personas hayan indicado que pudieron corregirlo.

Descarga todos los códigos utilizados en la guía, desde LaunchPad