Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download

Jupyter notebook sage2.ipynb

Project: TDC
Views: 507
Kernel: SageMath (stable)

Algo de programación

En esta hora, vamos a ver de forma muy breve algunas nociones de programación en SAGE/Python. En particular, veremos:

  • Listas y tuplas

  • Verdad y mentira

  • Comprensiones de listas (list comprehensions)

  • Definición de funciones

  • Instrucciones for / while / if

## Listas y tuplas

En Python/SAGEMATH, las listas se representan entre corchetes cuadrados [...]. La lista con cero elementos se representa como [].

DEFINICION DE LISTAS s[3]=78 #es asignar el valor 78 en la posicion 3 (cambiarle el nombre) s[-1]#con el signo menos empieza a contar la lista al reves range (principio,final,salto) = l[principio:final:salto] #si faltan cosas sage usa valores por defecto l[::-1] #darle la vuelta a una lista [1..n] (a,b,c) #Las tuplas, a todos los efectos, son como listas que no se pueden modificar. s.pop(n) #es el enesimo elemnto de la lista s del l[n] #elimina el elemnto ensimo de l l.append(1) #añade el elemnto a la lista ---------------------------------------------------------------------------------------------------------------- COMPRESION [f(x) for x in (lista) if condicion ] ------------------------------------------------------------------------------------------------------------------ ==,!=,>=,<= ---------------------------------------------------------------------------------------------------------------------- DEFINICIONES def nombre (v): las cosas que quiero que haga la def return blabla def dollar_a_euro(dollars): euros=0.891019415*dollars return euros ----------------------------------------------------------------------------------------------------------------------- if/for/while if condición: instrucciones elif condición: instrucciones elif otra_condición: más instrucciones else: nada de lo anterior for variable(s) en lista(s): haz cosas while condición es cierta: haz cosas.
File "<ipython-input-11-77796e818169>", line 1 DEFINICION DE LISTAS ^ SyntaxError: invalid syntax
l_1 = [0,1,2,3,4] l_1
[0, 1, 2, 3, 4]

Para una lista l, sus elementos se llaman l[i], contando a partir de cero:

l_1[0], l_1[3]
(0, 3)

Y se les puede asignar una valor:

l_1[4] = 'holita' l_1
[0, 1, 2, 42, 'holita']

También se puede empezar a contar desde el final, con índide -1:

l_1[-1]
'holita'

Y se puede extraer parte de una lista con l[principio:final:salto]:

l=range(20) l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
l[2:12]
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

Si no se pone principio o final, Python emplea unos valores por defecto:

l[2:]
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
l[:10:2]
[0, 2, 4, 6, 8]
l[-2::-1]
[18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

Por ejemplo, la forma más sencilla de darle la vuelta a la lista es:

l[::-1]
[19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

La función range(m,n,s) da la lista de enteros empezando por m, acabando justo antes de n, y aumentanto de s en s.

range(6)
[0, 1, 2, 3, 4, 5]
range(2,21,2)
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

La longitud de una lista se mide con len; y es un error extraer un elemento más allá del final (o del principio) de una lista:

l = range(0,20,2) l
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
len(l)
10
l[9]
18
l[10]
--------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-15-fb7291eca45e> in <module>() ----> 1 l[Integer(10)] IndexError: list index out of range
l[-10]
0
l[-11]
--------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-18-8115ce3de616> in <module>() ----> 1 l[-Integer(11)] IndexError: list index out of range

Las listas tienen una aritmética propia:

l1 = [55, 23, 11, -5, 6] l2 = [0,0,1,0]
l1+l2
[55, 23, 11, -5, 6, 0, 0, 1, 0]
3*l2
[0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0]

SAGE tiene la siguiente extensión:

[1..7] # SAGEMATH, no Python
[1, 2, 3, 4, 5, 6, 7]

Una precisión: en Python, las variables funcionan como etiquetas que apuntan a un objeto. En el caso de listas, esto puede ser importante:

l1 = [11, 35, 18, 'a', 'b', 'c', 'd']
l2 = l1

Ahora, l2y l1 apuntan a la misma lista; si cambio una, cambio la otra:

l2[1] = 'X' l2
[11, 'X', 18, 'a', 'b', 'c', 'd']
l1
[11, 'X', 18, 'a', 'b', 'c', 'd']

Para hacer una copia distinta de una lista, se hace así:

l3 = copy(l2) l3
[11, 'X', 18, 'a', 'b', 'c', 'd']

Ahora l3 es realmente distinta:

l3[0] = 150
l3
[150, 'X', 18, 'a', 'b', 'c', 'd']
l2
[11, 'X', 18, 'a', 'b', 'c', 'd']

Las tuplas, a todos los efectos, son como listas que no se pueden modificar.

l2 = tuple(l2) l4 = (1,2,3,'p') l2
(11, 'X', 18, 'a', 'b', 'c', 'd')
l4
(1, 2, 3, 'p')
l2[1] = '2'
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-33-3233919e4a2f> in <module>() ----> 1 l2[Integer(1)] = '2' TypeError: 'tuple' object does not support item assignment

Otras funciones: borrar un elemento de una lista, añadir elementos a una lista

l = []
l.append(1)
l
[1]
s = l + [1..5]
s
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 1, 2, 3, 4, 5]
elemento = s.pop(3)
elemento
12
s
[0, 2, 4, 12, 14, 16, 18, 1, 2, 3, 4, 5]
del s[4]
s
[1, 1, 2, 4]

## List comprehensions

En matemáticas usamos muchas veces construcciones del tipo: {m3Z tales que 20m25}. \{ m^3 \in \mathbb{Z} \text{ tales que } 20 \leq m \leq 25 \}. Las “comprensiones de listas” ayudan a escribir estas listas de forma natural:

s = [ m^3 for m in [20..25]] s
[8000, 9261, 10648, 12167, 13824, 15625]

Otro ejemplo: si queremos los primos entre 252^5 y 262^6,

primos = [n for n in [2^10..2^11] if n.is_prime()] print primos
[1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039]

Verdades y mentiras

En Python/SAGE, existen los valores True y False, y las comprobaciones habituales:

s, l
([1, 1, 2, 4], [1])
s == l
False
s != l
True
10 >= 9
True
True and True or False
True

Las listas vacías se interpretan como False, el resto como True:

bool([])
False
bool([0])
True
bool([1,2,3,4,5,6])
True

Definición de funciones

# Esencialmente: # def función(argumentos): # ____ instrucciones; # incrementando el sangrado # ____ hasta "return algo" # # Ejemplo: función que calcula la conversión de $ a € (a día 02-03-2015) def dollar_a_euro(dollars): euros=0.891019415*dollars return euros dollar_a_euro(1000)
891.019415000000
# Un poco más sofisticado: argumentos por defecto: def dollar_a_euro(dollars, cambio=0.891019415): return cambio*dollars
dollar_a_euro(1000)
891.019415000000
dollar_a_euro(1000, cambio=1.01)
1010.00000000000

## if/for/while

Sobre esto no hay mucho que decir, salvo la sintaxis:

if condición: instrucciones elif condición: instrucciones elif otra_condición: más instrucciones else: nada de lo anterior for variable(s) en lista(s): haz cosas while condición es cierta: haz cosas.

Veamos ejemplos:

for a in [1, 'a' ]: print a
1 a
for (i,j) in [[1,'a'], [2,'b']]: print i, j
1 a 2 b
[(i,j) for (i,j) in [[1,'a'], [2,'b']]]
[(1, 'a'), (2, 'b')]
# Suma de los n primeros números: def suma_n(n): s=0 # s es una variable LOCAL for i in [1..n]: s = s+i return s suma_n(100)
5050
# Función fibonacci: def fib(n): if n<2: return n else: return fib(n-1)+fib(n-2)
[(k, fib(k)) for k in range(0,10)]
[(0, 0), (1, 1), (2, 1), (3, 2), (4, 3), (5, 5), (6, 8), (7, 13), (8, 21), (9, 34)]
# while: test de primalidad: def factor_o_primo(n): i=2 while i<n: if n % i ==0: # n % i = resto de la división de n por i. return i i+=1 # o i=i+1 return 'primo'
factor_o_primo(2)
'primo'
factor_o_primo(3)
'primo'
factor_o_primo(14876875)
5

Algunas funciones de SAGE devuelven listas:

l = xgcd(11, 35)
l
(1, 16, -5)
1 == 16*11-5*35
True

Pero también podemos hacer:

d, alfa, beta = xgcd(11, 35)
d
1
alfa
16
beta
-5

Ejercicios

Ejercicio. Escribe una función que imprima las tablas de multiplicar, hasta 10, algo así:

tabla_del(6) 6 x 0 = 0 6 x 1 = 6 6 x 2 = 12 6 x 3 = 18 6 x 4 = 24 6 x 5 = 30 6 x 6 = 36 6 x 7 = 42 6 x 8 = 48 6 x 9 = 54 6 x 10 = 60
def tablademult (n): for i in [0,..,10]: print n,'x',i,'=',n*i
tablademult(8)

Ejercicio. Escribe un programa que calcule los siguientes 20 años bisiestos. (Hay que saber bien la definición de bisiesto.)

def es_bisiesto(n): return n%4==0 and (n%100!=0 or n%400==0)
def bisiestos (n): if es_bisiesto (n) : return range (n,n+20*4,4) return bisiestos(n+1)
bisiestos(2017)
bisiestos (2016)

Ejercicio. Escribe un programa que calcule la suma de los elementos de una lista

def suma (s1): s=0 for i in (s1): s=s+i return s
suma ([1,2,3])
6
del?
Object `del` not found.
len ([])
0

Ejercicio. Con una compresión de listas, calcula la suma de todos los múltiplos de 33 y 55 que no son múltiplos de 4545 menores que 50000.

mod(3,1)==0
True
filter(lambda x:(i%3==0)and(i%5==0)and(i%45!=0),M)
multiplo = [i for i in [1..50000] if (i%3==0)and(i%5==0)and(i%45!=0)] print multiplo
[1..50000]
mod(3456,15)
6
filter(lambda x: (x.is_cyclic()),S)

Ejercicio. Una terna pitagórica es una conjunto de tres entero positivos (a,b,c)(a,b,c) tal que a2+b2=c2a^2+b^2=c^2. Por ejemplo, las ternas pitagóricas cuyas componentes son menores que 1010 son: [(3,4,5),(4,3,5),(6,8,10),(8,6,10)]. [(3,4,5),(4,3,5),(6,8,10),(8,6,10)].

Construye el conjunto de ternas pitagóricas cuyas componentes son menores que 5050 usando comprensiones de listas (con condiciones).

(2,3,4)
(2, 3, 4)
Terna50=[(a,b,c) for a in [1..50] for b in [1..50] for c in [1..50] if a^2+b^2==c^2]
Terna50

Ejercicio. Escribe un programa que imprima todas las particiones (descendentes) de 10: 9+1, ..., etc. (Difícil.)8+2,8+1+1,

Ejercicio. Lee con detenimiento, paciencia e interés el tutorial de programación de SAGE.