numero_entero = 5          # Asigno el número 5 a la variable numero_entero
print numero_entero        # Imprimo el valor que tiene la variable numero_entero
print type(numero_entero)  # Imprimo el tipo de la variable numero_entero

"""
Explanation: 15/10
Características del Python. Lenguajes compilados vs interpretados. Tipado estático vs dinámico. Fuertemente tipado vs débilmente tipado.
Variables. Operaciones Elementales. Tipos de Datos atómicos. Estructuras de Control Selectivas
Python
Python es un lenguaje de programación interpretado, fuertemente tipado, de tipado dinámico 
Compilado vs Interpretado
Existen infinitas clasificaciones para los lenguajes de programación, entre ellas una que los distingue en función de cuándo requieren de una aplicación para que la computadora entienda el código escrito por el desarrollador:
*  Compilador: * programa que lee todo el código en un instante y lo traduce al lenguaje binario que es el que entiende la computadora. Sería el equivalente a traducir un libro, cada frase se traduce una única vez y después se usa la frase traducida.
* Intérprete:*** programa que lee el código a medida que lo necesita y va traduciendo al binario, la computadora ejecuta la instrucción que el intérprete le pide, y descarta esa traducción; por lo que cuando vuelva a pasar por esa misma porción de código, deberá volver a traducirla. Es el equivalente a un intérprete en una conferencia, si el orador repite la misma frase más de una vez, éste tiene que volver a traducirla.
| Compilado | Interpretado 
-------| ---------- |  ------------
Velocidad de desarrollo|Lento, hay que compilar cada vez y es una tarea que puede tardar varios minutos| Rápido, se modifica el código y se vuelve a probar
Velocidad de ejecución| Rápido, se compila una única vez todo el programa y ejecutable generado ya lo entiende la máquina| Lento, es necesario leer, interpretar y traducir el código mientras el programa está corriendo
Dependencia de la plataforma|Si, siempre que se genera un ejecutable es para una arquitectura en particular|No, con instalar el intérprete en la computadora que se quiere correr el programa es suficiente
Dependencia del lenguaje|No, una vez que se compilo no es necesario instalar el compilador para ejecutar el programa|Si, siempre que se quiera correr el programa es necesario instalar el intérprete
Si bien Python es un lenguaje interpretado, en realidad se podría compilar el código y algo de eso hace sólo el intérprete cuando genera los archivos *.pyc.
Tipado estático vs tipado dinámico
Otra posible clasificación radica en si una variable puede cambiar el tipo de dato que se puede almacenar en ella entre una sentencia y la siguiente (tipado dinámico). O si en la etapa de definición se le asigna un tipo de dato a una variable y, por más que se puede cambiar el contenido de la misma, no cambie el tipo de dato de lo que se almacena en ella (tipado estático).
Fuertemente tipado vs débilmente tipado
Y por último, también podríamos clasificar los lenguajes en función de la posibilidad que nos brindan para mezclar distintos tipos de datos. <br>
Se dice que un lenguaje es fuertemente tipado cuando no se pueden mezclar dos variables de distinto tipo lanzando un error o excepción. <br>
Por el contrario, cuando se pueden mezclar dos variables de distinto tipo, realizar una operación entre ellas y obtener un resultado se dice que es un lenguaje débilmente tipado. <br>
Por ejemplo, en javascript (lenguaje débilmente tipado), si queremos sumar el string '1' con el número 2 dá como resultado el string '12', cuando en Python lanza una excepción al momento de ejecutar el código y, en Pascal, lanza un error al momento de querer compilar el código.
Declaración y definición de variables
En lenguajes como Pascal, la declaración y la definición de variables se encuentran en dos momentos distintos.
La declaración se dá dentro del bloque  var y es donde el desarrollador le indica al compilador que va a necesitar una porción de memoria para almacenar algo de un tipo de dato en particular y va a referirse a esa porción de memoria con un nombre en particular. <br>
Por ejemplo:
Pascal
var
   n : integer;
Se declara que existirá una variable llamada n y en ella se podrán guardar números enteros entre -32.768 y 32.767.
La definición de esa variable se dá en el momento en el que se le asigna un valor a esa variable. <br>
Por ejemplo:
Pascal
n := 5;
En Python, la declaración y definición de una variable se hacen el mismo momento:
Python
n = 5
n = 'Hola mundo'
En la primer línea se declara que se usará una variable llamada n, que almacenará un número entero y se la define asignándole el número 5. <br>
En la segunda línea, a esa variable de tipo entero se la "pisa" cambiándole el tipo a string y se le asigna la cadena de caracteres 'Hola mundo'
Objetivos y características
En 1989 Guido van Rossum era parte del equipo que desarrollaba Amoeba OS y se dió cuenta que muchos programadores al momento de tener que elegir un lenguaje para solucionar ciertos problemas se encontraban con que tenían dos alternativas, pero ninguna cerraba a la perfección:
* Bash: lenguaje de scripting (es el que usa la consola de linux como intérprete) y en este contexto se quedaba corto y complicaba la solución
* C: lenguaje estructurado con características de bajo, mediano y alto nivel; pero que en estas circunstancias era demasiado y era como matar un mosquito con cañón.
Ante esta situación, e influido por el lenguaje ABC del cual había participado, es que decidió crear Python como un lenguaje intermedio entre bash y C que tiene las siguientes características:
* Extensible (se le pueden agregar módulos en C y Python)
* Multiplataforma (Amoeba OS, Unix, Windows y Mac)
* Sintaxis simple, clara y sencilla
* Fuertemente tipado
* Tipado dinámico
* Gran librería estándar
* Introspección
Filosofia de Python
Dentro de lo que es el Zen de Python están escritas varias reglas que debería seguir todo código escrito en Python.
Algunas de ellas son:
* Bello es mejor que feo
* Explícito es mejor que implícito
* Simple es mejor que complejo
* Complejo es mejor que complicado
* La legibilidad cuenta
* Los casos especiales no son tan especiales como para quebrantar las reglas
* Aunque lo práctico le gana a la pureza
* Si la implementación es difícil de explicar, es una mala idea
Estructura de un programa en Python
La estructura de un programa en Python no es tan estricta como puede serlo en Pascal o en C/C++, ya que no debe comenzar con ninguna palabra reservada, ni con un procedimiento o función en particular. Simplemente con escribir un par de líneas de código ya podríamos decir que tenemos un programa en Python.
Lo que es importante destacar es la forma de identificar los distintos bloques de código. En Pascal se definía un bloque de código usando las palabras reservadas Begin y End; en C/C++ se define mediante el uso de las llaves ({ y }). Sin embargo, en Python, se utiliza la indentación; es decir, la cantidad de espacios/tabs que hay entre el comienzo de la línea y el primer carácter distinto a ellos.

Tipos de datos
En Python a las variables se les puede preguntar de qué tipo son usando la función type:
Python
tipo_de_la_variable =/ type(variable)
Enteros
Python 2 distingue dos tipos de enteros:
* int
* long
En Python 3 directamente existe un único tipo de entero, los int.
End of explanation
"""


numero_muy_grande = 9223372036854775807
print numero_muy_grande
print type(numero_entero)

"""
Explanation: Ahora, ¿qué pasa cuando ese número entero crece mucho?, por ejemplo, si le asignamos 9223372036854775807
End of explanation
"""


numero_muy_grande += 1
print numero_muy_grande
print type(numero_muy_grande)

"""
Explanation: ¿Y si ahora le sumamos 1?
End of explanation
"""


numero_real = 7.5
print numero_real
print type(numero_real)

"""
Explanation: Reales
End of explanation
"""


print numero_entero + numero_real
print type(numero_entero + numero_real)

"""
Explanation: ¿Y qué pasa si a un entero le sumamos un real?
End of explanation
"""


dividendo = 5
divisor = 3
resultado = dividendo / divisor
print resultado
print type(resultado)


"""
Explanation: Operaciones entre reales y enteros
¿Y si dividimos dos números enteros?, ¿dará un número real?
End of explanation
"""


divisor = 3.0
resultado = dividendo / divisor
print resultado
print type(resultado)


"""
Explanation: En cambio, si alguno de los números es real:
End of explanation
"""


cociente = dividendo // divisor
print "cociente: ", cociente
print type(cociente)

resto = dividendo % divisor
print "resto: ", resto
print type(resto)

"""
Explanation: ¿Y si queremos hacer la división entera por más que uno de los números sea real?
End of explanation
"""


complejo = 5 + 3j
print complejo
print type(complejo)
complejo_cuadrado = complejo ** 2
print '(5+3j)*(5+3j) = 5*5 + 5*3j + 3j*5 + 3j*3j = (25-9) + 30j'
print complejo_cuadrado


"""
Explanation: Esto cambia en Python 3, donde la / hace la división real (por más que le pases dos números enteros) y la // hace la división entera.
Complejos
End of explanation
"""


boolean = True
print boolean
print not boolean
print type(boolean)
print True or False and True

"""
Explanation: Si bien Python soporta aritmética de complejos, la verdad es que no es uno de los tipos de datos más usados. Sin embargo, es bueno saber que existe.
Booleanos
Python también soporta el tipo de dato booleano:
End of explanation
"""


boolean = 5 < 7
print boolean


"""
Explanation: También se puede crear un boolean a partir de comparar dos números:
End of explanation
"""


numero = 7
en_rango = 5 < numero < 9
fuera_de_rango = 5 < numero < 6
print 'numero vale {0}'.format(numero)
print '5 < numero < 9: {pertenece}'.format(pertenece=en_rango)
print '5 < numero < 6: %s' % fuera_de_rango


"""
Explanation: Incluso, se puede saber fácilmente si un número está dentro de un rango o no.
End of explanation
"""


print " %d %i %s %ld %lu %0.4d %4d" % (5, 5, 5, 5, 5, 5, 5)

"""
Explanation: Muchas formas de imprimir el número 5
End of explanation
"""


cadena_caracteres = 'Hola mundo'
print cadena_caracteres
print type(cadena_caracteres)

cadena_caracteres = "Y con doble comilla?, de qué tipo es?"
print cadena_caracteres
print type(cadena_caracteres)


"""
Explanation: Strings
En python los strings se pueden armar tanto con comillas simples (') como dobles ("), lo que no se puede hacer es abrir con unas y cerrar con otras.
End of explanation
"""


cadena_caracteres = """y si quiero
usar un string
que se escriba en varias
líneas?."""
print cadena_caracteres
print type(cadena_caracteres)


"""
Explanation: Además, se pueden armar strings multilínea poniendo tres comillas simples o dobles seguidas:
End of explanation
"""


cadena_caracteres = 'Hola mundo'
print cadena_caracteres
print 'El septimo caracter de la cadena "{0}" es "{1}"'.format(cadena_caracteres, cadena_caracteres[6])


"""
Explanation: Índices y Slice en string
Si queremos obtener un caracter del string podemos acceder a él simplemente con poner entre corchetes su posición (comenzando con la 0):
End of explanation
"""


print 'El septimo caracter de la cadena "{0}" es "{1}"'.format(cadena_caracteres, cadena_caracteres[-4])


"""
Explanation: H | o | l | a |   | m | u | n | d | o
-------| ---------- |  ------------
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Aunque también nos podemos referir a ese caracter comenzando por su posición, pero comenzando a contar desde la última posición (comenzando en 1):
End of explanation
"""


cadena_caracteres[6] = 'x'

"""
Explanation: H | o | l | a |   | m | u | n | d | o
-------| ---------- |  ------------
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
-10 | -9 | -8 | -7 | -6 | -5 | -4 | -3 | -2 | -1
Lo que no se puede hacer es cambiar sólo una letra de un string:
End of explanation
"""


print cadena_caracteres[2:8]     # Con los dos índices positivos
print cadena_caracteres[2:-2]    # Con un índice negativo y otro positivo
print cadena_caracteres[-8:8]    # Con un índice negativo y otro positivo
print cadena_caracteres[-8:-2]   # Con ambos índices negativos
print cadena_caracteres[2:-2:3]  # Y salteándose de a dos


"""
Explanation: Aunque a veces lo que queremos es una parte del string, no todo:
End of explanation
"""


cadena_caracteres = 'Hola mundo\n'
print cadena_caracteres
print cadena_caracteres[:-1]
print cadena_caracteres[:-5]

"""
Explanation: Aunque lo más común es quitar el último carácter, por ejemplo, cuando es un Enter:
End of explanation
"""


numero = raw_input('Ingrese un número')
print numero
print type(numero)


"""
Explanation: Ingreso de datos desde teclado
End of explanation
"""


numero = int(numero)
print numero
print type(numero)


"""
Explanation: Y para convertirlo como entero:
End of explanation
"""


numero1 = 1
numero2 = 2

if numero1 == numero2:
    print 'Los números son iguales'

print 'Este string se imprime siempre'

print 'Ahora cambio el valor de numero2'
numero2 = 1

if numero1 == numero2:
    print 'Los números son iguales'

print 'Este string se imprime siempre'

"""
Explanation: None
None es el tipo de dato nulo que sólo puede tomar un valor: None. Aunque parezca que es muy inútil, en realidad se usa mucho.
Estructuras de control
Así como en Pascal se delimitan los bloques de código con las palabras reservadas begin y end, en Python se usan la indentación (espacios) para determinar qué se encuentra dentro de una estructura de control y qué no.
if
End of explanation
"""


numero1 = 1
numero2 = 2

if numero1 == numero2:
    print 'Los números son iguales'
    print 132
    print 23424
else:
    print 'Los números son distintos'

"""
Explanation: if-else
End of explanation
"""


# Como lo tendríamos que hacer en Pascal o C.
if numero1 == numero2:
    print 'Los dos números son iguales'
else:
    if numero1 > numero2:
        print 'numero1 es mayor a numero2'
    else:
        print 'numero1 es menor a numero2'

"""
Explanation: if-elif-else
Ahora si queremos imprimir si un número es igual, menor o mayor a otro tendríamos que usar if anidados en Pascal o C; y no queda del todo claro:
End of explanation
"""


# Más corto y elegante en Python.
if numero1 == numero2:
    print 'Los dos números son iguales'
elif numero1 > numero2:
    print 'numero1 es mayor a numero2'
else:
    print 'numero1 es menor a numero2'

"""
Explanation: En cambio, en Python lo podemos un poco más compacto y claro:
End of explanation
"""


lista_de_numeros = []

if lista_de_numeros:
    print 'la lista tiene elementos'
else:
    print 'la lista no tiene elementos'


"""
Explanation: Como ya dijimos antes, se puede usar el operador in para saber si un elemento se encuentra en una lista:
End of explanation
"""


if lista_de_numeros:
    print 'La lista no esta vacía'

if False or None or [] or () or {} or 0:
    print 'Alguna de las anteriores no era falsa'
else:
    print 'Todos los valores anteriores son consideradas como Falso'


"""
Explanation: Cualquier tipo de dato se lo puede evaluar como booleano.
Se toma como falso a:
* None
* False para los bool
* cero para todo tipo de dato numérico: 0, 0L, 0.0, 0j
* vacío para cualquier secuencia o diccionario: '', (), [], {}
Por lo tanto, se puede saber si una lista esta vacía o no con simplemente:
End of explanation
"""


num = 5
es_par = True if (num % 2 == 0) else False
print '5 es par?:', es_par

num = 6
es_par = True if (num % 2 == 0) else False

print '6 es par?:', es_par

nulo = None
print nulo
print type(nulo)

"""
Explanation: short-if
Otra forma de escribir el if en una sola línea es poner:
Python
variable = valor1 if condicion else valor2
Por ejemplo:
End of explanation
"""


