Tipos de datos en Sage ====================== .. index:: python, servidor web Introducción a Sage ::::::::::::::::::: En esta asignatura usaremos el programa **Sage** para resolver distintos problemas de matemáticas con el ordenador. El programa es libre, lo que nos permite copiarlo, modificarlo y redistribuirlo libremente. Sage consta de un buen número de librerías para ejecutar cálculos matemáticos y para generar gráficas. Para llamar a estas librerías se usa el lenguaje de programación **python**, para el que existen un buen número de recursos didácticos disponibles. Python es un lenguaje de propósito general de muy alto nivel, que permite representar conceptos abstractos de forma natural y, en general, hacer más con menos código. Buena parte de las librerías que componen Sage se pueden usar directamente desde python, sin necesidad de acarrear todo el entorno de Sage. Existen varias formas de interactuar con Sage: desde la consola, desde ciertos programas como TeXmacs o Cantor, y desde el *navegador de internet*, como estamos haciendo ahora. Para ello, Sage crea un *servidor web* que escucha las peticiones del cliente (un navegador), realiza los cálculos que le pide el cliente, y le devuelve los resultados. En esta asignatura sólo usaremos el interfaz web. .. index:: cuadro de texto Cuadros de texto ~~~~~~~~~~~~~~~~ Los cuadros de texto como éste permiten incluir comentarios en una hoja de trabajo. Si haces doble clic sobre el cuadro de texto puedes editar el contenido. Al entrar en modo de edición, aparecen botones y desplegables para cambiar algunos aspectos del estilo del texto. Lo más importante para mantener un orden en la hoja de trabajo es el primer desplegable, que permite elegir si se trata de un párrafo, un encabezado. .. index:: cuadro de código Cuadros de código ~~~~~~~~~~~~~~~~~ Los cuadros de código son rectangulares y su borde cambia de color al seleccionarlos. Dentro de los cuadros de código podemos escribir instrucciones que serán ejecutadas al pulsar el botón ``evaluate`` o teclear *mayúsculas\+Enter*. Puedes crear un nuevo cuadro de código pulsando sobre la línea azul que aparece al poner el cursor sobre un cuadro de código existente, o pulsando *control\+Enter* dentro de un cuadro de código. Puedes crear un nuevo bloque de texto pulsando sobre la misma línea azul, pero manteniendo pulsada la tecla de mayúsculas. :: sage: print 'Hola, Mundo' Hola, Mundo Si ponemos varias líneas de código, se ejecutan una tras otra de arriba a abajo. El **intérprete de instrucciones** lee las instrucciones, las interpreta y ejecuta lo que se le pide. Si al ejecutar las instrucciones se produce una *salida,* se muestra debajo del cuadro de código. :: sage: #Los comentarios en python comienzan con # sage: print 'Hola' #El comando print muestra sus argumentos en la salida del programa sage: print 'Mundo' Hola Mundo Operaciones ::::::::::: Uso como calculadora ~~~~~~~~~~~~~~~~~~~~ Podemos usar los bloques de comandos como una simple calculadora, escribiendo operaciones elementales y observando el resultado debajo del cuadro. Podemos introducir números con decimales usando el punto decimal. Los paréntesis marcan qué comando se ejecuta antes, naturalmente. :: sage: (1*2)+(3*4)+5 19 :: sage: 1*(2+3)*(4+5) 45 :: sage: #Un numero racional sage: 1/2 1/2 :: sage: #Un número de coma flotante sage: 1+1.0 2.00000000000000 .. index:: precedencia de operadores Reglas de precedencia ~~~~~~~~~~~~~~~~~~~~~ En ausencia de paréntesis, Sage decide qué operaciones se ejecutan antes y cuáles después usando unas *reglas de precedencia de operadores* bastante estándar. En la siguiente tabla de operadores, cada uno se ejecutará antes que los que están por encima. Los operadores con la misma precedencia se agrupan de izquierda a derecha, excepto la exponenciación, que agrupa de derecha a izquierda. No necesitas conocer todos estos operadores por ahora: =========================================================================================== ================================================================== operador Descripción ------------------------------------------------------------------------------------------- ------------------------------------------------------------------ or O booleano and Y booleano *not x* NO booleano in , not in , is , is not , < , <= , > , >= , <> , != , == comparaciones, comprobación de pertenencia y de tipo \| O bit a bit & Y bit a bit \+ , \- Suma y resta \* , / , / / , % multiplicación, división, el resto \+ x , \-x , ~ x positivos, negativos, NO bit a bit ^ exponenciación x [indice] , x [indice: indice] , x (arguments. ..) , x.attribute Índices, rebanadas, llamada a funciones, referencia a atributos ( expresiones ...) , [expresiones ...] , {clave: dato ...} tuplas, listas, diccionarios, evaluación de expresiones =========================================================================================== ================================================================== *Ejercicio.* Intenta predecir el resultado de ejecutar las instrucciones de debajo antes de pulsar el botón de evaluar. :: sage: 2*3^1+1*3^2 :: sage: 2*3^((1+1)*3)^2 :: sage: True or True and False :: sage: 1==2-1 :: sage: 2 < 3 and not 1 == 2 Llamadas a funciones ~~~~~~~~~~~~~~~~~~~~ Además de las operaciones aritméticas, podemos usar las muchas funciones disponibles. La forma de usarlas es escribir el nombre de la función, seguido del argumento, o argumentos, entre paréntesis, y separados por comas. :: sage: sin(pi/3) 1/2*sqrt(3) :: sage: (1 + sin(pi/3))/2 1/4*sqrt(3) + 1/2 :: sage: max(2,3) 3 .. index:: variables Variables ::::::::: Para guardar un valor dentro de una variable, usamos la sintaxis: :: variable = expresion Por ejemplo, :: numero = 1 + 2 + 3 + 4 + 5 + 6 largo = 2.56*20 angulo = pi/3 Para poder ver el valor de una variable podemos usar el comando ``print`` : :: print numero print largo, angulo print largo * sin(angulo) Una vez definida una variable, podemos hacer cálculos con su valor: :: masa = 3 aceleracion = 10 fuerza = masa\*aceleracion print fuerza :: sage: numero = 1+2+3+4+5+6 sage: largo = 2.56*20 sage: angulo = pi/3 :: sage: print numero sage: print largo, angulo sage: print largo * sin(angulo) 21 51.2000000000000 1/3*pi 25.6000000000000*sqrt(3) Nota: no confundas la asignación ( ``=`` ) con el operador de comparación de igualdad ( ``==`` ). :: sage: velocidad = 3 :: sage: velocidad == 3 True *Nota* : los nombres de las variables deben empezar por una letra o un guión bajo (_), pueden contener números, y son distintos si se usan mayúsculas o minúsculas. *Las variables* ``numero`` *y* ``Numero`` *son distintas* . :: sage: print Numero Traceback (most recent call last): ... NameError: name 'Numero' is not defined .. index:: del, colector de basura Liberar una variable ~~~~~~~~~~~~~~~~~~~~ Usando el comando ``del`` , podemos liberar una variable, y a partir de ese punto el nombre de la variable deja de estar definido. :: del variable :: sage: numero = 12 sage: print 2*numero 24 :: sage: del numero sage: print 3*numero Traceback (most recent call last): ... NameError: name 'numero' is not defined Al usar ``del`` solamente liberamos la referencia a un dato en la memoria, pero no el dato en sí. Otras referencias a ese dato siguen siendo válidas, y no se corrompen por el uso de ``del`` . Por tanto, esta instrucción no tiene nada que ver con las reservas de memoria en lenguajes de bajo nivel como C, que reservan y liberan espacio en la memoria. Para liberar la memoria no usada, Python usa un `colector de basura `_ . Este colector de basura identifica los objetos a los que no apunta ninguna referencia y los libera. :: sage: lista1 = [1,2,3,4] sage: lista2 = lista1 sage: del lista1 sage: print lista2 [1, 2, 3, 4] .. index:: tipo de dato, booleano, número entero, número racional, coma flotante, expresión simbólica, tipado dinámico Tipos de datos :::::::::::::: En las variables podemos almacenar cualquier tipo de datos que resulte de evaluar una expresión. Más adelante en el curso guardaremos en las variables matrices, gráficas e incluso objetos abstractos como espacios vectoriales. Por ahora hemos usado los siguientes tipos de datos: - Booleanos: sólo toman el valor ``True`` o ``False`` . - Enteros: cualquier número entero, positivo o negativo, de longitud arbitraria. Ej.: 1, 10, \-30 - Racionales Ej.: 1/2, \-3/4 - Números de coma flotante: un número con unos cuantos dígitos decimales y un exponente, que representa un número real de forma aproximada. Ej.: 1.25, \-1.5e6 - Expresiones simbólicas: expresiones matemáticas que representan números reales de forma exacta. Ej.: pi/4 (:math:`\pi/4`), (1+sqrt(2))/2 (:math:`\frac{1+\sqrt{2}}{2}`) Las variables pueden almacenar referencias a datos de cualquier tipo: python usa **tipado dinámico** . Sin embargo, todos los datos tienen necesariamente un tipo :: sage: 2 >=3 False :: sage: var1=2 sage: var2=3 sage: #La variable es_menor almacena un booleano sage: es_menor = var1 < var2 :: sage: print es_menor True :: sage: factorial(1000) 402387260077093773543702433923003985719374864210714632543799910429938512398629020592044208486969404800479988610197196058631666872994808558901323829669944590997424504087073759918823627727188732519779505950995276120874975462497043601418278094646496291056393887437886487337119181045825783647849977012476632889835955735432513185323958463075557409114262417474349347553428646576611667797396668820291207379143853719588249808126867838374559731746136085379534524221586593201928090878297308431392844403281231558611036976801357304216168747609675871348312025478589320767169132448426236131412508780208000261683151027341827977704784635868170164365024153691398281264810213092761244896359928705114964975419909342221566832572080821333186116811553615836546984046708975602900950537616475847728421889679646244945160765353408198901385442487984959953319101723355556602139450399736280750137837615307127761926849034352625200015888535147331611702103968175921510907788019393178114194545257223865541461062892187960223838971476088506276862967146674697562911234082439208160153780889893964518263243671616762179168909779911903754031274622289988005195444414282012187361745992642956581746628302955570299024324153181617210465832036786906117260158783520751516284225540265170483304226143974286933061690897968482590125458327168226458066526769958652682272807075781391858178889652208164348344825993266043367660176999612831860788386150279465955131156552036093988180612138558600301435694527224206344631797460594682573103790084024432438465657245014402821885252470935190620929023136493273497565513958720559654228749774011413346962715422845862377387538230483865688976461927383814900140767310446640259899490222221765904339901886018566526485061799702356193897017860040811889729918311021171229845901641921068884387121855646124960798722908519296819372388642614839657382291123125024186649353143970137428531926649875337218940694281434118520158014123344828015051399694290153483077644569099073152433278288269864602789864321139083506217095002597389863554277196742822248757586765752344220207573630569498825087968928162753848863396909959826280956121450994871701244516461260379029309120889086942028510640182154399457156805941872748998094254742173582401063677404595741785160829230135358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 :: sage: numero = factorial(1000) :: sage: numero/factorial(1001) 1/1001 Números de coma flotante y expresiones simbólicas ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Al usar el ordenador para hacer matemáticas es importante saber si los datos del ordenador representan los objetos matemáticos de forma exacta. Es imposible almacenar en un ordenador con una cantidad finita de memoria todas las cifras decimales del número **pi** . Una alternativa es almacenar sólo unas cuantas cifras, y cometer por tanto un pequeño error. Para la mayoría de las aplicaciones es más que suficiente usar 10 o 20 *cifras decimales significativas* . Con esto queremos decir que al escribir el número en notación exponencial, descartamos todas las cifras a partir de la número 10 o 20. Por ejemplo, el número :math:`1/\pi` con diez dígitos significativos: .. MATH:: 3.183098861 \cdot 10^{-1} y la constante de Planck con seis dígitos significativos: .. MATH:: 6,62606 \cdot 10^{-34} Al hacer operaciones con números que contienen errores, los errores se suman y multiplican, y pueden acabar estropeando un cálculo. Otra alternativa es usar una variable simbólica, y usar las reglas aritméticas sin hacer cálculos con decimales, exactamente igual que os contaban en el instituto: .. MATH:: \frac{\sqrt[3]{2}\cdot 3^2}{\frac{3 \cdot 4}{\sqrt[3]{4}}}= 2^{1/3-2+2/3}3^{2-1}=2^{-1}3=3/2 Al estar orientado preferentemente al público matemático, Sage prefiere usar expresiones simbólicas exactas antes que aproximaciones numéricas. Como vimos antes, para obtener una representación decimal de una expresión simbólica, podemos usar el comando ``n()`` (n de numérico). :: sage: 1/pi 1/pi :: sage: n(1/pi) 0.318309886183791 :: sage: a = sqrt(2) :: sage: n(a) 1.41421356237310 .. index:: método Métodos específicos de cada tipo de datos ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Cada tipo de datos tiene sus propios métodos: funciones que se aplican sólo a datos de este tipo y que se llaman escribiendo primero la variable que contiene el dato, después un punto (``.``), y después el método: :: variable.metodo() Por ejemplo, podemos calcular la factorización de un número entero, pero no de un número real, o podríamos intentar simplificar una expresión simbólica, pero no podemos simplificar un número entero. :: sage: a = 12 sage: print a.factor() #Factorizacion del entero 'a' 2^2 * 3 :: sage: b = 4.7 sage: print b.integer_part() #Parte entera del numero real 'b' 4 :: sage: c = (3*sqrt(6)+sqrt(2))/sqrt(8) sage: print c.full_simplify() #Intenta simplificar la expresion 'c' 3/2*sqrt(3) + 1/2 :: sage: print b.factor() Traceback (most recent call last): ... AttributeError: 'sage.rings.real_mpfr.RealLiteral' object has no attribute 'factor' :: sage: print a.full_simplify() Traceback (most recent call last): ... AttributeError: 'sage.rings.integer.Integer' object has no attribute 'full_simplify' [Tabulador] ~~~~~~~~~~~ El tabulador permite conocer la lista completa de métodos aplicables a un dato: - Escribe el nombre de una variable seguido de un punto, y pulsa [Tabulador] para ver todos los métodos específicos al tipo de datos de la variable. - Escribe el nombre de una variable seguido de un punto y algunos caracteres, y pulsa [Tabulador] para ver sólo los métodos que comienzan con esos caracteres. :: sage: a. :: sage: b. .. index:: Integer, int, RealNumber, float Números de Sage y de python ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Aunque Sage utiliza el lenguaje python, los tipos numéricos en Sage no corresponden exactamente a los tipos numéricos de python, ya que los números en Sage tienen más funcionalidad. Por ejemplo, los enteros de Sage permiten calcular su lista de divisores, su expresión binaria, etcétera. Por defecto, los tipos numéricos son enteros, racionales y números reales de Sage, no de python. :: sage: a = 12 #Entero de SAGE sage: #a = Integer(12) #Otra forma equivalente de definir un entero de SAGE sage: b = int(12) #Entero de 32 bits de python :: sage: print a.divisors(), a.digits(base = 2) [1, 2, 3, 4, 6, 12] [0, 0, 1, 1] :: sage: print b.divisors() Traceback (most recent call last): ... AttributeError: 'int' object has no attribute 'divisors' :: sage: c = 1.2 #Real de SAGE (de precision limitada) sage: c = RealNumber(1.2) #Otra forma equivalente de definir un real de SAGE sage: d = float(1.2) #Real de 64 bits de python :: sage: d.exact_rational() Traceback (most recent call last): ... AttributeError: 'float' object has no attribute 'exact_rational' :: sage: c.exact_rational() 5404319552844595/4503599627370496 Secuencias de datos ::::::::::::::::::: .. index:: cadena de caracteres Cadenas de caracteres ~~~~~~~~~~~~~~~~~~~~~ Las **cadenas de caracteres** son *secuencias de caracteres* (letras, números, puntuación...) que se manipulan de forma conjunta y se pueden almacenar en una variable. Para introducir cadenas de caracteres en el código, *separamos el texto entre comillas* simples ('cadena'), comillas dobles ("cadena"), o triples comillas simples para cadenas más largas ('''cadena larga'''). :: sage: print 'Hola' Hola Se pueden usar algunas **operaciones** con cadenas de caracteres: - La suma (\+) de cadenas devuelve una cadena resultado de poner la primera cadena después de la segunda - El producto (\*) de una cadena por un número natural repite la cadena tantas veces como indica el número. :: sage: print 'Hola' + 'tu' sage: print 'Hola'*2 Holatu HolaHola :: sage: cadena1 = 'Hola' sage: cadena2 = ' a todas' #presta atencion al espacio en blanco al principio sage: cadena3 = cadena1 + cadena2 sage: cadena4 = cadena1 + '.'*3 + cadena2 :: sage: print cadena1 sage: print cadena2 sage: print cadena3 sage: print cadena4 Hola a todas Hola a todas Hola... a todas Podemos obtener la longitud de una cadena con el comando ``len`` . :: sage: print len(cadena1), len(cadena2), len(cadena3), len(cadena4) 4 8 12 15 .. index:: subcadena, rango Extraer caracteres y subcadenas ------------------------------- Para acceder al carácter que ocupa la posición j\-ésima en una cadena de caracteres, usamos la notación :: cadena[j] ¡Ojo! Se empieza a contar desde el número 0, el índice del primer carácter. El índice del último carácter es L\-1, donde L es la longitud de la cadena. También podemos acceder a una subcadena (o rango), desde el índice j (inclusive) hasta el k (exclusive), con la notación :: cadena[j:k] Por ejemplo: :: cadena = 'Si miras al abismo...' print cadena[0], cadena[1], cadena[2], cadena[3] print cadena[3:8] :: sage: cadena = 'Si miras al abismo...' sage: print cadena[0], cadena[1], cadena[2], cadena[3] sage: print cadena[3:10] S i m miras a .. index:: tupla Tuplas ~~~~~~ Las tuplas contienen unos cuantos elementos no necesariamente del mismo tipo. Basta con poner las variables entre paréntesis separadas por comas para formar una tupla. tupla = (elemento1, elemento2) Una vez creada, podemos acceder a sus elementos usando corchetes, igual que hacíamos con las cadenas de caracteres. :: sage: frutas = ('pera','manzana','naranja') sage: primos = (2,3,5,7,11,13) sage: print frutas[0] sage: print primos[0:3] sage: primo = primos[2] sage: fruta = frutas[2] sage: print primo, fruta pera (2, 3, 5) 5 naranja Las operaciones \+ y \* actúan sobre tuplas de la misma forma que sobre cadenas de caracteres. :: sage: (1,2,'a') + (3,4) (1, 2, 'a', 3, 4) :: sage: (1, 'a')*3 (1, 'a', 1, 'a', 1, 'a') Si queremos guardar cada elemento de la tupla en una variable distinta, podemos usar el acceso a los elementos usando los corchetes: :: frutas = ('pera','manzana','naranja') a=frutas[0] b=frutas[1] c=frutas[2] o también podemos *desempaquetar* la tupla con una sóla instrucción: :: a,b,c = frutas lo que, al igual que el código anterior, guarda en la variable ``a`` el primer elemento de la tupla, en la variable ``b`` el segundo y en la variable ``c`` el tercero. Si intentamos desempaquetar una tupla de N elementos con más, o con menos de N variables, obtendremos un error. :: sage: frutas = ('pera','manzana','naranja') sage: a,b,c = frutas :: sage: print c + ',' + b + ',' + a naranja,manzana,pera :: sage: a,b = frutas Traceback (most recent call last): ... ValueError: too many values to unpack :: sage: a,b,c,d = frutas Traceback (most recent call last): ... ValueError: need more than 3 values to unpack Las tuplas son **immutables** , es decir, que no se puede quitar ni añadir elementos a una tupla una vez ha sido creada, ni siquiera sustituir un elemento por otro. .. index:: lista, range, srange Listas ~~~~~~ Las listas se usan de modo similar a las tuplas, pero se pueden quitar y añadir elementos en cualquier momento. Decimos que son *contenedores dinámicos de datos* . La sintaxis para crear listas es igual a la de las tuplas, pero usando corchetes en vez de paréntesis. Una vez creadas, podemos acceder a sus elementos usando los corchetes, pero además podemos asignar nuevos valores a posiciones arbitrarias de la lista. :: sage: lista_frutas = ['pera','manzana','naranja'] sage: print lista_frutas sage: lista_frutas[1] = 'fresa' sage: print lista_frutas ['pera', 'manzana', 'naranja'] ['pera', 'fresa', 'naranja'] También podemos eliminar elementos de la lista con el comando ``del`` y añadir elementos al final de la lista con el comando ``append`` . :: sage: print lista_frutas[1] fresa :: sage: lista_frutas = ['pera','manzana','naranja'] sage: print lista_frutas sage: lista_frutas.append('fresa') sage: print lista_frutas sage: del lista_frutas[1] sage: print lista_frutas ['pera', 'manzana', 'naranja'] ['pera', 'manzana', 'naranja', 'fresa'] ['pera', 'naranja', 'fresa'] :: sage: print lista_frutas sage: lista_frutas.insert(2,'otra fruta') sage: print lista_frutas ['pera', 'naranja', 'fresa'] ['pera', 'naranja', 'otra fruta', 'fresa'] El comando ``srange`` permite crear listas de números de SAGE (en python se usa la función ``range`` , que devuelve enteros de python): - ``srange(j,k,d)`` : devuelve los números entre ``j`` (inclusive) y ``k`` (exclusive), pero contando de ``d`` en ``d`` elementos. A pesar de que el uso más extendido es con números enteros, los números ``j``, ``k`` y ``d`` pueden ser enteros o no. Abreviaturas: - ``srange(k)`` : devuelve ``srange(0,k,1)``. Si, en particular, ``k`` es un natural, devuelve los naturales entre ``0`` (inclusive) y ``k`` (exclusive); y si ``k`` es negativo, devuelve una lista vacía. - ``srange(j,k)`` : devuelve la lista ``srange(j,k,1)``. Si, en particular, ``j`` y ``k`` son enteros, devuelve los enteros entre ``j`` (inclusive) hasta el anterior a ``k``. :: sage: print srange(10) sage: print srange(10,20) sage: print srange(10,20,2) sage: print srange(10,20,1.5) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [10, 11, 12, 13, 14, 15, 16, 17, 18, 19] [10, 12, 14, 16, 18] [10.0000000000000, 11.5000000000000, 13.0000000000000, 14.5000000000000, 16.0000000000000, 17.5000000000000, 19.0000000000000] .. index:: in Pertenencia ~~~~~~~~~~~ En cualquiera de las estructuras anteriores, podemos comprobar si un elemento está en la lista usando el operador ``in`` , que devuelve ``True`` o ``False`` según el elemento pertenezca o no al contenedor de datos. :: sage: 10 in [1,2,3,4] False :: sage: 'n' in 'En un lugar de la Mancha' True :: sage: 133 in srange(0,1000,7) True .. index:: join Conversiones entre secuencias ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Las conversiones tupla \-> lista, cadena \-> lista, lista\->tupla y cadena\->tupla son triviales, usando las funciones ``tuple`` y ``list`` : :: sage: tupla_0 = (1,2,3) sage: lista_0 = ['a','b','c'] sage: cadena_0 = 'qwerty' :: sage: tuple(cadena_0) ('q', 'w', 'e', 'r', 't', 'y') :: sage: list(tupla_0) [1, 2, 3] Sin embargo, aunque existe la función ``str`` , el resultado no es el que deseamos normalmente: :: sage: str(lista_0) "['a', 'b', 'c']" :: sage: str(tupla_0) '(1, 2, 3)' La función ``str`` intenta dar una representación textual *lo más fidedigna posible* del objeto que pasamos como argumento. La situación siguiente es más usual: tenemos una lista de cadenas de caracteres, y queremos unir esas cadenas, opcionalmente usando otra cadena como separador. Para ello usamos el método ``join`` , que tienen todas las cadenas de caracteres. :: sage: ', '.join(lista_0) 'a, b, c' :: sage: ''.join(lista_0) 'abc' Mostrar información por pantalla :::::::::::::::::::::::::::::::::: Para poder ver en pantalla los valores de las variables, hemos usado el comando ``print`` . :: print var1 print var1, var2, ... De esta forma podemos mostrar los valores de las variables. También podemos escribir texto que contenga los valores de estas variables usando el operador ``%`` y los códigos de formato. Para usarlo, escribimos una cadena que contiene códigos de formato seguida del operador ``%`` y a continuación la variable que queremos sustituir, o una tupla de variables si hay más de una. :: lados = 8 print 'El número de lados es %d'%lados area = 17.5 print 'El área es %f'%area print 'El área del polígono de %d lados es %f'%(lados, area) nombre = 'Juan' print '%s vino ayer a cenar'%nombre Los códigos más usuales son: - ``%d`` : número entero - ``%f`` : número de coma flotante, con decimales - ``%.3f`` : número de coma flotante, con 3 decimales exactamente - ``%s`` : cadena de caracteres (o cualquier dato que no sea entero ni de coma flotante) :: sage: lados = 8 sage: print 'El número de lados es %d'%lados sage: area = 17.5 sage: print 'El área es %.3f'%area sage: print 'El área del polígono de %d lados es %f'%(lados, area) sage: nombre = 'Juan' sage: print '%s vino ayer a cenar'%nombre El número de lados es 8 El área es 17.500 El área del polígono de 8 lados es 17.500000 Juan vino ayer a cenar