Introducción
Esta sección es un ligero desvío, pero cuando trabajas con datos, a menudo quieres producir una salida estructurada (tablas, etc.). Por ejemplo:
Nombre Acciones Precio
---------- ---------- -----------
AA 100 32,20
IBM 50 91,10
CAT 150 83,44
MSFT 200 51,23
GE 95 40,37
MSFT 50 65,10
IBM 100 70,44
Formateo de cadenas
Una forma de formatear cadenas en Python 3.6+ es con f-strings.
>>> nombre = 'IBM'
>>> acciones = 100
>>> precio = 91.1
>>> f'{nombre:>10s} {acciones:>10d} {precio:>10.2f}'
' IBM 100 91.10'
>>>
La parte {expresión:formato} es reemplazada.
Se suele utilizar con print.
print(f'{nombre:>10s} {acciones:>10d} {precio:>10.2f}')
Códigos de formato
Los códigos de formato (después del : dentro de {}) son similares a printf() de C. Los códigos comunes incluyen:
d Entero decimal
b Entero binario
x Entero hexadecimal
f Flotante como [-]m.dddddd
e Flotante como [-]m.dddddde+-xx
g Flotante, pero uso selectivo de notación científica
s Cadena
c Carácter (desde un entero)
Los modificadores comunes ajustan el ancho del campo y la precisión decimal. Esta es una lista parcial:
:>10d Entero alineado a la derecha en un campo de 10 caracteres
:<10d Entero alineado a la izquierda en un campo de 10 caracteres
:^10d Entero centrado en un campo de 10 caracteres
:0.2f Flotante con precisión de 2 dígitos
Formateo de diccionarios
Puedes usar el método format_map() para aplicar el formateo de cadenas a un diccionario de valores:
>>> s = {
'nombre': 'IBM',
'acciones': 100,
'precio': 91.1
}
>>> '{nombre:>10s} {acciones:10d} {precio:10.2f}'.format_map(s)
' IBM 100 91.10'
>>>
Utiliza los mismos códigos que f-strings pero toma los valores del diccionario suministrado.
Método format()
Existe un método format() que puede aplicar formateo a argumentos posicionales o argumentos de palabras clave.
>>> '{nombre:>10s} {acciones:10d} {precio:10.2f}'.format(nombre='IBM', acciones=100, precio=91.1)
' IBM 100 91.10'
>>> '{:>10s} {:10d} {:10.2f}'.format('IBM', 100, 91.1)
' IBM 100 91.10'
>>>
Para ser franco, format() es un poco verboso. Prefiero f-strings.
Formateo estilo C
También puedes usar el operador de formateo %.
>>> 'El valor es %d' % 3
'The value is 3'
>>> '%5d %-5d %10d' % (3,4,5)
' 3 4 5'
>>> '%0.2f' % (3.1415926,)
'3.14'
Esto requiere un solo elemento o una tupla en el lado derecho. Los códigos de formato también se basan en printf() de C.
Nota: Este es el único formateo disponible para cadenas de bytes.
>>> b'%s tiene %d mensajes' % (b'Dave', 37)
b'Dave has 37 messages'
>>> b'%b tiene %d mensajes' % (b'Dave', 37) ## %b puede usarse en lugar de %s
b'Dave has 37 messages'
>>>
Ejercicio 2.8: Cómo formatear números
Un problema común al imprimir números es especificar el número de decimales. Una forma de solucionarlo es usar f-strings. Prueba estos ejemplos:
>>> valor = 42863.1
>>> print(valor)
42863.1
>>> print(f'{valor:0.4f}')
42863.1000
>>> print(f'{valor:>16.2f}')
42863.10
>>> print(f'{valor:<16.2f}')
42863.10
>>> print(f'{valor:*>16,.2f}')
*******42,863.10
>>>
La documentación completa sobre los códigos de formateo utilizados en f-strings se puede encontrar aquí. A veces, el formateo también se realiza utilizando el operador % de cadenas.
>>> print('%0.4f' % valor)
42863.1000
>>> print('%16.2f' % valor)
42863.10
>>>
La documentación sobre los diversos códigos utilizados con % se puede encontrar aquí.
Aunque se utiliza comúnmente con print, el formateo de cadenas no está vinculado a la impresión. Si quieres guardar una cadena formateada, simplemente asígnala a una variable.
>>> f = '%0.4f' % valor
>>> f
'42863.1000'
>>>
Ejercicio 2.9: Recopilando datos
En el Ejercicio 2.7, escribiste un programa llamado report.py que calculaba la ganancia/perdida de una cartera de acciones. En este ejercicio, vas a comenzar a modificarlo para generar una tabla como esta:
Nombre Acciones Precio Cambio
---------- ---------- ---------- ----------
AA 100 9.22 -22.98
IBM 50 106.28 15.18
CAT 150 35.46 -47.98
MSFT 200 20.89 -30.34
GE 95 13.48 -26.89
MSFT 50 20.89 -44.21
IBM 100 106.28 35.84
En este informe, "Precio" es el precio actual de la acción y "Cambio" es el cambio en el precio de la acción desde el precio de compra inicial.
Para generar el informe anterior, primero querrás recopilar todos los datos mostrados en la tabla. Escribe una función make_report() que tome una lista de acciones y un diccionario de precios como entrada y devuelva una lista de tuplas que contengan las filas de la tabla anterior.
Agrega esta función a tu archivo report.py. Aquí es cómo debería funcionar si la pruebas interactiva:
>>> portfolio = read_portfolio('/home/labex/project/portfolio.csv')
>>> prices = read_prices('/home/labex/project/prices.csv')
>>> report = make_report(portfolio, prices)
>>> for r in report:
print(r)
('AA', 100, 9.22, -22.980000000000004)
('IBM', 50, 106.28, 15.180000000000007)
('CAT', 150, 35.46, -47.98)
('MSFT', 200, 20.89, -30.339999999999996)
('GE', 95, 13.48, -26.889999999999997)
...
>>>
Ejercicio 2.10: Imprimiendo una tabla formateada
Repite el bucle for del Ejercicio 2.9, pero cambia la instrucción print para formatear las tuplas.
>>> for r in report:
print('%10s %10d %10.2f %10.2f' % r)
AA 100 9.22 -22.98
IBM 50 106.28 15.18
CAT 150 35.46 -47.98
MSFT 200 20.89 -30.34
...
>>>
También puedes expandir los valores y usar f-strings. Por ejemplo:
>>> for name, shares, price, change in report:
print(f'{name:>10s} {shares:>10d} {price:>10.2f} {change:>10.2f}')
AA 100 9.22 -22.98
IBM 50 106.28 15.18
CAT 150 35.46 -47.98
MSFT 200 20.89 -30.34
...
>>>
Toma las declaraciones anteriores y agréguelas a tu programa report.py. Haz que tu programa tome la salida de la función make_report() e imprima una tabla formateada adecuadamente como se muestra.
Ejercicio 2.11: Agregando algunos encabezados
Supongamos que tienes una tupla de nombres de encabezados como esta:
encabezados = ('Nombre', 'Acciones', 'Precio', 'Cambio')
Agrega código a tu programa que tome la tupla de encabezados anterior y cree una cadena donde cada nombre de encabezado esté alineado a la derecha en un campo de 10 caracteres de ancho y cada campo esté separado por un solo espacio.
' Nombre Acciones Precio Cambio'
Escribe código que tome los encabezados y cree la cadena de separación entre los encabezados y los datos siguientes. Esta cadena es simplemente un montón de caracteres "-" debajo de cada nombre de campo. Por ejemplo:
'---------- ---------- ---------- -----------'
Cuando termines, tu programa debería producir la tabla mostrada al principio de este ejercicio.
Nombre Acciones Precio Cambio
---------- ---------- ---------- ----------
AA 100 9.22 -22.98
IBM 50 106.28 15.18
CAT 150 35.46 -47.98
MSFT 200 20.89 -30.34
GE 95 13.48 -26.89
MSFT 50 20.89 -44.21
IBM 100 106.28 35.84
Ejercicio 2.12: Desafío de formateo
¿Cómo modificarias tu código para que el precio incluya el símbolo de moneda ($) y la salida se vea así:
Nombre Acciones Precio Cambio
---------- ---------- ---------- ----------
AA 100 $9.22 -22.98
IBM 50 $106.28 15.18
CAT 150 $35.46 -47.98
MSFT 200 $20.89 -30.34
GE 95 $13.48 -26.89
MSFT 50 $20.89 -44.21
IBM 100 $106.28 35.84
Resumen
¡Felicitaciones! Has completado el laboratorio de formateo. Puedes practicar más laboratorios en LabEx para mejorar tus habilidades.