Beruflich Dokumente
Kultur Dokumente
Francisco Bórquez
Departamento de Informática
Universidad Técnica Federico Santa María
1er SEM,2010
Departamento de Informática
Universidad Técnica Federico Santa María
Script/Guión
• Si en alguna ocasión has escrito un guion largo
para un intérprete de órdenes (o shell script),
puede que conozcas esta sensación:
• Te encantaría añadir una característica más, pero
ya es tan lento, tan grande, tan complicado...O la
característica involucra una llamada al sistema u
otra función accesible sólo desde C.
• El problema en sí no suele ser tan complejo como
para transformar el guion en un programa en C.
Igual el programa requiere cadenas de longitud
variable u otros tipos de datos (como listas
ordenadas de nombres de archivo) fáciles en sh,
pero tediosas en C.
• O quizá no tienes tanta soltura con C.
Departamento de Informática
Lenguajes de Programación ILI-153 2
Script/Guión
Departamento de Informática
Lenguajes de Programación ILI-153
Python: un híbrido moderno
Departamento de Informática
Lenguajes de Programación ILI-153
Python
Departamento de Informática
Lenguajes de Programación ILI-153
Hola Mundo en Python
Departamento de Informática
Lenguajes de Programación ILI-153
Características de Python
• Muy legible y elegante
– Imposible escribir código ofuscado
• Simple y poderoso
– Minimalista: todo aquello innecesario no hay que escribirlo (;, {, },
'\n')
– Muy denso: poco código hace mucho
– Soporta objetos y estructuras de datos de alto nivel: strings, listas,
diccionarios, etc.
– Múltiples niveles de organizar código: funciones, clases, módulos,
y paquetes
• Python standard library (http://www.python.org/doc/current/lib/lib.html)
contiene clases de utilidad
– Si hay áreas que son lentas se pueden reemplazar por plugins en
C o C++, siguiendo la API para extender o empotrar Python en una
aplicación, o a través de herramientas como SWIG, sip o Pyrex.
Departamento de Informática
Lenguajes de Programación ILI-153
Características de Python II
• De scripting
– No se tiene que declarar constantes y variables antes de
utilizarlas
– No requiere paso de compilación/enlazador
– La primera vez que se ejecuta un script de Python se compila y
genera bytecode que es luego interpretado
– Alta velocidad de desarrollo y buen rendimiento
• Código interoperable (como en Java "write once run
everywhere")
– Se puede utilizar en múltiples plataforma (más aún que Java)
– Puedes incluso ejecutar Python dentro de una JVM (Jython)
• Open Source
– Razón por la cual la Python Library sigue creciendo y creciendo
• De propósito general
– Puedes hacer en Python todo lo que puedes hacer con C# o
Java, o más
Departamento de Informática
Lenguajes de Programación ILI-153
Peculiaridades sintácticas
Departamento de Informática
Lenguajes de Programación ILI-153
Prototyping
Departamento de Informática
Lenguajes de Programación ILI-153
Nada se puede entender sin OOP
Departamento de Informática
Lenguajes de Programación ILI-153
Python vs. Java
Departamento de Informática
Lenguajes de Programación ILI-153
Python vs. Jython
• Python
– También llamado Cpython
– Implementación del lenguaje Python en C
– Python C API permite extender Python con
librerías realizadas en C
– Partes que requieren mayor rendimiento en
Python están implementadas en C o C++ y
tan sólo contienen una pequeña capa de
Python encima
• Jython
– Implementación de Python en Java
– Permite acceder a todas las APIs de Java
• P.E. Podemos producir Swing GUIs desde Python
Departamento de Informática
Lenguajes de Programación ILI-153
¿Para qué [no] es útil?
• Python no es el lenguaje perfecto, no es bueno para:
– Programación de bajo nivel (system-programming), como
programación de drivers y kernels
• Python es de demasiado alto nivel, no hay control directo sobre
memoria y otras tareas de bajo nivel
– Aplicaciones que requieren alta capacidad de computo
• No hay nada mejor para este tipo de aplicaciones que el viejo C
• Python es ideal:
– Como lenguaje sticky/pegamento para combinar varios
componentes juntos (filosofía modular de UNIX-pipes)
– Para llevar a cabo prototipos de sistema
– Para la elaboración de aplicaciones cliente
– Para desarrollo web y de sistemas distribuidos
– Para el desarrollo de tareas científicas, en los que hay que
simular y prototipar rápidamente
Departamento de Informática
Lenguajes de Programación ILI-153
Usando Python desde línea comando
• Para arrancar el intérprete (Python interactivo) ejecutar:
$ python
Python 2.3.3 (#1, Dec 30 2003, 08:29:25)
[GCC 3.3.1 (cygwing special)] on cygwin
Type "help", "copyright", "credits" or "license" for more
information.
>>>
• Un comando simple:
>>> print "Hola Mundo"
Hola Mundo
>>>
• Para salir del intérprete Ctrl-D o Ctrl-Z (depende SO) o:
>>> import sys
>>> sys.exit()
$
Departamento de Informática
Lenguajes de Programación ILI-153
Ejecutando programa script.py
Departamento de Informática
Lenguajes de Programación ILI-153
Sentencias y bloques
Departamento de Informática
Lenguajes de Programación ILI-153
Identificadores
• Los identificadores sirven para nombrar variables,
funciones y módulos
– Deben empezar con un carácter no numérico y
contener letras, números y '_‘
– Python es case sensitive
• Palabras reservadas:
– and elif global or assert else if pass break except
import print class exec in raise continue finally is return
def for lambda try del from not while
• Variables y funciones delimitadas por __
corresponden a símbolos implícitamente definidos:
__name__ nombre de función
__doc__ documentación sobre una función
__init__() constructor de una clase
Departamento de Informática
Lenguajes de Programación ILI-153
Tipos de datos I
Departamento de Informática
Lenguajes de Programación ILI-153
Tipos de datos II
• Strings, delimitados por un par de (', " ,"""). Dos string juntos sin
delimitador se unen
>>> print "Hi" "there"
Hithere
– Los códigos de escape se expresan a través de '\':
>>>print '\n‘
– Raw strings (sin procesar string “en bruto”)
>>> print r'\n\\' # no se 'escapa' \n
– Es lo mismo ' que ", p.e. "\\[foo\\]" r'\[foo\]‘
>>> len('La vida es mucho mejor con Python.')
>>> 34
>>> 'La vida es mucho mejor con Python.'.upper()
'LA VIDA ES MUCHO MEJOR CON PYTHON.'
>>> "La vida es mucho mejor con Python".find("Python")
27
>>> 'La vida es mucho mejor con Python'.replace('Python', 'Jython')
'La vida es mucho mejor con Jython’
Departamento de Informática
Lenguajes de Programación ILI-153
Tipos de datos III
Departamento de Informática
Lenguajes de Programación ILI-153
Tipos de datos IV
• Listas []
– Indexadas por un entero comienzan en 0 (soporta
indexación negativa):
>>> meses = ["Enero", "Febrero"]
>>> print meses[0]
Enero
>>> #de atrás para adelante -1 feberero -2 enero
print meses[-2]
Enero
>>> meses.append("Marzo")
>>> print meses
['Enero', 'Febrero', 'Marzo']
– Más (+) es el operador de concatenación:
>>> print meses+meses
['Enero', 'Febrero', 'Marzo', 'Enero', 'Febrero‘,'Marzo']
Departamento de Informática
Lenguajes de Programación ILI-153
Tipos de datos IV
• Las listas pueden contener cualquier tipo de objetos Python:
>>> meses.append (meses)
>>> print meses
['Enero', 'Febrero', 'Marzo', ['Enero', 'Febrero', 'Marzo' ]]
>>> meses.append(1)
['Enero', 'Febrero', 'Marzo', ['Enero', 'Febrero', 'Marzo' ], 1]
• Para añadir un elemento a una lista:
>>> items = [4, 6]
>>> items.insert(0, -1)
>>> items
[-1, 4, 6]
• Para usar una lista como una pila, se pueden usar append y pop:
>>> items.append(555)
>>> items [-1, 4, 6, 555]
>>> items.pop()
555
>>> items [-1, 4, 6]
• Lista por comprensión:
mylist = [x*x for x in range(3)]
Departamento de Informática
Lenguajes de Programación ILI-153
Funciones para listas
• len ( l i s t )
• del l i s t [ x : y ]
• l i s t . extend ( l )
• list.insert(i,x)
• l i s t . remove ( x )
• l i s t . count ( x )
• list.sort()
• l i s t . reverse ( )
• l i s t . append ( x ) # Pi l a y Cola
• l i s t . pop ( ) # Pi l a
• l i s t . pop ( 0 ) # Cola
Departamento de Informática
Lenguajes de Programación ILI-153 28
Slicing
– Dos puntos (:) es el operador de rodajas o Slice,
– permite trabajar con una porción de la lista, el elemento indicado
por el segundo parámetro no se incluye:
>>> print meses[1:2]
['Febrero']
• Slicing/rodajas:
– s[m:n]
• del m-avo componente, al final pero excluir el n-avo
– s [m:]
• del m-avo al final,
– s[:n]
• del comienzo, al final pero excluir el n-avo
– s[:]
• todos los componentes
– s*4
• repeticiones
Departamento de Informática
Lenguajes de Programación ILI-153
Tipos de datos V
• Tuplas (), lo mismo que listas, pero con pares de valores , e.j. (1, 2)
• Diccionarios {} arrays asociativos o mapas, indexados por una clave,
la cual puede ser cualquier objeto Python, aunque normalmente es
una tupla:
>>> mydict = {"altura" : "media", "habilidad" : "intermedia",
"salario" : 1000 }
>>> print mydict
{altura': 'media', 'habilidad': 'intermedia', 'salario': 1000}
>>> print mydict["habilidad"]
intermedia
– Puedes comprobar la existencia de una clave en un diccionario usando
has_key:
if mydict.has_key('altura'):
print 'Nodo encontrado'
– Lo mismo se podría hacer:
if 'altura' in mydict:
print 'Nodo encontrado'
Departamento de Informática
Lenguajes de Programación ILI-153
Como se ve?
Departamento de Informática
Lenguajes de Programación ILI-153
Simple interactive model
$ python pres.py # carga y ejecuta
france: chirac has 0 years to go
us: clinton esta fuera de la oficina
romania: illiescu has 3 years to go
peru: fujimori esta fuera de la oficina
Departamento de Informática
Lenguajes de Programación ILI-153
Diccionarios
• asignación / modificación
>>> rulers ["peru"][2]=10 //ver 2.2
>>> rulers ["mexico"] = ["fox", 2000, 6]
>>> rulers ["pakistan"] = [ ] #no requiere consistencia tipo
Departamento de Informática
Lenguajes de Programación ILI-153
Operadores
Departamento de Informática
Lenguajes de Programación ILI-153 36
Control de Flujo
q = 4
h = 5
if q < h :
print "primer test pasado"
else:
print "segundo test pasado"
>>> python condicional.py
primer test pasado
Departamento de Informática
Lenguajes de Programación ILI-153
Control de Flujo: bucles
• while es sentencia de repetición. Ejecuta un bloque
de código hasta que una condición es falsa.
• Por ejemplo:
reply = 'repite'
while reply == 'repite':
print 'Hola'
reply = raw_input('Introduce "repite" para
hacerlo de nuevo: ')
Hola
Introduce "repite" para hacerlo de nuevo:
repite
Hola
Introduce "repite" para hacerlo de nuevo:
adiós
Departamento de Informática
Lenguajes de Programación ILI-153
Control de flujo
def fun(number = 23):
running = True
while running:
guess = int(raw_input("Ingrese un numero: " ))
if guess == number:
print "Correcto!"
running = False
elif guess < number :
print "Incorrecto , es mayor"
else:
print "Incorrecto , es menor"
else:
print "Termino el Loop."
print "Termino el programa"
raw_input ("Pulse enter para salir: " )
Departamento de Informática
Lenguajes de Programación ILI-153 39
While con salto incondicional
>>> while True:
s = raw_input ("Ingrese String : " )
if s == “quit" :
break
if len(s) > 3:
continue
print "Tiene que ser mas largo"
Departamento de Informática
Lenguajes de Programación ILI-153 40
Control de Flujo: bucles
1 2 3 4
• La función range genera una secuencia
descrita por ([start,] end [,step]), donde los
campos start y step son opcionales. Start
es 0 y step es 1 por defecto.
Departamento de Informática
Lenguajes de Programación ILI-153
Control de Flujo: bucles
Departamento de Informática
Lenguajes de Programación ILI-153 43
Funciones
def intersect (seq1, seq2): # sin info de tipo
res = [ ] # inicializando lista
for x in seq1: # iterando sobre la lista
if x in seq2: # miembro pre construido
res.append (x)
return res
Departamento de Informática
Lenguajes de Programación ILI-153
Funciones
def fib(n):
"""La serie de Fibonacci hasta n"""
a, b = 0, 1
while b < n:
print b,
a, b = b, a+b
Departamento de Informática
Lenguajes de Programación ILI-153 45
Funciones
• Una función se declara usando la palabra clave def
def myfunc(a,b):
sum = a + b
return sum
>>> print myfunc (5,6)
11
• A una función se le pueden asignar parámetros por
defecto:
def myfunc(a=4,b=6):
sum = a + b
return sum
>>>print myfunc()
10
>>>print myfunc(b=8)
12
Departamento de Informática
Lenguajes de Programación ILI-153
Ejemplo de Valores por Defecto
def ask_ok(prompt, retries=4, complaint='Yes or no,
please!'):
while True:
ok = raw_input(prompt)
if ok in ('y', 'ye', 'yes'): return True
if ok in ('n', 'no', 'nop', 'nope'): return False
retries = retries - 1
if retries < 0: raise IOError, 'refusenik user'
print complaint
• Podemos llamarla
>>>ask_ok('Hola: ')
>>>ask_ok('Chao: ',complaint='en gringo yes/no')
>>>ask_ok('Prompt ',1,"nada")
Departamento de Informática
Lenguajes de Programación ILI-153 47
Funciones: n° párametros variable
• Listas de argumentos y argumentos basados en palabras
clave:
def testArgLists_1(*args, **kwargs):
print 'args:', args
print 'kwargs:', kwargs
Departamento de Informática
Lenguajes de Programación ILI-153
Módulos
• Un módulo es una colección de métodos en un archivo
que acaba en .py. El nombre del archivo determina el
nombre del módulo en la mayoría de los casos.
• E.j. modulo.py:
def one(a):
print "in one"
def two (c):
print "in two“
• Uso de un módulo:
>>> import modulo
>>> dir(modulo) # lista contenidos módulo
['__builtins__', '__doc__', '__file__', '__name__',
'one', 'two']
>>> modulo.one(2)
in one
Departamento de Informática
Lenguajes de Programación ILI-153
Módulos
Departamento de Informática
Lenguajes de Programación ILI-153
Módulos II
Departamento de Informática
Lenguajes de Programación ILI-153 52
Clases y herencia
• Notaciones estándar: super clases, clases
derivadas, self (como this en otros lenguajes),
despacho dinámico
• Cada clase y cada objeto es un namespace
(unidad de encapsulamiento) con un diccionario
• Para ubicar una operación, buscar en el diccionario
del objeto (tabla de despacho). Si no lo encuentra,
examina las superclases.
• Operador de sobrecarga se usa a través de los
sgtes operadores predefinidos:
__init__ constructor
__del__ destructor
__add__ operador “+”
__repr__ printing, representación en salida
Departamento de Informática
Lenguajes de Programación ILI-153
Python Orientado a Objetos
Departamento de Informática
Lenguajes de Programación ILI-153
Python Class Example
#!/usr/local/bin/python
Departamento de Informática
Lenguajes de Programación ILI-153
Miembros de Datos creados implícitamente
class Number:
def __init__ (self, start):
self.data = start; # es definida la data
def __add__ (self, other): # numero + numero
return Number (self.data + other.data)
def __repr__ (self):
return ‘self.data’ # convierte a string
• nota: no hay manera de sobrecargar
(Number + integer) etc.
Departamento de Informática
Lenguajes de Programación ILI-153
Algunas clases pueden ser una coleccion
class collection:
def __getitem__ (self, i):
return self.data[i] #la data es indexable
>>> X=collection()
>>> X.data = [1, 2, 3]
>>> for item in X:
print item
Departamento de Informática
Lenguajes de Programación ILI-153
Clases y métodos son objetos
class widget:
def doit (self, message):
print message
Gizmo1 = widget ( );
Gizmo2 = widget ( );
def factory (aClass, *args): # class parameter
return apply (aClass, args);
thing = factory (widget);
doer = thing.doit;
doer (“show it”); #el mismo ya esta enlazado
Departamento de Informática
Lenguajes de Programación ILI-153
Clases
• Una clase contiene una colección de métodos. Cada
método contiene como primer parámetro (self) que hace
referencia a un objeto. self equivalente a this en C++
class PenguinPen:
def __init__(self):
self.penguinCount = 0
def add (self, number = 1):
""" Add penguins to the pen. The default number is 1 """
self.penguinCount = self.penguinCount + number
def remove (self, number = 1):
""" Remove one or more penguins from the pen """
self.penguinCount = self.penguinCount - number
def population (self):
""" How many penguins in the pen- """
return self.penguinCount
penguinPen = PenguinPen()
penguinPen.add(5) # Tux y su familia
print penguinPen.population()
$ python PenguinPen.py
5
Departamento de Informática
Lenguajes de Programación ILI-153
Más clases/Herencia
class Basic:
def __init__(self, name):
self.name = name
def show(self):
print 'Basic -- name: %s' % self.name
Departamento de Informática
Lenguajes de Programación ILI-153
Probando clases
>>>obj1 = Basic('Manzana')
>>>obj1.show()
Basic -- name: Manzana
>>>obj2 = Special('Naranja', 1)
>>>obj2.show()
Basic -- name: Naranja
Special -- upper name: NARANJA.
It's edible.
Departamento de Informática
Lenguajes de Programación ILI-153
Herencia Múltiple
Departamento de Informática
Lenguajes de Programación ILI-153 62
class Ford( Startibartfast, Arthur ):
#!/usr/local/bin/python x = 42.0
def prefect(self):
#------------------------------------------------------------- print "Hello from prefect\n" + str( Ford.x )
#-------------------------------------------------------------
class Startibartfast:
def hello(self):
f = Ford()
print "Hello from Startibartfast's hello method"
f.prefect()
#-------------------------------------------------------------
class Arthur: f.hello()
def hello(self):
f.doSomething( 12345.001 )
print "Hello from Arthur's hello method\n"
return None
Departamento de Informática
Lenguajes de Programación ILI-153
Errores y excepciones
Departamento de Informática
Lenguajes de Programación ILI-153
Excepciones
Departamento de Informática
Lenguajes de Programación ILI-153
Cláusulas except
try:
statement(s)
except [expression [, target]]:
statement(s)
[else:
statement(s) ]
[finally:
statement(s) ]
Departamento de Informática
Lenguajes de Programación ILI-153
Ejemplo
import sys
try :
f = open("myfile.txt","r")
s = f.readline()
i = int(s.strip())
except IOError,(errno,strerror):
print " I/O error(%s) : %s " % (errno,strerror)
except ValueError :
print " Could not conver t data to an integer. "
except :
print " Unexpected error : " , sys.excinfo( ) [ 0 ]
raise
raw_input("Ingrese enter para continuar")
Departamento de Informática
Lenguajes de Programación ILI-153
Excepciones
• Cada vez que un error ocurre se lanza una excepción, visualizándose un
extracto de la pila del sistema. E.j. si variable a no ha sido enlazada(ligada):
>>> print a
Departamento de Informática
Lenguajes de Programación ILI-153
Excepciones, etc.
Departamento de Informática
Lenguajes de Programación ILI-153
Excepciones personalizadas
class E(RuntimeError):
def __init__(self, msg):
self.msg = msg
def getMsg(self):
return self.msg
try:
raise E('mi mensaje de error')
except E, obj:
print 'Msg:', obj.getMsg()
• # module1.py
class class1:
def __init__(self):
self.description = 'class #1'
def show(self):
print self.description
• # module2.py
class class2:
def __init__(self):
self.description = 'class #2'
def show(self):
print self.description
Departamento de Informática
Lenguajes de Programación ILI-153
Paquetes III
• # testpackage.py
import package_example
c1 = package_example.class1()
c1.show()
c2 = package_example.class2()
c2.show()
• Visualizaría:
class #1
class #2
• La localización de los paquetes debe
especificarse o bien a través de la variable de
entorno PYTHONPATH o en código del script
mediante sys.path
Departamento de Informática
Lenguajes de Programación ILI-153
Paquetes IV
• Como en Java el código de un paquete puede
recogerse en un .zip:
>>> import zipfile
>>> a=zipfile.PyZipFile('mipackage.zip', 'w', zipfile.ZIP_DEFLATED)
>>> a.writepy('package_example')
>>> a.close()
>>> ^Z # ^D depende de SO
• Luego lo puedes importar y usar insertando su path en
sys.path o alternativamente añadiendo a la variable de
entorno PYTHONPATH una referencia al nuevo .zip
creado:
$ mkdir prueba; cp mipackage.zip prueba
$ export PYTHONPATH=/home/dipina/examples/prueba/mipackage.zip
>>> import sys # esta y la siguiente no hacen falta si se ha
inicializado PYTHONPATH
>>> sys.path.insert(0, '/home/dipina/examples/prueba/mipackage.zip')
>>> import package_example
>>> class1 = package_example.module1.class1()
>>> class1.show()
class #1
>>> ^Z
Departamento de Informática
Lenguajes de Programación ILI-153
Manejo de archivos
• Leer un archivo
fh = open("holamundo.py") #crea objeto de tipo archivo
for line in fh.readlines() : # lee todas las líneas
print line,
fh.close()
$ python leerarchivo.py
#!/usr/bin/python
print "Hola mundo“
• Escribir un archivo
fh = open("out.txt", "w")
fh.write ("estamos escribiendo ...\n")
fh.close()
$ python escribirarchivo.py
$ cat out.txt
estamos escribiendo ...
• Nota: existe el modulo pickle se utiliza para la serialización de objetos (objetos
persistentes).
Departamento de Informática
Lenguajes de Programación ILI-153
Más sobre print
sys.stdout = PrintRedirect('tmp.log')
print 'Log message #1'
print 'Log message #2'
print 'Log message #3'
Departamento de Informática
Lenguajes de Programación ILI-153
Variables globales en Python
• Usar identificador global para referirse a variable global:
NAME = "Manzana"
def show_global():
name = NAME
print '(show_global) nombre: %s' % name
def set_global():
global NAME
NAME = 'Naranja'
name = NAME
print '(set_global) nombre: %s' % name
>>>show_global()
( show_global) nombre: Manzana
>>>set_global()
(set_global) nombre: Naranja
>>>show_global()
(show_global) nombre: Naranja
Departamento de Informática
Lenguajes de Programación ILI-153
Expresiones Regulares
Departamento de Informática
Lenguajes de Programación ILI-153
Expresiones Regulares
Departamento de Informática
Lenguajes de Programación ILI-153
Otros Modificadores
Departamento de Informática
Lenguajes de Programación ILI-153
Algunas ER
(.*)blog(.*)\.com$
# dominios .com que contengan blog
pagina\s{1,8}(\d+)
# palabra pagina, multiples espacios y un numero
0x[0-9ABCDEF]*
# numero hexadecimal
linux+
# ’linux’ y muchas ’x’
ˆbegin (.*) end$
# linea que parta con ’begin ’ y termine con ’ end’
Departamento de Informática
Lenguajes de Programación ILI-153
Uso de Expresiones Regulares
Departamento de Informática
Lenguajes de Programación ILI-153
Funciones para Expresiones Regulares
Departamento de Informática
Lenguajes de Programación ILI-153
Ejemplo de uso de ER
import re
def checkMatch (myMatch):
if myMatch:
print "Si calza!"
else:
print "No calza! "
match1=re.search ("^From " , "From John Lock : " )
match2=re.compile ( "^From" ).search ( "To Jacob " )
match3=re.search ( "From" , "Desde From From" )
match4=re.match ( "From" , "Desde From From" )
checkMatch (match1);checkMatch (match2)
checkMatch (match3);checkMatch (match4 )
str1=re.split("\W+" , "4 8 15 16 23 42" )
str2,n=re.subn ( "-" , " " , "Archivo-de-prueba 2" )
print str1 , "\n" , str2 , " ( " ,n , " subs ) “
• Si calza!
• No calza!
• Si calza!
• No calza!
• ['4', '8', '15', '16', '23', '42']
• Archivo de prueba 2 ( 2 subs )
Departamento de Informática
Lenguajes de Programación ILI-153
MatchObject
• Algunos Atributos:
.re # objeto ER
.string # string original
.pos # posicion inicial de busqueda
.endpos # posicion final de busqueda
Departamento de Informática
Lenguajes de Programación ILI-153
Ejemplo
Departamento de Informática
Lenguajes de Programación ILI-153
More Information on Python
Departamento de Informática
Lenguajes de Programación ILI-153
Fin
Departamento de Informática
Universidad Técnica Federico Santa María 91