Lección 0.3.2 · 45 min

Cadenas, f-strings y formato de números y fechas

Un ticker, una fecha y una línea de un informe son texto. La lección enseña a trocear símbolos como «ES=F» o «EURUSD», a dar formato a precios, porcentajes y P&L con f-strings y a escribir y leer fechas sin ambigüedad.

Fig. — Anatomía de una especificación de formato: el P&L con signo, miles y dos decimales en 12 caracteres
02/06
Módulo
0.3 · Fundamentos del lenguaje
Duración
45 min
Lecciones del nivel 0
  1. 0.1 · Bienvenida y expectativas

    1. 0.1.1 Trading sistemático, algorítmico y cuantitativo frente al discrecional
    2. 0.1.2 Expectativas realistas: costes, tiempo y riesgo de pérdida
    3. 0.1.3 Estructura del curso, tests de entrada, repositorio personal y aprendizaje con IA
  2. 0.2 · Entorno de trabajo moderno

    1. 0.2.1 Instalación de Python con uv: versiones y ciclo de soporte
    2. 0.2.2 Entornos virtuales y dependencias: uv init, uv add, pyproject.toml y lockfiles
    3. 0.2.3 Editores (VS Code, Cursor, PyCharm) y notebooks (Jupyter, JupyterLab, marimo)
    4. 0.2.4 Terminal básica, rutas, variables de entorno y ficheros .env
    5. 0.2.5 Git y GitHub: commits, ramas, pull requests y .gitignore
    6. 0.2.6 Introducción a los asistentes de código con IA: prompts, revisión y tests
  3. 0.3 · Fundamentos del lenguaje

    1. 0.3.1 Variables, tipos y operadores; coma flotante y decimal para precios y ticks
    2. 0.3.2 Cadenas, f-strings y formato de números y fechas
    3. 0.3.3 Listas, tuplas, diccionarios, conjuntos y comprensiones
    4. 0.3.4 Control de flujo: if, elif, else, for, while y match-case
    5. 0.3.5 Funciones: argumentos, *args y **kwargs, lambdas y ámbito
    6. 0.3.6 Excepciones; módulos y paquetes, con los imports perezosos de Python 3.15
  4. 0.4 · Python intermedio

    1. 0.4.1 Programación orientada a objetos: clases, herencia, composición y dataclasses
    2. 0.4.2 Tipado: type hints, mypy o ty y Pydantic para configuraciones
    3. 0.4.3 Iteradores, generadores, decoradores y context managers
    4. 0.4.4 Ficheros (CSV, JSON, YAML, TOML) y fechas con zonas horarias
    5. 0.4.5 Logging profesional y testing con pytest
    6. 0.4.6 Concurrencia: threading, multiprocessing, asyncio y free-threading
  5. 0.5 · Computación numérica y datos

    1. 0.5.1 NumPy 2: arrays, broadcasting, vectorización, álgebra lineal y generadores aleatorios
    2. 0.5.2 pandas 3.0: Series, DataFrame, índices temporales, Copy-on-Write, tipo str y pd.col()
    3. 0.5.3 Selección, filtrado, groupby, merge, pivot, resample y ventanas móviles
    4. 0.5.4 Polars: API lazy frente a eager, expresiones, rendimiento y cuándo elegirlo frente a pandas
    5. 0.5.5 DuckDB y SQL esencial: SELECT, JOIN, GROUP BY y funciones de ventana sobre Parquet
  6. 0.6 · Visualización

    1. 0.6.1 Matplotlib orientado a objetos, Seaborn y Plotly: gráficos de precios, drawdown y velas
    2. 0.6.2 Dashboards rápidos con Streamlit: un panel de seguimiento en un solo script
  7. 0.7 · Matemáticas y estadística mínimas

    1. 0.7.1 Rentabilidades simples y logarítmicas, interés compuesto y estadística descriptiva
    2. 0.7.2 Probabilidad y distribuciones, correlación frente a causalidad y regresión simple
    3. 0.7.3 Álgebra lineal intuitiva: vectores y matrices como preparación para carteras

Cadenas: el texto de un programa de trading

Tickers, nombres de mercado, lados de una orden, líneas de un fichero y mensajes de un informe: todo eso es texto, y en Python el texto es el tipo str (lección 0.3.1). Una cadena se escribe entre comillas simples o dobles, que son equivalentes; las triples ("""…""") permiten varias líneas.

Una cadena es una secuencia de caracteres en orden, y cada carácter tiene una posición, su índice, que empieza en 0. Con corchetes se lee un carácter (s[0]) o un trozo (s[inicio:fin], el corte, que incluye inicio y excluye fin). Los índices negativos cuentan desde el final: s[-1] es el último carácter.

IN [01]python
par = "EURUSD"
print(len(par), par[0], par[-1])
print(par[:3], par[3:])
print(par[::-1])
print("USD" in par, "JPY" in par)
OUT [01]Índices y cortes en un par de divisas
6 E D
EUR USD
DSURUE
True False

len da el número de caracteres. [:3] toma los tres primeros (de 0 a 2) y [3:], del índice 3 al final: las dos divisas del par. Un tercer número en el corte es el paso; [::-1] recorre la cadena al revés. El operador in pregunta si un trozo aparece dentro de la cadena y devuelve un bool.

Las cadenas son inmutables: no se puede cambiar un carácter (par[0] = "G" da un error). Todas las operaciones que parecen modificarlas devuelven una cadena nueva. Con + se concatenan y con * se repiten:

IN [02]python
base, cotizada = "EUR", "USD"
simbolo = base + "/" + cotizada
print(simbolo)
print("-" * 20)
OUT [02]Concatenar y repetir
EUR/USD
--------------------

La primera línea asigna dos variables a la vez; la forma se explica con las tuplas en la lección 0.3.3.

Métodos para limpiar y trocear símbolos

Los símbolos llegan escritos de muchas formas: en minúsculas desde un formulario, con espacios desde una hoja de cálculo, con sufijos que cada proveedor de datos usa a su manera. En Yahoo Finance, por ejemplo, ES=F es el futuro E-mini S&P 500 (el contrato más cercano a vencimiento) y EURUSD=X, el cruce euro-dólar; en otros proveedores el mismo par es EURUSD o EUR/USD, y una criptomoneda puede ser BTC-USD o BTCUSDT1Nota 1 · Yahoo Finance: ES=F y EURUSD=X. Cada proveedor documenta sus símbolos; al cambiar de proveedor, hay que traducirlos..

Los métodos de las cadenas son funciones que se llaman con un punto detrás del valor (simbolo.upper()). Los que más se usan para este trabajo:

MétodoQué haceEjemploResultado
strip()Quita espacios al principio y al final" es=f ".strip()"es=f"
upper() / lower()Mayúsculas / minúsculas"es=f".upper()"ES=F"
partition(sep)Parte en tres por la primera aparición de sep"ES=F".partition("=")("ES", "=", "F")
split(sep)Parte por todas las apariciones de sep"BTC-USD".split("-")["BTC", "USD"]
replace(a, b)Cambia a por b"EUR/USD".replace("/", "")"EURUSD"
startswith / endswith¿Empieza o termina por…?"ES=F".endswith("=F")True
removesuffix / removeprefixQuita un sufijo o prefijo si está"EURUSD=X".removesuffix("=X")"EURUSD"

Con ellos, un símbolo mal escrito se normaliza en una línea, y un símbolo bien escrito se descompone en sus partes:

IN [03]python
entrada = "  es=f \n"
simbolo = entrada.strip().upper()
print(repr(entrada), "->", repr(simbolo))

raiz, sep, tipo = simbolo.partition("=")
print(raiz, tipo, simbolo.endswith("=F"))

base, cotizada = "BTC-USD".split("-")
print(base, cotizada)

print("EURUSD=X".removesuffix("=X"))
print("EUR/USD".replace("/", ""))
OUT [03]Normalizar y trocear símbolos
'  es=f \n' -> 'ES=F'
ES F True
BTC USD
EURUSD
EURUSD

repr muestra la cadena tal como es, con comillas y con el salto de línea escrito como \n; print la mostraría sin ellos y los espacios pasarían desapercibidos. Es la forma de ver qué hay de verdad dentro de un texto que no se comporta como se espera.

partition siempre devuelve tres trozos, aunque no encuentre el separador (los dos últimos quedan vacíos); split devuelve tantos como haya, y asignarlos a dos variables solo funciona si son exactamente dos. Por eso, cuando un símbolo tiene una única marca (= en Yahoo), partition es la opción robusta.

El troceado sigue el mismo esquema para cualquier proveedor: limpiar, comprobar el formato y separar las partes.

sínoTexto recibidostrip y upper¿Contiene =?partitionCorte por posición
Fuente Mermaid
flowchart TB
  E[Texto recibido] --> N[strip y upper]
  N --> F{¿Contiene =?}
  F -- sí --> P[partition]
  F -- no --> C[Corte por posición]

Cuando el formato no tiene separador, como EURUSD, se trocea por posición: las divisas siempre tienen tres letras (son códigos ISO 4217), así que [:3] y [3:] bastan. Si no hay ni separador ni longitud fija (BTCUSDT), hace falta una tabla con los símbolos que publica el propio mercado; adivinar las partes es una fuente segura de errores.

f-strings: texto con valores dentro

Una f-string es una cadena con una f delante. Dentro, todo lo que va entre llaves se evalúa como código y se sustituye por su valor. Es la forma de construir mensajes, nombres de fichero y líneas de informe:

IN [04]python
ticker = "SINT"
cierre = 142.22
anterior = 139.98
print(f"{ticker} cierra en {cierre}")
print(f"Variación: {cierre - anterior}")
OUT [04]Valores dentro del texto
SINT cierra en 142.22
Variación: 2.240000000000009

Dentro de las llaves puede ir cualquier expresión, como la resta de la segunda línea, que muestra otra vez la coma flotante de la lección 0.3.1: el texto necesita un formato que fije los decimales. Si se olvida la f, las llaves salen tal cual en el texto y no hay ningún error que avise. Un atajo útil: un = al final de la expresión escribe también su nombre.

IN [05]python
print(f"{cierre=}  {anterior=}")
print(f"{cierre - anterior = :.2f}")
OUT [05]El atajo de depuración
cierre=142.22  anterior=139.98
cierre - anterior = 2.24

{cierre=} escribe el nombre de la variable, un igual y su valor: útil para seguir un cálculo sin escribir dos veces el nombre. La segunda línea añade un formato tras los dos puntos, .2f, que es lo que se ve a continuación.

El mini-lenguaje de formato

Lo que va tras los dos puntos dentro de las llaves es la especificación de formato. Tiene sus campos en un orden fijo, y cada uno es opcional. La figura de la cabecera descompone {pnl:>+12,.2f}, el formato típico de una columna de P&L:

CampoEjemploQué hace
Alineación< > ^A la izquierda, a la derecha, centrado (con un carácter de relleno delante, si se quiere: *>)
Signo+Escribe el signo también en los positivos (por defecto, solo en los negativos)
Ancho12Ocupa al menos 12 caracteres, rellenando con espacios
Agrupación, o _Separa los miles con coma o guion bajo
Precisión.2Número de decimales (con f y %)
Tipof % e dDecimal fijo, porcentaje (multiplica por 100), notación científica, entero
IN [06]python
pnl = 1426.71
rent = 0.07041
volumen = 2_322_609

print(f"{cierre:.2f}  {cierre:.4f}  {cierre:.0f}")
print(f"{rent:.2%}  {rent:+.1%}  {-rent:+.1%}")
print(f"{volumen:,}  {volumen:_}  {volumen:.2e}")
print(f"{pnl:+,.2f}  {-pnl:+,.2f}")
print(f"[{pnl:>12,.2f}]  [{pnl:<12,.2f}]  [{'SINT':^10}]")
OUT [06]Precios, porcentajes, signos y miles
142.22  142.2200  142
7.04%  +7.0%  -7.0%
2,322,609  2_322_609  2.32e+06
+1,426.71  -1,426.71
[    1,426.71]  [1,426.71    ]  [   SINT   ]

Tres detalles que conviene fijar. El tipo % multiplica por 100: la rentabilidad se guarda como tanto por uno (0,07041) y se muestra como porcentaje, nunca al revés. El formato .2f redondea solo lo que se muestra: la variable sigue valiendo lo mismo, con todos sus decimales. Y el redondeo del formato es el de la coma flotante, con los mismos empates engañosos que round() en la lección 0.3.1; para importes que tienen que cuadrar al céntimo, el redondeo se hace antes con Decimal.

El signo explícito (+) es la convención de los informes de P&L y de las variaciones de precio: +1,426.71 y -1,426.71 se distinguen de un vistazo, y una columna de cifras con signo siempre del mismo ancho se lee mejor.

Un informe de operaciones alineado

El ancho y la alineación sirven para construir tablas de texto: el registro de un script que opera, un correo con el resumen del día o la salida de un backtest en la terminal. Los números se alinean a la derecha, para que las unidades queden una debajo de otra, y el texto a la izquierda.

Las cinco operaciones de la celda son las primeras de operaciones_sint.csv (enlace en «Recursos»), con el P&L ya neto de comisiones. La lista de tuplas y el bucle for se explican en las lecciones 0.3.3 y 0.3.4; aquí basta con saber que la línea de dentro del bucle se repite para cada operación:

IN [07]python
operaciones = [
    ("2021-03-04", "ORO", "corto", 200, 190.08, -3123.56),
    ("2021-09-02", "SINT", "largo", 180, 108.64, 7.43),
    ("2021-10-27", "SINT", "corto", 10, 112.07, -31.50),
    ("2021-11-10", "SINT", "corto", 40, 104.30, -306.72),
    ("2022-07-22", "SINT", "largo", 200, 102.83, 1426.71),
]
cabecera = (f"{'Fecha':<10}  {'Símbolo':<7}  {'Lado':<5}  "
            f"{'Cant.':>5}  {'Entrada':>8}  {'P&L':>10}")
print(cabecera)
print("-" * len(cabecera))
for fecha, simbolo, lado, cant, entrada, pnl in operaciones:
    print(f"{fecha:<10}  {simbolo:<7}  {lado:<5}  "
          f"{cant:>5}  {entrada:>8.2f}  {pnl:>+10,.2f}")
OUT [07]Informe de cinco operaciones
Fecha       Símbolo  Lado   Cant.   Entrada         P&L
-------------------------------------------------------
2021-03-04  ORO      corto    200    190.08   -3,123.56
2021-09-02  SINT     largo    180    108.64       +7.43
2021-10-27  SINT     corto     10    112.07      -31.50
2021-11-10  SINT     corto     40    104.30     -306.72
2022-07-22  SINT     largo    200    102.83   +1,426.71

La cabecera usa los mismos anchos que las filas, y la raya mide lo mismo que la cabecera gracias a len. Dos f-strings seguidas entre paréntesis se unen en una sola cadena: es la forma de partir una línea larga sin que el código pase de 72 caracteres. Las cadenas de dentro de las llaves ({'Fecha':<10}) usan comillas simples para distinguirse de las dobles de la f-string; desde Python 3.12 se podrían repetir las dobles, pero se lee peor.

Formato español sin tocar el locale

Python formatea los números a la inglesa: coma para los miles y punto para los decimales. En España se escribe al revés, 1.426,71, y el símbolo de porcentaje va separado de la cifra (7,04 %). Para un informe que lee una persona, el formato local importa: 1,426 es mil cuatrocientos veintiséis para un lector inglés y uno coma cuatro para uno español.

Python tiene una forma «oficial» de hacerlo, el módulo locale y el tipo de formato n, que usan la configuración regional del sistema. Tiene dos problemas. El resultado depende de la máquina: el mismo script escribe 1.426,71 en un portátil configurado en español y 1426.71 en un servidor con el locale C, el habitual en contenedores. Y locale.setlocale cambia una configuración global del proceso, que afecta a todo lo que se ejecuta en él, incluidas las librerías.

La alternativa robusta es formatear a la inglesa, que es determinista, e intercambiar después los dos signos. str.maketrans(",.", ".,") crea una tabla de traducción (cada coma por un punto y cada punto por una coma) y translate la aplica en una sola pasada. La celda lo envuelve en una función para no repetirlo; las funciones se ven en la lección 0.3.5, y aquí basta con saber que def da nombre a un cálculo y return devuelve su resultado:

IN [08]python
A_ESPANOL = str.maketrans(",.", ".,")

def es(numero, decimales=2):
    """Número con miles en punto y decimales en coma."""
    return f"{numero:,.{decimales}f}".translate(A_ESPANOL)

def es_pct(tanto_por_uno, decimales=2):
    """Porcentaje en formato español: 7,04 %."""
    return es(tanto_por_uno * 100, decimales) + " %"

print(es(1426.71), es(-3123.56), es(2_322_609, 0))
print(es_pct(0.07041), es_pct(-0.25, 1))
print(f"P&L del día: {es(pnl)} €")
OUT [08]Formato español determinista
1.426,71 -3.123,56 2.322.609
7,04 % -25,0 %
P&L del día: 1.426,71 €

La precisión también puede venir de una variable: {numero:,.{decimales}f} anida unas llaves dentro de la especificación. El resultado es el mismo en cualquier máquina, y los números se guardan siempre como números: el formato español es solo para mostrarlos. Un fichero de datos (CSV, Parquet) nunca lleva números formateados, ni en español ni en inglés.

Fechas: ISO 8601, strftime y strptime

Una fecha escrita como texto es ambigua: 03/04/2025 es el 3 de abril en España y el 4 de marzo en Estados Unidos. La norma ISO 8601 resuelve el problema escribiendo de lo mayor a lo menor, 2025-04-03, con un único orden posible. Es el formato de los ficheros de datos del curso, de las APIs de los brókeres y de pandas. Tiene una ventaja más: como texto, las fechas ISO se ordenan igual que en el calendario.

IN [09]python
iso = ["2025-04-03", "2024-12-31", "2025-01-15"]
espanol = ["03/04/2025", "31/12/2024", "15/01/2025"]
print(sorted(iso))
print(sorted(espanol))
OUT [09]ISO 8601 se ordena bien como texto
['2024-12-31', '2025-01-15', '2025-04-03']
['03/04/2025', '15/01/2025', '31/12/2024']

sorted ordena alfabéticamente. Con ISO 8601 el resultado es cronológico; con el formato español, el 31 de diciembre de 2024 queda el último porque «31» va después de «15» en el alfabeto.

Para operar con fechas (sumar días, saber el día de la semana) no se usa el texto, sino el tipo date del módulo datetime. date.fromisoformat convierte un texto ISO en una fecha, e isoformat hace lo contrario. Para cualquier otro formato, strftime («string from time») escribe una fecha con un patrón, y strptime («string parse time») la lee:

CódigoSignificaEjemplo
%YAño con cuatro cifras2025
%mMes con dos cifras12
%dDía con dos cifras31
%H:%M:%SHora, minutos y segundos15:30:00
%A / %BNombre del día / del mes (según el locale)Wednesday / December
IN [10]python
from datetime import date, datetime

fecha = date.fromisoformat("2025-12-31")
print(fecha, fecha.year, fecha.month, fecha.day)
print(fecha.strftime("%d/%m/%Y"), f"{fecha:%d/%m/%Y}")
print(fecha.weekday(), f"{fecha:%A}")

leida = datetime.strptime("31/12/2025", "%d/%m/%Y").date()
print(leida == fecha, leida.isoformat())

orden = datetime.fromisoformat("2025-12-31T15:30:00")
print(orden, orden.date(), orden.time())
OUT [10]De texto a fecha y de fecha a texto
2025-12-31 2025 12 31
31/12/2025 31/12/2025
2 Wednesday
True 2025-12-31
2025-12-31 15:30:00 2025-12-31 15:30:00

Las f-strings aceptan los mismos códigos tras los dos puntos: {fecha:%d/%m/%Y} equivale a strftime. weekday numera los días desde el lunes (0) hasta el domingo (6): el 31 de diciembre de 2025 es miércoles. datetime añade la hora a la fecha; en ISO 8601, la T separa las dos partes.

Los nombres de días y meses (%A, %B) tienen el mismo problema que el formato de los números: dependen del locale y en el runner del curso, como en muchos servidores, salen en inglés. La solución es la misma: no depender de él.

IN [11]python
DIAS = ("lunes", "martes", "miércoles", "jueves",
        "viernes", "sábado", "domingo")
MESES = ("enero", "febrero", "marzo", "abril", "mayo", "junio",
         "julio", "agosto", "septiembre", "octubre", "noviembre",
         "diciembre")

print(f"{DIAS[fecha.weekday()]}, {fecha.day} de "
      f"{MESES[fecha.month - 1]} de {fecha.year}")
print(f"Informe_{fecha:%Y%m%d}.txt")
OUT [11]Nombres en español sin locale
miércoles, 31 de diciembre de 2025
Informe_20251231.txt

DIAS[fecha.weekday()] usa el número del día como índice, igual que con los caracteres de una cadena. A los meses se les resta 1 porque month va de 1 a 12 y los índices empiezan en 0. La última línea muestra otra aplicación de ISO 8601: los nombres de fichero con la fecha en AAAAMMDD aparecen ordenados en cualquier carpeta.

Ejercicios

  1. Escribe el código que, a partir de " usdjpy ", obtenga el símbolo normalizado USDJPY, la divisa base y la cotizada, y lo muestre como USD/JPY.
Solución
IN [12]python
texto = "  usdjpy "
par = texto.strip().upper()
base, cotizada = par[:3], par[3:]
print(par, base, cotizada)
print(f"{base}/{cotizada}")
OUT [12]Normalizar un par de divisas
USDJPY USD JPY
USD/JPY

strip quita los espacios, upper pasa a mayúsculas y los cortes [:3] y [3:] separan las dos divisas, que siempre tienen tres letras.

  1. Con pnl = -1288.04 y rent = -0.10063, escribe una línea con este aspecto exacto (ancho 12 para el P&L y 8 para la rentabilidad, alineados a la derecha): P&L: -1,288.04 | Rent.: -10.06%.
Solución
IN [13]python
pnl = -1288.04
rent = -0.10063
print(f"P&L: {pnl:>12,.2f} | Rent.: {rent:>8.2%}")
OUT [13]Línea con anchos fijos
P&L:    -1,288.04 | Rent.:  -10.06%

>12 reserva doce caracteres y alinea a la derecha; , separa los miles y .2f deja dos decimales. En la rentabilidad, .2% multiplica por 100 y añade el símbolo: «-10.06%» ocupa siete caracteres, así que el ancho 8 deja un espacio delante.

  1. Un fichero de un bróker trae la fecha "04/03/2025 09:30" en formato estadounidense (mes/día/año). Conviértela a ISO 8601 y escribe el día de la semana en español.
Solución
IN [14]python
momento = datetime.strptime("04/03/2025 09:30", "%m/%d/%Y %H:%M")
print(momento.isoformat())
print(DIAS[momento.weekday()])
OUT [14]Fecha estadounidense a ISO 8601
2025-04-03T09:30:00
jueves

El patrón de strptime tiene que describir el texto tal como llega: %m/%d y no %d/%m. Con el patrón español, la fecha se habría leído como 4 de marzo sin ningún error: es el fallo más peligroso, porque no avisa.

Footnotes

  1. Yahoo Finance: ES=F y EURUSD=X. Cada proveedor documenta sus símbolos; al cambiar de proveedor, hay que traducirlos. ↩

Respuesta plegada en cada pregunta

Autoevaluación

  1. ¿Qué devuelve "EURUSD"[3:]?

    • A"EUR"
    • B"USD"
    • C"RUSD"
    • D"URUSD"
    Ver respuesta

    Respuesta B. "USD"

    Los índices empiezan en 0 y el corte [3:] va desde el carácter de índice 3 hasta el final: U, S, D. [:3] daría EUR.

  2. ¿Qué muestra f"{-1288.04:+,.2f}"?

    • A-1288.04
    • B-1.288,04
    • C-1,288.04
    • D+1,288.04
    Ver respuesta

    Respuesta C. -1,288.04

    + pide el signo siempre (aquí el número ya es negativo), , agrupa los miles con comas y .2f deja dos decimales. El formato es el inglés: la coma separa miles y el punto, decimales.

  3. ¿Por qué los ficheros de datos guardan las fechas como 2025-12-31 y no como 31/12/2025?

    • APorque Python no sabe leer el formato español
    • BPorque ISO 8601 no es ambiguo y, como texto, se ordena igual que en el calendario
    • CPorque ocupa menos
    • DPorque lo exige pandas
    Ver respuesta

    Respuesta B. Porque ISO 8601 no es ambiguo y, como texto, se ordena igual que en el calendario

    03/04/2025 es 3 de abril en España y 4 de marzo en Estados Unidos; 2025-04-03 solo tiene una lectura. Y al ir de lo mayor (año) a lo menor (día), el orden alfabético coincide con el cronológico.

  4. Un script formatea los importes con f"{x:n}" para que salgan con el formato del sistema. ¿Qué problema tiene?

    • ANinguno: es la forma recomendada
    • BQue n no admite decimales
    • CQue el resultado depende del locale de cada máquina: el mismo script escribe informes distintos en el portátil y en el servidor
    • DQue es más lento
    Ver respuesta

    Respuesta C. Que el resultado depende del locale de cada máquina: el mismo script escribe informes distintos en el portátil y en el servidor

    n usa la configuración regional activa, que cambia entre máquinas y en muchos servidores es C (sin separador de miles). Un informe tiene que salir igual en todas partes: mejor fijar el formato en el código.

Ideas clave

  • Una cadena es una secuencia inmutable de caracteres: se indexa desde 0, se corta con [inicio:fin] y sus métodos devuelven cadenas nuevas.
  • Para trocear símbolos, partition y split separan por un carácter y removesuffix quita un sufijo conocido. Normaliza con strip y upper antes de comparar.
  • El formato va tras los dos puntos de la f-string: {pnl:>+12,.2f} es alineado a la derecha, con signo, 12 de ancho, miles con coma y dos decimales.
  • El formato español se obtiene intercambiando comas y puntos con translate, sin tocar el locale: así el informe sale igual en cualquier máquina.
  • Las fechas se guardan en ISO 8601 (2025-12-31): no son ambiguas y se ordenan bien como texto. strftime y strptime convierten entre date y cualquier otro formato.

Recursos

Datos