pythonnerdlabs.com.ar/media/2017/07/12/python.pdf · 2017-07-12 · estilos python es un lenguaje...

144
Python Leo Vidarte

Upload: others

Post on 25-Jul-2020

6 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Python

Leo Vidarte

Page 2: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Python fue creado porGuido van Rossumen 1991

Características principales:

● Lenguaje de alto nivel● Interpretado● Tipado fuerte, pero dinámico● Los bloques no necesitan llaves● La documentación es parte del código● Posee un intérprete interactivo

Page 3: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Filosofía

Python hace foco en la simplicidad, la claridad, el pragmatismo y la diversión.

Es sencillo de aprender y su código es elegante:

def fib(n):

a, b = 0, 1

while a < n:

print(a, end=' ')

a, b = b, a+b

0 1 1 2 3 5 8 13 21...

Page 4: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

EstilosPython es un lenguaje de programación multiparadigma.

Esto significa que más que forzar a los programadores a adoptar un estilo particular de programación, permite varios estilos:

● Programación orientada a objetos● Programación imperativa● Programación funcional

Page 5: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Usos

Python es un lenguaje multipropósito.

Sirve para crear todo tipo de software:

● Aplicaciones de escritorio● Aplicaciones Web● Servicios (API's)● Automatizar tareas en servidores● Internet of Things

Page 6: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Su intérprete interactivo es idealpara aprender y hacer pruebas

Page 7: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Intérprete interactivo

$> python3

Python 3.5.2 (default, Jul 5 2016, 12:43:10)

Type "help", "copyright", "credits" or "license" for more

information.

>>>

Page 8: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Intérprete interactivo

$> python3

Python 3.5.2 (default, Jul 5 2016, 12:43:10)

Type "help", "copyright", "credits" or "license" for more

information.

>>> print("hola a todos")

Page 9: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Intérprete interactivo

$> python3

Python 3.5.2 (default, Jul 5 2016, 12:43:10)

Type "help", "copyright", "credits" or "license" for more

information.

>>> print("hola a todos")

hola a todos

Page 10: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Python como calculadora>>> 2 + 2

4

>>> 2 - 2

0

>>> 2 * 3

6

>>> 10 / 2

5.0

>>> 10 // 3

3

>>> 2 ** 3

8

>>> (10 - 3) * 5

35

>>> _ / 3

2.6666666666666665

>>> 8 % 3

2

Page 11: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Juguemos un poco !

Page 12: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Logo en Python

>>> import turtle

>>>

Page 13: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Logo en Python

>>> import turtle

>>> for i in range(5):

... turtle.forward(100)

... turtle.right(144)

...

>>>

Page 14: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Logo en Python

>>> import turtle

>>> for i in range(5):

... turtle.forward(100)

... turtle.right(144)

...

>>>

Page 15: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Logo en Python

>>> import turtle

>>> for _ in range(20):

... turtle.forward(i * 10)

... turtle.right(144)

Page 16: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Logo en Python

>>> import turtle

>>> for _ in range(20):

... turtle.forward(i * 10)

... turtle.right(144)

...

>>>

Page 17: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Un ejemplomás interesante 1 import turtle

2

3 colors = [

4 'red', 'purple', 'blue',

5 'green', 'yellow', 'orange'

6 ]

7

8 turtle.bgcolor('black')

9

10 for x in range(360):

11 turtle.pencolor(colors[x % 6])

12 turtle.width(x/100+1)

13 turtle.forward(x)

14 turtle.left(59)

Page 18: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

VariablesTipado dinámico

>>> n = 1

>>> type(n)

<class 'int'>

>>> n = "ahora soy un str"

>>> type(n)

<class 'str'>

>>> n = 1.2

>>> type(n)

<class 'float'>

Tipado fuerte

>>> a = 1

>>> b = "2"

>>> a + b

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

TypeError: unsupported operand type(s) for

+: 'int' and 'str'

>>> a + int(b)

3

Page 19: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Tipos básicos: int, float, str, bool>>> i = 1

>>> type(i)

<class 'int'>

>>> f = 3.14

>>> type(f)

<class 'float'>

>>> s = "2"

>>> type(s)

<class 'str'>

>>> b = True

>>> type(b)

<class 'bool'>

Notación binaria, octal y hexadecimal

>>> 0b111

7

>>> 0o111

73

>>> 0x111

273

>>> bin(7)

'0b111'

>>> oct(73)

'0o111'

>>> hex(273)

'0x111'

Casting

>>> int("1")

>>> float(3)

>>> str(2)

>>> bool(1)

Chars

>>> chr(65)

'A'

>>> ord('A')

65

Page 20: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Operaciones con booleanos

>>> bool(0)

False

>>> bool(0.0)

False

>>> bool("")

False

>>> bool(None)

False

>>> bool(1)

True

>>> bool(0.1)

True

>>> bool("hello")

True

>>> bool(not None)

True

>>> "s" == True

False

>>> bool("s") == True

True

Operadores lógicos

>>> not False

True

>>> True and True

True

>>> True or False

True

Page 21: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Los strings son inmutables

En Python todo es un objeto.Inmutables son aquellos objetos

que una vez creadosno se pueden alterar.

>>> s = "hello"

>>> id(s)

139752245777776

>>> s += " world"

>>> id(s)

139752246378160

>>> s

'hello world'

>>> s[0] = "H"

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

TypeError: 'str' object does not support item assignment

Page 22: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Métodos de str>>> s = "">>> s.<Tab>s.__add__( s.__le__( s.capitalize( s.islower( s.rpartition(s.__class__( s.__len__( s.casefold( s.isnumeric( s.rsplit(s.__contains__( s.__lt__( s.center( s.isprintable( s.rstrip(s.__delattr__( s.__mod__( s.count( s.isspace( s.split(s.__dir__( s.__mul__( s.encode( s.istitle( s.splitlines(s.__doc__ s.__ne__( s.endswith( s.isupper( s.startswith(s.__eq__( s.__new__( s.expandtabs( s.join( s.strip(s.__format__( s.__reduce__( s.find( s.ljust( s.swapcase(s.__ge__( s.__reduce_ex__( s.format( s.lower( s.title(s.__getattribute__( s.__repr__( s.format_map( s.lstrip( s.translate(s.__getitem__( s.__rmod__( s.index( s.maketrans( s.upper(s.__getnewargs__( s.__rmul__( s.isalnum( s.partition( s.zfill(s.__gt__( s.__setattr__( s.isalpha( s.replace( s.__hash__( s.__sizeof__( s.isdecimal( s.rfind( s.__init__( s.__str__( s.isdigit( s.rindex( s.__iter__( s.__subclasshook__( s.isidentifier( s.rjust(

>>> help(s.join) join(...) method of builtins.str instance S.join(iterable) -> str Return a string which is the concatenation of the strings in the iterable. The separator between elements is S.

Page 23: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

print(value1, ..., sep=' ', end='\n', file=sys.stdout, flush=False)>>> a, b = 1, 2

>>> print("a =", a, ", b =", b)

a = 1 , b = 2

>>> print(192, 168, 0, 1, sep=".")

192.168.0.1

>>> f = open("data.txt", "w")

>>> print("42 is the answer", file=f)

>>> f.close()

>>> import sys

>>> print("Error 42!", file=sys.stderr)

Error 42!

>>> for i in range(4):

... print(i)

...

1

2

3

4

>>> for i in range(4):

... print(i, end=" ")

...

1 2 3 4 >>>

Page 24: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

String format>>> "{} {} {}".format(1, "dos", True)

'1 dos True'

>>> "{2} {1} {0}".format(1, "dos", True)

'True dos 1'

>>> "{0} {1} {bool}".format(1, "dos", bool=True)

'1 dos True'

>>> "{0:4} {1:8} {pi:10}".format(5, 10, pi=3.1416)

' 5 10 3.1416'

>>> "{0:<4} {1:^8} {pi:>10}".format(5, 10, pi=3.1416)

'5 10 3.1416'

Page 25: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Python y Unicodeα í ∞ U დ й น ይ ☺

Page 26: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Desde Python 3todo string es Unicode>>> pi = "π">>> print(pi)

π

>>> type(pi)

<class 'str'>

>>> len(pi)

1

>>> pi.encode('utf8')

b'\xcf\x80'

La filosofía en Python para leer yprocesar archivos de textos es la siguiente:1. Al leer desencodear.2. Procesar como unicode.3. Encodear al escribir.

import io

# readwith io.open(filename, 'r', encoding='utf8') as f: text = f.read()

# process Unicode text

# writewith io.open(filename, 'w', encoding='utf8') as f: f.write(text)

Page 27: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Listas [<element>, <element>, ... <element>]>>> l = [1, 2, 3]

>>> type(l)

<class ‘list’>

>>> l.append(4)

>>> l

[1, 2, 3, 4]

>>> l[0]

1

>>> l[-1]

4

>>> l[0] = 0

>>> l

[0, 2, 3, 4]

Simple stack>>> l.pop()

4

Simple queue>>> l.pop(0)

1

Slicing

>>> l[1:3]

[2, 3]

>>> l[::2]

[2, 4]

>>> l[::-1]

[4, 3, 2, 0]

Tamaño de la lista

>>> len(l)

4

Mixed lists

mixedList = [True, 5,

'some string',

123.45]

Page 28: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Listas vacías

Una lista vacía evalúa como False

>>> bool([])

False

Tratar de obtener un elemento que no existe dispara una Exception de tipo IndexError

>>> [][0]

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

IndexError: list index out of range

>>> try:

... print([][0])

... except IndexError:

... print("out of range")

...

out of range

Page 29: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Recorrer una lista con forEl siguiente es un patrón muy usado en Python, en el que se recorre una lista para generar un bucle del tipo for(i=0; i<10; i++). La lista es generada por range(), una función para generar listas numéricas:

>>> for i in range(5):

... print(i)

...

0

1

2

3

4

Si quisiéramos enumerar una lista tenemos la función enumerate()

>>> for i, e in enumerate(["aa", "bb", "cc"]):

... print(i, e)

...

0 aa

1 bb

2 cc

También podemos iterar un string

>>> for c in "hola":

... print(c)

...

h

o

l

a

Page 30: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Tuplas (<element1>, <element2>, ... <elementN>)

Son similares a las listas pero son inmutables

>>> t = (1, 2, 3, 4)

>>> t = 1, 2, 3, 4

>>> t

(1, 2, 3, 4)

>>> type(t)

<class 'tuple'>

>>> t[0]

1

>>> t[1:3]

(2, 3)

>>> len(t)

4

Tratar de cambiar una tupla dispara una Exception de tipo TypeError

>>> t[1] = 2Traceback (most recent call last):

File "<stdin>", line 1, in <module>

TypeError: 'tuple' object does not support item assignment

Page 31: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Tip acerca de las tuplas

Aunque es una buena práctica ponerlos, los paréntesis son opcionales al construir tuplas

>>> x = 1, 2, 3, 4>>> x(1, 2, 3, 4)

>>> type(x)<class 'tuple'>

La asignación de múltiples variables en una única instrucción usa esta propiedad de las tuplas, ya que en realidad es una descomposición de la misma

>>> x, y = 1, 2>>> x1>>> y2

Así que podemos aprovechar esto para intercambiar variables sin necesidad de usar un auxiliar :)

>>> x, y = y, x>>> x2>>> y1

Page 32: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Diccionarios {<key>:<value>, <key>:<value>, ..., <key>:<value>}

Son colecciones de key:value que no tienen un orden en particular

>>> d = {"x": 0, "y": 1}

>>> d["x"]

0

>>> type(d)

<class 'dict'>

>>> d["y"] = 1.2

>>> d.items()

dict_items([('x', 0), ('y', 1.2)])

>>> d.keys()

dict_keys(['x', 'y'])

>>> d.values()

dict_values([0, 1.2])

Page 33: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Sets {<value>, <value>, ..., <value>}Un set es una colección de datos sin orden pero donde no existen los elementos duplicados.

>>> s1 = {1, 2, 1}

>>> s1

{1, 2}

>>> type(s1)

<class 'set'>

>>> s1.add(3)

{1, 2, 3}

Operaciones>>> s1 = {1, 2, 3}

>>> s2 = {2, 3, 4}

En s1 pero no en s2:>>> s1 - s2

{1}

Union:>>> s1 | s2

{1, 2, 3, 4}

Sólo los que están en ambos:>>> s1 & s2

{2, 3}

Los diferentes:>>> s1 ^ s2

{1, 4}

Page 34: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Funciones

Page 35: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Built-in functionsabs() divmod() input() open() staticmethod()

all() enumerate() int() ord() str()

any() eval() isinstance() pow() sum()

basestring() execfile() issubclass() print() super()

bin() file() iter() property() tuple()

bool() filter() len() range() type()

bytearray() float() list() raw_input() unichr()

callable() format() locals() reduce() unicode()

chr() frozenset() long() reload() vars()

classmethod() getattr() map() repr() xrange()

cmp() globals() max() reversed() zip()

compile() hasattr() memoryview() round() __import__()

complex() hash() min() set()

delattr() help() next() setattr()

dict() hex() object() slice()

dir() id() oct() sorted()

El intérprete de Python tiene un conjunto de funcionesbuilt-in que están siempre disponibles:

Page 36: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

range()En Python 3, range() produce un tipo nativo de datos llamado range, que junto con list y tuple conforman los tres tipos básicos de secuencias. Al igual que tuple, es un objeto inmutable.

>>> type(range(10))

<class 'range'>

Este objeto es iterable al igual que las listas y las tuplas, pero no devuelve inmediatamente todos sus valores, sino que los va generando a medida que se los pedimos. Podemos obtener inmediatamente sus valores de esta forma:

>>> list(range(10))

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> tuple(range(10))

(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

Page 37: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Funciones definidaspor el usuario>>> def foo(a, b):

... return a + b

...

>>> foo(2, 4)

6

>>> type(foo)

<class 'function'>

>>> f = foo

>>> f(2, 4)

6

Argumentos por default

>>> def pow(x, y=2):

... return x ** y

...

>>> pow(3)

9

>>> pow(y=2, x=4)

16

>>> t = (3, 4)

>>> pow(*t)

81

>>> d = {'x':5, 'y':2}

>>> pow(**d)

25

Page 38: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Funciones lambdaEn Python existe un tipo de función especial que sólo permite una expresión y que se declara en una sóla línea. La forma general es

lambda argument_list: expression

No necesita la palabra return, ya que lo que se devuelve es el resultado de esa expresión

>>> pow = lambda x, y: x ** y

>>> pow(2, 3)

8

>>> type(pow)

<class 'function'>

Page 39: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

List comprehensionLas comprensiones de listas ofrecen una manera concisa de crear listas. Supongamos que queremos crear una lista con los cuadrados de los primeros 10 números enteros, La forma clásica sería

>>> cuadrados = []

>>> for x in range(10):

... cuadrados.append(x**2)

…>>> cuadrados

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

>>> x

9

Notar que esto crea (o sobreescribe) una variable llamada x que sigue existiendo luego de que el bucle haya terminado. Podemos calcular la lista de cuadrados sin ningún efecto secundario haciendo:

cuadrados = list(map(lambda x: x**2, range(10)))

O, el equivalente usando list comprehension

cuadrados = [x ** 2 for x in range(10)]

Page 40: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Ejemplo de acumulador funcional

>>> def fold_list(fn, acc, _list):

... if _list:

... return fold_list(fn, acc + fn(_list.pop()), _list)

... return acc

...

>>> fold_list(lambda x: x ** 2, 0, [1, 2, 3])

14

Page 41: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Más list comprehensionA partir de una lista con los diez primeros enteros obtener sólo los impares:

>>> list(filter(lambda x: x % 2, range(10)))

[1, 3, 5, 7, 9]

También podemos obtener un generador (similar a range)

>>> [x for x in range(10) if x % 2]

<generator object <genexpr> at 0x7f26b3da68e0>

Crear un query string a partir de un diccionario:

>>> query = {'ord': 'asc', 'q': 'text', 'limit': 10}

>>> "&".join(["%s=%s" % (n, v) for n, v in query.items()])

'q=text&limit=10&ord=asc'

Page 42: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

GeneradoresLos generadores son funciones que van generando y devolviendo datos a medida que se los pedimos. Utilizan yield en lugar de return, y son útiles para ahorrar memoria

>>> def my_range(n):... i = 0... while i < n:... yield i... i += 1...

>>> my_range(10)<generator object my_range>

Podemos recorrer manualmente sus datos usando la función built-in next

>>> g = my_range(3)>>> next(g)0>>> next(g)1>>> next(g)2>>> next(g)3>>> next(g)4>>> next(g)Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration

Page 43: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Decoradores

Los decoradores son funciones que reciben como parámetros otras funciones y retornan como resultado otras funciones con el objetivo de alterar el funcionamiento original de la función que se pasa como parámetro

>>> def logger(fn):... def wrapper(*args, **kwargs):... print("Llamando a", fn.__name__)... return fn(*args, **kwargs)... return wrapper...

>>> @logger... def sum(a, b):... return a + b...

>>> sum(1, 2)Llamando a sum3

>>> sum.__name__'wrapper'

Page 44: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

@wraps

Para evitar que la función decorada pierda su nombre y su docstring se utiliza el decorador wraps

>>> from time import time>>> from functools import wraps

>>> def timethis(fn):... '''... Decorator that reports the execution time.... '''... @wraps(fn)... def wrapper(*args, **kwargs):... start = time()... result = fn(*args, **kwargs)... end = time()... print(fn.__name__, end - start)... return result... return wrapper...

>>> @timethis... def countdown(n):... '''... Counts down.... '''... while n > 0:... n -= 1...

>>> countdown(1000000)countdown 0.06418180465698242

>>> countdown.__name__'countdown'

>>> countdown.__doc__'\n Counts down.\n '

Page 45: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Decoradores conargumentos

>>> def tags(tag_name):... def decorator(fn):... @wraps(fn)... def wrapper(*args, **kwargs):... return "<{0}>{1}</{0}>".format(tag_name, fn(*args, **kwargs))... return wrapper... return decorator...

>>> @tags("p")... def get_greeting(name, lastname):... return "Hello {} {}".format(name, lastname)...

>>> get_greeting("John", "Anderson")'<p>Hello John Anderson</p>'

Sin azúcar sintáctico

>>> def get_title(section):... return "Welcome to {}".format(section)...

>>> get_title = tags("h1")(get_title)>>> get_title("index")'<h1>Welcome to index</h1>'

Un tercer nivel de funciones anidadas es necesario para pasarle argumentos al decorador

Page 46: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Tips con la consola

Page 47: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

# export PYTHONSTARTUP=$HOME/.pythonstartup

import atexitimport osimport readlineimport rlcompleter

historyPath = os.path.expanduser("~/.pyhistory")

#readline.parse_and_bind('tab: menu-complete')readline.parse_and_bind('tab: complete')

def save_history(historyPath=historyPath): import readline readline.write_history_file(historyPath)

if os.path.exists(historyPath): readline.read_history_file(historyPath)

atexit.register(save_history)del os, atexit, readline, rlcompleter, save_history, historyPath

Activar el autocompletadoy la historiaEl intérprete lee el archivo al que apunte la variable de entorno PYTHONSTARTUP.

Podemos poner ahí funciones o cualquier cosa que necesitemos tener siempre a mano en la consola.

Para activar el autocompletado (con tab) y el historial de comandos ingresados, hay que poner el siguiente código:

Page 48: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

# fib.py

def fib(n): l = [] a, b = 0, 1 for _ in range(n): l.append(a) a, b = b, a+b return l

Levantar tus archivos .pycon la consolaAlgo muy útil de la consola es que te permite levantar código de un archivo y jugar con él interactivamente:

$ python3 -i fib.py>>> fib(5)[0, 1, 1, 2, 3]>>> fib(10)[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

Page 49: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Ayuda!También para eso es útil la consola. Mediante la función help() se puede acceder a la documentación de cada método, clase o paquete.

# fib.py

def fib(n): """Gets a list for the first n numbers in the Fibonacci sequence.""" l = [] a, b = 0, 1 for _ in range(n): l.append(a) a, b = b, a+b return l

$ python3 -i fib.py>>> help(fib)fib(n) Gets a list for the first n numbers in the Fibonacci sequence.

Page 50: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Guardar la sesión actual en un archivo

>>> import readline

>>> readline.write_history_file('/file/to/session')

Page 51: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Exceptionsraise Exception("Error message")

def divide(x, y): try: result = x / y except ZeroDivisionError: print("division by zero!") except TypeError as e: print(e) else: print("result is", result) finally: print("executing finally clause")

BaseException +-- SystemExit +-- KeyboardInterrupt +-- GeneratorExit +-- Exception +-- StopIteration +-- StandardError | +-- BufferError | +-- ArithmeticError | | +-- FloatingPointError | | +-- OverflowError | | +-- ZeroDivisionError | +-- EnvironmentError | | +-- IOError | +-- EOFError | +-- ImportError | +-- LookupError | | +-- IndexError | | +-- KeyError | +-- MemoryError | +-- NameError | +-- ReferenceError | +-- RuntimeError | | +-- NotImplementedError | +-- SystemError | +-- TypeError | +-- ValueError | +-- UnicodeError | +-- UnicodeDecodeError | +-- UnicodeEncodeError | +-- UnicodeTranslateError +-- Warning +-- DeprecationWarning +-- PendingDeprecationWarning +-- RuntimeWarning +-- SyntaxWarning

Page 52: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Clases

Page 53: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

La clase más sencilla que podés hacer

Las clases también son objetos

>>> class Foo:

... pass

...

>>> type(Foo)

<class 'type'>

>>> f = Foo()

>>> type(f)

<class '__main__.Foo'>

>>> f.n = 2

>>> f.pow = lambda e: f.n ** e

>>> f.pow(2)

4

>>> f.pow(3)

8

>>> f.n = 3

>>> f.pow(2)

9

Page 54: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Un ejemplo más realimport math

class Point:

""" Point class """

def __init__(self, x, y):

self.x = x

self.y = y

def distance(self, other):

dx = self.x - other.x

dy = self.y - other.y

return math.sqrt(dx**2 + dy**2)

def __str__(self):

return "Point(%s,%s)" % (self.x, self.y)

>>> p0 = Point(5, 10)

>>> p1 = Point(10, 15)

>>> p0.distance(p1)

7.0710678118654755

>>> p0

<__main__.Point object at

0x7f4f94d4fd68>

>>> p1

<__main__.Point object at

0x7f4f94ceb240>

>>> print(p0)

Point(5,10)

>>> print(p1)

Point(10,15)

Page 55: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Singleton en PythonUn singleton en Python es trivial, sólo hay que

usar la propiedad de los módulo de que sólo son

importados una única vez:

PythónicoLos usuarios de Python se refieren a menudo a laFilosofía Python que es bastante análoga a lafilosofía de Unix. El código que sigue los principios de Python de legibilidad y transparencia se dice que es "pythonico". Contrariamente, el código opaco u ofuscado es bautizado como "no pythonico".

Estos principios fueron famosamente descritos por el desarrollador de Python Tim Peters en El Zen de Python

# singleton.py

class Singleton:

pass

singleton = Singleton()

# main.py

from singleton import singleton

Page 56: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

El ZendePython>>> import this

● Bello es mejor que feo.● Explícito es mejor que implícito.● Simple es mejor que complejo.● Complejo es mejor que complicado.● Plano es mejor que anidado.● Espaciado es mejor que denso.● La legibilidad cuenta.● Los casos especiales no son tan especiales como para quebrantar las

reglas.● Los errores nunca deberían dejarse pasar silenciosamente.● A menos que hayan sido silenciados explícitamente.● Frente a la ambigüedad, rechazar la tentación de adivinar.● Debería haber una -y preferiblemente sólo una- manera obvia de hacerlo.● Aunque esa manera puede no ser obvia al principio a menos que usted sea

Holandés (Guido es holandés).● Ahora es mejor que nunca.● Aunque nunca es a menudo mejor que ya.● Si la implementación es difícil de explicar, es una mala idea.● Si la implementación es fácil de explicar, puede que sea una buena idea.● Los espacios de nombres (namespaces) son una gran idea ¡Hagamos más

de esas cosas!.

Page 57: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Clases: Variables de clase y de instanciaEn general, las variables de instancia son para datos únicos de cada instancia y las variables de clase son para atributos y métodos compartidos por todas las instancias de la clase:

class Perro:

tipo = 'canino' # variable de clase compartida por

# todas las instancias

def __init__(self, nombre):

self.nombre = nombre # variable de instancia única para la instancia

Page 58: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Clases: HerenciaHerencia simple:

class ClaseDerivada(ClaseBase):

<declaración-1>

.

.

.

<declaración-N>

Herencia múltiple:

class ClaseDerivada(Base1, Base2, Base3):

<declaración-1>

.

.

.

<declaración-N>

Para la mayoría de los propósitos, en los casos más simples, podés pensar en la búsqueda de los atributos heredados de clases padres como primero en profundidad, de izquierda a derecha, sin repetir la misma clase cuando está dos veces en la jerarquía. Por lo tanto, si un atributo no se encuentra en ClaseDerivada, se busca en Base1, luego (recursivamente) en las clases base de Base1, y sólo si no se encuentra allí se lo busca en Base2, y así sucesivamente.

Page 59: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Clases: Variables privadas

>>> class Point:

... def __init__(self, x, y):

... self._x = x

... self.__y = y

...

>>> p = Point(5, 10)

>>> p._x

5

Las variables “privadas” de instancia, que no pueden accederse excepto desde dentro de un objeto, no existen en Python. Sin embargo, hay una convención que se sigue en la mayoría del código Python: un nombre prefijado con un guión bajo (por ejemplo, _x) debería tratarse como una parte no pública de la API (más allá de que sea una función, un método, o un dato). Si querés protegerla un “poco más” usá doble guión bajo:

>>> p.__y

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

AttributeError: 'Point' object has no

attribute '__y'

>>> p._Point__y

10

Page 60: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Clases: Setters y Getters class Foo:

def __init__(self):

self.__x = None

def __get_x(self):

return self.__x

def __set_x(self, value):

self.__x = value

def __del_x(self):

del self.__x

x = property(__get_x, __set_x, __del_x,

"I'm the x property")

Python adhiere al Uniform Access Principle, que dice más o menos que desde el punto de vista de un cliente del programa que hace una llamada a una función de clase, si una consulta es un atributo (campo en cada objeto) o una función (algoritmo) no tiene que tener ninguna diferencia.

Y lo que significa es que en Python no se usan los get_x() y set_x(), al menos no externamente.

Para cualquier atributo que deba ser computado tenemos la función built-in property()

Page 61: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Módulos y Paquetes

Page 62: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Módulosfibo.py

"""Fibonacci module

"""

def fib(n):

"""Return Fibonacci series up to n"""

result = []

a, b = 0, 1

while b < n:

result.append(b)

a, b = b, a+b

return result

def fib2(n):

"""Prints Fibonacci series up to n"""

print(", ".join(map(str, fib(n))))

$ python3

>>> import fibo

>>> help(fibo)

Help on module fibo:

NAME

fibo - Fibonacci module

FUNCTIONS

fib(n)

Return Fibonacci series up to n

fib2(n)

Prints Fibonacci series up to n

FILE

/home/lvidarte/fibo.py

Page 63: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Módulos (import)Módulos como comandos

La ejecución de fibo.py no produce un resultado

$ python3 fibo.py

$

Para usar directamente un módulo es muy común agregar algo así al final del archivo:

if __name__ == "__main__":

import sys

fib2(int(sys.argv[1]))

Y agregar el shebang al inicio del archivo:

#!/usr/bin/python3

Luego de darle permisos de ejecución podemos hacer:

$ ./fibo.py 10

1, 1, 2, 3, 5, 8

Existen varias formas en las cuales podemos importar el contenido de un módulo:

1. import fibo

fibo.fib(10)

fibo.fib2(10)

2. import fibo as fibonacci

fibonacci.fib(10)

fibonacci.fib2(10)

3. from fibo import *

fib(10)

fib2(10)

4. from fibo import fib2 as fibonacci

fibonacci(10)

Page 64: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Packages

Packages es la manera en que Python permite estructurar módulos con características similares.

Un paquete es un directorio conteniendo módulos Python y un archivo __init__.py

sound/ Top-level package __init__.py Initialize the sound package formats/ Subpackage for format conversions __init__.py wavread.py wavwrite.py aiffread.py aiffwrite.py auread.py auwrite.py ... effects/ Subpackage for sound effects __init__.py echo.py surround.py reverse.py ... filters/ Subpackage for filters __init__.py equalizer.py vocoder.py karaoke.py ...

Page 65: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

.└── sound ├── effects │ ├── echo.py │ ├── __init__.py │ └── reverse.py ├── filters │ └── __init__.py └── __init__.py

Contenido de los archivos

# sound/__init__.py__all__ = ["effects", "filters"]from . import effects, filters

# sound/effects/__init__.py__all__ = ["echo", "reverse"]from . import echo, reverse

# sound/effects/echo.pydef echofilter(): print("echofilter function")

# sound/effects/reverse.pydef f1(): print("reverse f1")

def f2(): print("reverse f2")

# sound/filters/__init__.pydef foo(): print("filters foo")

Distintos imports que puedo hacer

>>> import sound>>> sound.effects.echo.echofilter<function echofilter at 0x7f0a420b3ea0>

>>> from sound import *>>> effects.echo.echofilter<function echofilter at 0x7f795f2bcd90>>>> filters.foo<function foo at 0x7f795d61b048>

>>> from sound.effects import *>>> echo.echofilter<function echofilter at 0x7f07c0046d90>>>> reverse.f1<function f1 at 0x7f07c0046ea0>

>>> from sound.effects.echo import echofilter>>> echofilter<function echofilter at 0x7f0a420b3ea0>

Page 66: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Módulos de lalibrería estándarLa librería estándar es realmente grande. Para mencionar sólo algunos de los módulos más usados tenemos: sys, re, os, math, logging, datetime, time, collections, threading, multiprocessing, sqlite, json, random, urllib2

● Pequeño paseo por la Biblioteca Estándar

● Pequeño paseo por la Biblioteca Estándar - Parte II

Batteries included!

>>> import antigravity

Page 67: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Servidor HTTP en una línea

$ python3 -m http.server

Serving HTTP on 0.0.0.0 port 8000 …

usage: server.py [-h] [--cgi] [--bind ADDRESS] [port]

Page 68: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Manejo de Paquetes y Entornos Virtuales

Page 69: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Manejando paquetes con pip

Es posible instalar, actualizar y quitar paquetes usando pip.Por defecto pip instalará paquetes desde PyPI (Python Package Index).

$ sudo pip install requests==2.6.0

Collecting requests==2.6.0

Using cached requests-2.6.0-py2.py3-none-any.whl

Installing collected packages: requests

Successfully installed requests-2.6.0

Commandos comunes

pip search <consulta>

pip install <paquete>pip install <paquete>==<version>pip install -r requirements.txt

pip uninstall <paquete>

pip freeze > requirements.txt

pip --version

En Ubuntu conviven pip y pip3,para python2 y python3

respectivamente

Page 70: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Entornos virtualesPodés crear un entorno virtual que maneje una versión específica de Python y sus propios paquetes, esto es un ambiente aislado del resto del sistema, donde podés controlar las versiones específicas de cada módulo que use tu programa, independientemente de lo que tengas instalado a nivel sistema.

$ python3 -m venv mi-entorno

Luego de crearlo hay que activarlo

$ source mi-entorno/bin/activate

Vas a ver que ahora en el prompt aparece el nombre del entorno que estás usando

(mi-entorno)

$

A partir de acá podés instalar paquetes con pip en forma local.

apt-get install python3-venv

Page 72: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

RequestsHTTP forHumans

pip install requests

>>> import requests

>>> r = requests.get('https://api.minirobots.com.ar')

>>> r.status_code

200

>>> r.headers['content-type']

'application/json; charset=utf-8'

>>> r.encoding

'utf-8'

>>> r.text

'{"message":"Welcome to minirobots api"...

>>> r.json()

{'version': '0.0.2', 'date': 'Tuesday, June 06, 2017',

'message': 'Welcome to minirobots api', 'time': '00:29:49'}

Page 73: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Un servicio con Flask

1 from flask import Flask

2 app = Flask(__name__)

3

4 @app.route('/')

5 def index():

6 return "Hola a todos !"

7

8 if __name__ == '__main__':

9 app.run()

app.py

pip install flask

Page 74: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Un servicio con Flask

1 from flask import Flask

2 app = Flask(__name__)

3

4 @app.route('/')

5 def index():

6 return "Hola a todos !"

7

8 if __name__ == '__main__':

9 app.run()

app.py

$> python3 app.py * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Page 75: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Un servicio con Flaskapp.py

$> python3 app.py * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)127.0.0.1 - - [29/Sep/2016 22:54:28] "GET / HTTP/1.1" 200 -

1 from flask import Flask

2 app = Flask(__name__)

3

4 @app.route('/')

5 def index():

6 return "Hola a todos !"

7

8 if __name__ == '__main__':

9 app.run()

Page 76: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Servicio Flask para interfacear con Arduinofrom flask import Flask, request, render_template

app = Flask(__name__)

commands = ['forward', 'backward', 'left', 'right']

@app.route('/')

def index():

if len(request.args.keys()) == 1 and \

request.args.keys()[0] in commands:

command = request.args.keys()[0]

value = int(request.args.get(command))

getattr(turtle, command)(value)

return render_template('index.html')

if __name__ == '__main__':

app.run(host='0.0.0.0', port=8000 )

Código completo: server.py, index.html

Page 77: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Paralelismo

Page 78: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

LoggingLogging provee un set de funciones para loguear tus mensajes, ellas son debug(), info(), warning(), error() y critical().

El nivel por defecto es WARNING y la salida por defecto stdout (la consola)

import logging

# Esto saldrá en la consola

logging.warning("Ojo!")

# Esto no imprimirá nada

logging.info("No me verás")

Loguear a un archivo en modo DEBUG ycambiando el formato por default:

import logging

logging.basicConfig(

filename='example.log',

format='%(asctime)s [%(levelname)s] %(message)s',

level=logging.DEBUG

)

logging.debug('Mensaje que irá al log')

logging.info('Este también')

logging.warning('Y este')

# example.log2017-06-04 19:25:52,550 [DEBUG] Mensaje que irá al log

2017-06-04 19:25:52,550 [INFO] Este también

2017-06-04 19:25:52,550 [WARNING] Y este

Page 79: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

QueueExisten varias implementaciones de colas en Python, usaremos la del módulo multiprocessing que es segura tanto para threads como para procesos.

>>> from multiprocessing import Queue

>>> q = Queue()

>>> q.put(1)

>>> q.put(2)

>>> q.get()

1

>>> q.empty()

False

>>> q.get()

2

>>> q.empty()

True

Page 80: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Threading>>> from threading import Thread

>>> from multiprocessing import Queue

>>> import time

>>> q = Queue()

>>> def worker(q):

... for i in range(5):

... q.put(i)

... time.sleep(10)

...

>>> t = Thread(target=worker, args=(q,))

>>> t.start()

>>> for i in range(5):

... print(q.get())

...

0

1

2

3

4

>>> t

<Thread(Thread-1, stopped)>

Page 81: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Python threads are real system threads

$ ps fax | grep threads.py

7484 pts/2 Sl+ 0:20 | \_ python3 threads.py

$ ps -T -p 7484

PID SPID TTY TIME CMD

7484 7484 pts/2 00:00:03 python3

7484 7485 pts/2 00:00:02 python3

7484 7486 pts/2 00:00:02 python3

7484 7487 pts/2 00:00:02 python3

7484 7497 pts/2 00:00:02 python3

Python utiliza un Global Interpreter Lock (GIL), el cual es un mecanismo que sincroniza la ejecución de threads haciendo que sólamente un thread se ejecute a la vez. La limitación de esto es que no aprovecha múltiples cores.

Page 82: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Threadingq = Queue()

# Put some data into the queue

for item in range(total_data):

q.put(item)

# Put stop signal for workers

for _ in range(total_threads):

q.put(None)

threads = []

for _ in range(total_threads):

t = Thread(target=worker, args=(q,))

t.start()

threads.append(t)

for t in threads:

t.join()

logging.debug("Exiting")

import logging

from threading import Thread

from multiprocessing import Queue

total_threads = 4

total_data = 200

logging.basicConfig(

level=logging.DEBUG,

format='%(asctime)s [%(levelname)s] %(threadName)s

%(message)s'

)

def worker(q):

logging.debug("Starting worker")

while True:

item = q.get()

if item is None:

logging.debug("Exiting worker")

Break

logging.debug("Processing item {}".format(item))

Page 83: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

MultiprocessingMultiprocessing es un paquete que permite crear nuevos procesos utilizando un API similar a la del módulo threading. Debido a que utiliza subprocesos en lugar de hilos (threads), permite llevar a cabo varias operaciones concurrentes sin las limitaciones del Global Interpreter Lock. Corre en sistemas Unix y Windows.

$ ps fax | grep multiprocess

17227 pts/2 Sl+ 0:02 | \_ python3 multiprocess.py

17228 pts/2 S+ 0:01 | \_ python3 multiprocess.py

17229 pts/2 S+ 0:01 | \_ python3 multiprocess.py

17230 pts/2 S+ 0:01 | \_ python3 multiprocess.py

17231 pts/2 S+ 0:01 | \_ python3 multiprocess.py

DEBUG:root:Starting 0DEBUG:root:Starting 1INFO:root:Worker 0, item 0INFO:root:Worker 0, item 1INFO:root:Worker 0, item 3DEBUG:root:Starting 2INFO:root:Worker 0, item 4INFO:root:Worker 2, item 5INFO:root:Worker 0, item 6INFO:root:Worker 2, item 7DEBUG:root:Starting 3INFO:root:Worker 1, item 2INFO:root:Worker 1, item 10INFO:root:Worker 1, item 12INFO:root:Worker 3, item 11INFO:root:Worker 1, item 13INFO:root:Worker 1, item 14INFO:root:Worker 3, item 15INFO:root:Worker 1, item 16INFO:root:Worker 1, item 17INFO:root:Worker 3, item 18INFO:root:Worker 1, item 19DEBUG:root:Exiting 3DEBUG:root:Exiting 1INFO:root:Worker 2, item 8INFO:root:Worker 0, item 9DEBUG:root:Exiting 2DEBUG:root:Exiting 0DEBUG:root:Exiting Main Process

Page 84: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Multiprocessingq = Queue()

# Put some data into the queue

for item in range(total_data):

q.put(item)

# Put stop signal for workers

for _ in range(total_processes):

q.put(None)

processes = []

for _ in range(total_processes):

p = Process(target=worker, args=(q,))

p.start()

processes.append(p)

for p in processes:

p.join()

logging.debug("Exiting")

import logging

from multiprocessing import Process, Queue, cpu_count

total_processes = cpu_count()

total_data = 200

logging.basicConfig(

level=logging.DEBUG,

format='%(asctime)s [%(levelname)s] %(processName)s

%(message)s'

)

def worker(q):

logging.debug("Starting worker")

while True:

item = q.get()

if item is None:

logging.debug("Exiting worker")

Break

logging.debug("Processing item {}".format(item))

Page 85: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Testing

Page 86: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

unittestUnit testing framework

import unittest

class TestStringMethods(unittest.TestCase):

def test_upper(self):

self.assertEqual('foo'.upper(), 'FOO')

def test_isupper(self):

self.assertTrue('FOO'.isupper())

self.assertFalse('Foo'.isupper())

def test_split(self):

s = 'hello world'

self.assertEqual(s.split(), ['hello', 'world'])

# check that s.split fails when the separator is not a string

with self.assertRaises(TypeError):

s.split(2)

if __name__ == '__main__':

unittest.main()

$ python3 strings.py ...----------------------Ran 3 tests in 0.000s

OK

Page 87: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Debugging

Page 88: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

pdbThe Python Debugger

$ python3 -m pdb myscript.py

> /home/lvidarte/Test/python/pdb/myscript.py(1)<module>()

-> num_list = [1, 2, 3]

(Pdb) n

> /home/lvidarte/Test/python/pdb/myscript.py(2)<module>()

-> alpha_list = ['a', 'b', 'c']

(Pdb) j 12

> /home/lvidarte/Test/python/pdb/myscript.py(12)<module>()

-> foo()

(Pdb) s

--Call--

> /home/lvidarte/Test/python/pdb/myscript.py(4)foo()

-> def foo():

(Pdb) n

> /home/lvidarte/Test/python/pdb/myscript.py(5)foo()

-> while num_list:

(Pdb) n

> /home/lvidarte/Test/python/pdb/myscript.py(6)foo()

-> n = num_list.pop(0)

# myscript.py num_list = [1, 2, 3]alpha_list = ['a', 'b', 'c']

def foo(): while num_list: n = num_list.pop(0) print(n) for c in alpha_list: print(c)

if __name__ == '__main__': foo()

Page 89: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

pdbThe Python Debugger (cont...)

(Pdb) n

> /home/lvidarte/Test/python/pdb/myscript.py(7)foo()

-> print(n)

(Pdb) p num_list

[2, 3]

(Pdb) p n

1

(Pdb) l

3

4 def foo():

5 while num_list:

6 n = num_list.pop(0)

7 -> print(n)

8 for c in alpha_list:

9 print(c)

10

11 if __name__ == '__main__':

12 foo()

13

(Pdb) exit

Page 90: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

pdbThe Python Debugger (cont...)

También podés meter esta líneaen cualquier parte de tu programa:

import pdb; pdb.set_trace()

Ni bien tu programa llegue a esta línease ejecutará el debugger.

Page 91: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Raspberry Pi Python♥

https://www.raspberrypi.org/magpi/issues/

Page 92: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

PiCamera

Activar la cámara durante 10 segundos

# 01_preview.py

from picamera import PiCamera

from time import sleep

camera = PiCamera()

camera.start_preview()

sleep(10)

camera.stop_preview()

sudo apt-get install python3-picamera

Page 93: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

PiCamera - PhotosTomar 5 imágenes, una cada 5 segundos

# 02_take_photos.py

from picamera import PiCamera

from time import sleep

camera = PiCamera()

camera.start_preview()

for i in range(5):

sleep(5)

camera.capture('/home/pi/Desktop/image{}.jpg'.format(i))

camera.stop_preview()

Page 94: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

PiCamera - GIF Tomar varias imágenes y generar un .gif

# 03_gif.py

from picamera import PiCamera

from time import sleep

from os import system

camera = PiCamera()

camera.start_preview()

for i in range(10):

camera.capture('image{0:04d}.jpg'.format(i))

camera.stop_preview()

system('convert -delay 10 -loop 0 image*.jpg

animation.gif')

Page 95: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

PiCamera - Recording VideoGrabar 10 segundos de video

# 03_video.py

from picamera import PiCamera

from time import sleep

camera.start_preview()

camera.start_recording('/home/pi/Desktop/video.h264')

sleep(10)

camera.stop_recording()

camera.stop_preview()

omxplayer video.h264

Page 96: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

PiCamera - Configcamera.resolution = (1280, 1024)

camera.sharpness = 0

camera.contrast = 0

camera.brightness = 50

camera.saturation = 0

camera.ISO = 0

camera.video_stabilization = False

camera.exposure_compensation = 0

camera.exposure_mode = 'auto'

camera.meter_mode = 'average'

camera.awb_mode = 'auto'

camera.image_effect = 'none'

camera.color_effects = None

camera.rotation = 0

camera.hflip = False

camera.vflip = False

camera.crop = (0.0, 0.0, 1.0, 1.0)

camera.annotate_text = None

camera_annotate_text_size = 10

camera.annotate_background = Color('blue')

camera.annotate_foreground = Color('yellow')

Page 97: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

PiCamera - Effects Ciclar por todos los efectos disponibles

# 07_effects.py

from picamera import PiCamera, Color

from time import sleep

camera = PiCamera()

camera.annotate_background = Color('black')

camera.annotate_foreground = Color('white')

camera.start_preview()

for effect in camera.IMAGE_EFFECTS:

camera.image_effect = effect

camera.annotate_text = "Effect: %s" % effect

sleep(5)

camera.stop_preview()

negative, solarize, sketch, denoise, emboss, oilpaint, hatch, gpen, pastel, watercolor, film, blur, saturation, colorswap, washedout, posterise, colorpoint, colorbalance, cartoon, deinterlace1, and deinterlace2

Page 98: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

GPIO ZERO

Page 99: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

GPIO Zero - LEDs

from gpiozero import LED

from time import sleep

led = LED(17)

while True:

led.on()

sleep(1)

led.off()

sleep(1)

Page 100: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

GPIO Zero - Buttons

from gpiozero import LED, Button

from signal import pause

led = LED(17)

button = Button(3)

button.when_pressed = led.on

button.when_released = led.off

pause()

Page 101: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

GPIO ZeroCamera capture

from gpiozero import Button

from picamera import PiCamera

from datetime import datetime

from signal import pause

from time import sleep

button = Button(3)

camera = PiCamera()

def capture():

camera.start_preview()

sleep(2)

datetime = datetime.now().isoformat()

path = '/home/pi/Desktop/%s.jpg'

camera.capture(path % datetime)

camera.stop_preview()

sleep(5)

button.when_pressed = capture

pause()

Page 102: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Alarma consensor de movimiento

Page 103: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Alarma 1 from gpiozero import MotionSensor

2 from gpiozero import Buzzer

3 import time

4

5 pir = MotionSensor(22)

6 bz = Buzzer(17)

7

8 while True:

9 print("Ready")

10 pir.wait_for_motion()

11 print("Motion detected!")

12 bz.beep(0.5, 0.25, 8)

13 time.sleep(3) http://nerdlabs.com.ar/blog/2016/6/27/alarma-con-raspberry-pi/

Page 104: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

http://nerdlabs.com.ar/blog/2014/12/4/arduino-snake/

Snak

eSe trata de dos proyectos,Arduino Matrix y Arduino Gamepad

En el ejemplo la matriz funciona sobre un Arduino UNO y el gamepad sobre un Nano, ambos conectados a una Raspberry Pi y controlados con Python

Video

Page 105: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Python en IoT

Page 106: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Lámpara WiFicon Python y NodeMCU

Page 107: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Y se hizo la luzwhile True:

conn, addr = s.accept()

method, url = get_url(conn)

path, query = parse_url(url)

if path == '/':

r = query.get('r', 0)

g = query.get('g', 0)

b = query.get('b', 0)

led.set(r, g, b)

response = template.html % (led.r, led.g, led.b)

conn_send(conn, response)

conn.close()http://nerdlabs.com.ar/blog/2016/8/26/micropython-lampara-rgb/

Page 108: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

RobotArduino

Bluetooth

Page 109: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

from minirobots import turtle

from random import randint

def star(self, n, side):

for _ in range(n):

turtle.forward(side)

turtle.right(360 / n)

turtle.forward(side)

turtle.left(720 / n)

for _ in range(5):

n = randint(5, 7)

side = randint(10, 25)

star(n, side)

Estrellas al azar

http://minirobots.com.ar

Page 110: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

ESP-Car WiFi

Controlado remotamentecon Python

Page 111: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

ESP-Car WiFidef move(direction, speed, ms=None): params = {'dir': direction, 'speed': speed} r = requests.get(ESP_CAR_URL, params=params) if ms is not None: time.sleep(ms / 1000.0)

def right(speed, ms=None): move(DIR_RIGHT, speed, ms)

def left(speed, ms=None): move(DIR_LEFT, speed, ms)

def forward(speed, ms=None): move(DIR_FORWARD, speed, ms)

def reverse(speed, ms=None): move(DIR_REVERSE, speed, ms)

def stop(): move(DIR_STOP, 0, None)

Código completo acá

Page 112: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Tkinter

Page 113: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Tk - Simple Hello world

>>> from Tkinter import *

>>> root = Tk() # main window

>>> w = Label(root, text="Hello, world!")

>>> w.pack()

>>> root.mainloop()

Page 114: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Tk - Ejemplo de grillaimport Tkinter as tk

from minirobots import turtle

root = tk.Tk()

root.title('Tortuga')

bt_forward = tk.Button(root, text='Adelante', command=lambda:turtle.forward(20))

bt_left = tk.Button(root, text='Izquierda', command=lambda:turtle.left(90))

bt_right = tk.Button(root, text='Derecha', command=lambda:turtle.right(90))

bt_backward = tk.Button(root, text='Atrás', command=lambda:turtle.backward(20))

options = dict(padx=10, pady=10, ipadx=20, ipady=20)

bt_forward.grid(row=0, columnspan=2, **options)

bt_left.grid(row=1, column=0, **options)

bt_right.grid(row=1, column=1, **options)

bt_backward.grid(row=2, columnspan=2, **options)

tk.mainloop()

Código completo: ui.py

Page 115: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

TkEjemplocon clase

import tkinter as tk

class Application(tk.Frame):

def __init__(self, master):

super(Application, self).__init__(master)

self.pack()

self.create_widgets()

def create_widgets(self):

self.hello = tk.Button(self, text='Hello', command=self.say_hello)

self.hello.pack(side='top')

self.quit = tk.Button(self, text='Quit', command=self.master.destroy)

self.quit.pack(side='bottom')

def say_hello(self):

print('Hello')

if __name__ == '__main__':

master = tk.Tk()

app = Application(master)

app.mainloop()

Page 117: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Reglas del JuegoNace

3 vecinas

Permanece

2 ó 3 vecinas

Muereo sigue muerta2 o 3 vecinas

Las transiciones dependen del número de células vecinas vivas:

● Una célula muerta con exactamente 3 células vecinas vivas "nace" (al turno siguiente estará viva).

● Una célula viva con 2 ó 3 células vecinas vivas sigue viva.● En otro caso muere o permanece muerta

(por "soledad" o "superpoblación").

Podemos representar esto con un if/else así:

if (cell == DEAD and neigbords_alive == 3) or \ (cell == ALIVE and neigbords_alive in (2, 3)): return ALIVEelse: return DEAD

Page 118: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Game of Lifev0.1

Definimos el tablero y cómo imprimirlo.

En el tablero dibujamos un glider.

Finalmente imprimimos el tablero.

DEAD = 0ALIVE = 1

def print_board(board): for row in board: print(' '.join(['.' if col == DEAD else '#' for col in row]))

if __name__ == '__main__':

# Glider board = [ [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 1, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], ]

print_board(board)

life-v0.1_board.py

Page 119: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Game of Lifev0.2

Debajo de la función print_board

agregamos una función para obtener

el tamaño del tablero.

Finalmente imprimimos su

resultado.

def print_board(board): for row in board: print(' '.join(['.' if col == DEAD else '#' for col in row]))

def get_board_size(board): width = len(board[0]) # explícito mejor que implícito height = len(board) return (width, height)

...

print_board(board)

width, height = get_board_size(board)

print("width {}, height {}".format(width, height))

life-v0.2_board_size.py

Page 120: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Game of Lifev0.3

Creamos una función para obtener todas las células vecinas.

Reemplazamos la impresión del tamaño

del tablero por las células vecinas para

cada célula del tablero.

def get_neighbors(cell_pos, board): x_center, y_center = cell_pos width, height = get_board_size(board)

x_left = x_center-1 if x_center-1 >= 0 else width-1 x_right = x_center+1 if x_center+1 < width else 0 y_up = y_center-1 if y_center-1 >= 0 else height-1 y_down = y_center+1 if y_center+1 < height else 0

return (board[y_up][x_left], board[y_up][x_center], board[y_up][x_right], board[y_center][x_left], board[y_center][x_right], board[y_down][x_left], board[y_down][x_center], board[y_down][x_right])...

for x in range(width): for y in range(height): cell_pos = (x, y) neighbors = get_neighbors(cell_pos, board) print(cell_pos, neighbors)

life-v0.3_neighbors.py

Page 121: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Game of Lifev0.4

Modificamos la función anterior para

que devuelva directamente el

total de células vecinas vivas.

def count_neighbors_alive(cell_pos, board): x_center, y_center = cell_pos width, height = get_board_size(board)

x_left = x_center-1 if x_center-1 >= 0 else width-1 x_right = x_center+1 if x_center+1 < width else 0 y_up = y_center-1 if y_center-1 >= 0 else height-1 y_down = y_center+1 if y_center+1 < height else 0

return (board[y_up][x_left], board[y_up][x_center], board[y_up][x_right], board[y_center][x_left], board[y_center][x_right], board[y_down][x_left], board[y_down][x_center], board[y_down][x_right]).count(ALIVE)...

for x in range(width): for y in range(height): cell_pos = (x, y) neighbors_alive = count_neighbors_alive(cell_pos, board) print(cell_pos, neighbors_alive)

life-v0.4_neighbors_alive.py

Page 122: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Game of Lifev0.5

Creamos una función que nos devuelva,

teniendo en cuenta el estado actual de la célula y el total de

vecinas vivas,cuál será el próximo estado de la misma:

viva o muerta.

def get_next_cell_state(cell_state, neighbors_alive): if (cell_state == DEAD and neighbors_alive == 3) or \ (cell_state == ALIVE and neighbors_alive in (2, 3)): return ALIVE else: return DEAD

...

for x in range(width): for y in range(height): cell_pos = (x, y) cell_state = board[y][x] # alive or dead neighbors_alive = count_neighbors_alive(cell_pos, board) cell_next_state = get_next_cell_state(cell_state, neighbors_alive) print(cell_pos, neighbors_alive, cell_state, cell_next_state)

life-v0.5_next_cell_state.py

Page 123: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Game of Lifev0.6

Juntando las dos últimas funciones

creamos otra (tick) que recorra todo el

tablero y genere otro con el nuevo estado.

Finalmente llamamos varias veces a la

función tick.

def tick(board): width, height = get_board_size(board) board_ = [[DEAD] * width for _ in range(height)] for x in range(width): for y in range(height): cell_pos = (x, y) cell_status = board[y][x] neighbords_alive = count_neighbors_alive(cell_pos, board) board_[y][x] = get_next_cell_state(cell_status, neighbords_alive) return board_

...

for i in range(33): width, _ = get_board_size(board) if i: print('-' * ((width * 2) - 1)) print_board(board) board = tick(board) sleep(.5)

life-v0.6_tick.py

Ya tenemos una versión funcional del Juego de la

Vida!

Page 124: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Game of Lifev0.7

Es hora de convertir a board en una clase.

Lo primero es crear el constructor y un par

de métodos para setear el tablero, que

seguirá siendo una lista anidada como el

anterior.

class Board:

DEAD = 0 ALIVE = 1

def __init__(self, width=8, height=8): self._width = width self._height = height self.set(self._get_empty_board_list())

def set(self, board_list): self._board_list = [row[:] for row in board_list] # deep copy self._width = len(board_list[0]) self._height = len(board_list)

def _get_empty_board_list(self): return [[self.DEAD] * self._width for _ in range(self._height)]

def get(self): return self._board_list

life-v0.7_class_board.py

Paso 1

Page 125: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Game of Lifev0.7

Movemos get_board_size a size y adaptamos un poco count_neighbors_alive para convertirlo en un

método de la clase.

def size(self): return (self._width, self._height)

def count_neighbors_alive(self, x, y): x_center, y_center = x, y

x_left = x_center-1 if x_center-1 >= 0 else self._width-1 x_right = x_center+1 if x_center+1 < self._width else 0 y_up = y_center-1 if y_center-1 >= 0 else self._height-1 y_down = y_center+1 if y_center+1 < self._height else 0

return (self._board_list[y_up][x_left], self._board_list[y_up][x_center], self._board_list[y_up][x_right], self._board_list[y_center][x_left], self._board_list[y_center][x_right], self._board_list[y_down][x_left], self._board_list[y_down][x_center], self._board_list[y_down][x_right]).count(self.ALIVE)

life-v0.7_class_board.py

Paso 2

Page 126: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Game of Lifev0.7

Hacemos lo mismo con el resto de las

funciones, simplemente las

adaptamos mínimamente para

convertirlas en métodos de la clase.

def get_next_cell_state(self, cell_state, neighbors_alive): if (cell_state == self.DEAD and neighbors_alive == 3) or \ (cell_state == self.ALIVE and neighbors_alive in (2, 3)): return self.ALIVE else: return self.DEAD

def tick(self): board_list = self._get_empty_board_list() for x in range(self._width): for y in range(self._height): cell_state = self._board_list[y][x] neighbors_alive = self.count_neighbors_alive(x, y) args = (cell_state, neighbors_alive) board_list[y][x] = self.get_next_cell_state(*args) self._board_list = board_list

life-v0.7_class_board.py

Paso 3

Page 127: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Game of Lifev0.7

La función print_board la

dejamos fuera de la clase haciéndole unas

correcciones menores.

Creamos una instancia de Board y

realizamos las últimas correcciones.

# Gliderboard_list = [ [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0],

...

[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0],]

board = Board()board.set(board_list)

def print_board(board_list): for row in board_list: print(' '.join(['.' if col == Board.DEAD else '#' for col in row]))

for i in range(33): width, _ = board.size() if i: print('-' * ((width * 2) - 1)) print_board(board.get()) board.tick() sleep(.5)

life-v0.7_class_board.py

Paso 4

Page 128: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Game of Lifev0.8

Importamos tkinter y creamos la clase Life extendiendo la clase

Frame.

También creamos un widget de tipo Canvas

con un tamaño de cell_size por cada

célula.

import tkinter as tk

class Life(tk.Frame):

def __init__(self, board, cell_size=20): super(Life, self).__init__(tk.Tk()) self.master.title("Game of Life") self.grid() self.board = board self.cell_size = cell_size self.create_widgets() self.mainloop()

def create_widgets(self): width, height = self.board.size() kwargs = { 'width' : width * self.cell_size, 'height': height * self.cell_size, 'bg' : 'white', } self.canvas = tk.Canvas(self, **kwargs) self.canvas.grid()

life-v0.8_tkinter.py

Paso 1

Page 129: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Game of Lifev0.8

Finalmente reemplazamos todo lo

debajo delif __name__

por lo siguiente

if __name__ == '__main__':

board = Board(width=20, height=20) life = Life(board, cell_size=30)

life-v0.8_tkinter.py

Paso 2

Page 130: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Game of Lifev0.9

Creamos los métodos para generar la grilla base y agregamos la

llamada correspondiente en el

constructor.

self.cell_size = cell_size self.create_widgets() self.draw_grid() self.mainloop()

...

def draw_grid(self): self.draw_vertical_lines() self.draw_horizontal_lines()

def draw_vertical_lines(self, color='gray'): width, height = self.board.size() for i in range(width - 1): x = (self.cell_size * i) + self.cell_size y0 = 0 y1 = self.cell_size * height self.canvas.create_line(x, y0, x, y1, fill=color)

def draw_horizontal_lines(self, color='gray'): width, height = self.board.size() for i in range(height - 1): x0 = 0 x1 = self.cell_size * width y = (self.cell_size * i) + self.cell_size self.canvas.create_line(x0, y, x1, y, fill=color)

life-v0.9_grid.py

Page 131: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Game of Lifev0.10

Creamos en Life el método draw_cell, que nos permitirá dibujar cualquier

célula y guardar su ID en cells_alive.

También agregamos el método set_alive a

la clase Board.

self.draw_grid() self.cells_alive = {} self.mainloop()

...

def draw_cell(self, x, y, color='black'): x0 = x * self.cell_size y0 = y * self.cell_size x1 = x0 + self.cell_size y1 = y0 + self.cell_size args = (x0, y0, x1, y1) _id = self.canvas.create_rectangle(*args, width=0, fill=color) self.cells_alive[(x, y)] = _id self.board.set_alive(x, y)

...

def set_alive(self, x, y): self._board_list[y][x] = self.ALIVE

life-v0.10_draw_cell.py

Page 132: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Game of Lifev0.11

Creamos los métodos del_cell y toggle_cell y asociamos el evento

click a este último.

También agregamos el método set_dead en

Board.

self.cells_alive = {} self.create_events() self.mainloop()...

def del_cell(self, x, y): self.canvas.delete(self.cells_alive[(x, y)]) del self.cells_alive[(x, y)] self.board.set_dead(x, y)

def toggle_cell(self, event): x = event.x // self.cell_size y = event.y // self.cell_size if (x, y) in self.cells_alive: self.del_cell(x, y) else: self.draw_cell(x, y)

def create_events(self): self.canvas.bind_all('<Button 1>', self.toggle_cell)

...

def set_dead(self, x, y): self._board_list[y][x] = self.DEAD

life-v0.11_toggle_cell.py

Page 133: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Game of Lifev1.0

Creamos los métodos clear, draw y tick y

asociamos la tecla espacio a este último.

Agregamos el método get_cells_alive

en Board.

Listo, terminamos!

def create_events(self): self.canvas.bind_all('<Button 1>', self.toggle_cell) self.canvas.bind_all('<space>', self.tick)

def tick(self, event): self.board.tick() self.draw()

def draw(self): self.clear() for cell_pos in self.board.get_cells_alive(): self.draw_cell(*cell_pos)

def clear(self): for _id in self.cells_alive.values(): self.canvas.delete(_id) self.cells_alive = {}...

def get_cells_alive(self): cells = [] for x in range(self._width): for y in range(self._height): if self._board_list[y][x] == self.ALIVE: cells.append((x, y)) return cells

life-v1.0.py

Page 134: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores
Page 135: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Cosas que hice

Page 136: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Mi blog con Django

https://github.com/lvidarte/django-nerdlabs

Page 137: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Lai Sistema Cliente - Servidor para sincronizar anotaciones entre múltiples computadoras, lo uso principalmente para snippets o comandos complejos.

El servidor funciona con Tornado.

Usa encriptación y funciona con clave pública/privada.

$> lai sync

$> lai search "config"240: update-alternatives --config editor762: git config --global user.email "<mail>"843: dpkg-reconfigure locales

https://github.com/lvidarte/lai-clienthttps://github.com/lvidarte/lai-server

Page 138: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Visor de imágenes GTK Usagevimg # view all images in current dir

vimg image.png # view just image.png

vimg -r dir # view recursively all images in dir

Normal Mode

Space,j next image

Backspace,k previous image

i show/hide info

m add/remove image from memory list

o next image in memory list

p previous image in memory list

q quit

f enter/exit fullscreen mode

: enter to command mode

Command Mode

:cp <target> copy current image to directory

:mcp <target> copy all images in memory to dir

:q quit

Esc return to normal mode

https://github.com/lvidarte/vimg

Page 139: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Juegos con Python

Tetris - 450 líneashttps://github.com/lvidarte/tetris

Page 140: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Rompecabezas150 líneas

https://github.com/lvidarte/sliding-puzzle

Page 141: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Juegode la Vida280 líneas https://github.com/lvidarte/game-of-life

El juego de la vida es un autómata celular diseñado por el matemático británico John Horton Conway en 1970.

Page 142: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

11, un clon del 2048 con Python y curses

Es un clon del 2048 para la consola en 150 líneas.Lo llamé 11 porque utiliza (muestra) los exponentes en lugar del resultado, por lo tanto 1 + 1 = 2,pero 2 + 2 = 3, y así. Entonces se gana llegando al 11, ya que 2 ** 11 = 2048

Se juega con las teclas de Vim (hjkl)

https://gist.github.com/lvidarte/68644f0cda09c9476682

Page 143: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Laberintos con Python

Es una implementación de un sencillo algoritmo de generación de laberintos llamado Depth-first search.

El programa permite generar laberintos de cualquier tamaño. El juego consiste en mover el cuadrado rojo hasta el verde en la menor cantidad de movidas posibles.

https://github.com/lvidarte/maze

Page 144: Pythonnerdlabs.com.ar/media/2017/07/12/Python.pdf · 2017-07-12 · Estilos Python es un lenguaje de programación multiparadigma. Esto significa que más que forzar a los programadores

Gracias !