Guida Completa alla Formattazione Stringhe in Python: Dai Fondamentali ai Report Avanzati

Cerca:

Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors
Formattazione Stringhe Python

Se scrivi codice in Python, sai quanto sia importante comunicare con chiarezza, sia che si tratti di mostrare dati all’utente, generare report o creare messaggi di log. La presentazione delle informazioni fa davvero la differenza tra un output confuso e uno che colpisce nel segno. In Python, esistono diversi modi per modellare il testo proprio come desideri, rendendo i tuoi messaggi facili da leggere e piacevoli alla vista. Ti guideremo attraverso le tecniche più utili, dal mettere in ordine i dati in tabelle precise all’aggiungere un tocco di stile ai tuoi report. Vedrai come un testo ben formattato non sia solo un vezzo, ma una parte essenziale per creare applicazioni pulite ed efficienti.

Esercizio 1 – Livello Base: Presentazione Personale

Testo dell’esercizio

Scrivi un programma che chieda all’utente di inserire il proprio nome, cognome ed età, e poi stampi una frase di presentazione formattata usando il metodo .format(). La frase deve essere del tipo: “Ciao, io sono Mario Rossi e ho 18 anni.”

Soluzione commentata

# Raccolta dati dall'utente
nome = input("Inserisci il tuo nome: ")
cognome = input("Inserisci il tuo cognome: ")
eta = input("Inserisci la tua età: ")

# Formattazione con il metodo .format()
presentazione = "Ciao, io sono {} {} e ho {} anni.".format(nome, cognome, eta)
print(presentazione)

# Alternativa più elegante con format posizionale
presentazione2 = "Ciao, io sono {0} {1} e ho {2} anni.".format(nome, cognome, eta)
print(presentazione2)

Spiegazione teorica

Il metodo .format() è uno dei modi principali per formattare stringhe in Python. Funziona sostituendo i placeholder (segnaposto) {} con i valori passati come argomenti. I placeholder possono essere:

  • Vuoti: {} – vengono riempiti nell’ordine degli argomenti
  • Posizionali: {0}, {1}, {2} – permettono di riutilizzare e riordinare gli argomenti
  • Nominali: {nome}, {cognome} – utilizzano nomi specifici

Esercizio 2 – Livello Elementare: Calcolo e Formattazione Numerica

Testo dell’esercizio

Un negozio di elettronica deve stampare gli scontrini. Scrivi un programma che:

  1. Chieda il nome del prodotto, il prezzo unitario e la quantità
  2. Calcoli il totale e l’IVA (22%)
  3. Stampi uno scontrino formattato con 2 decimali per tutti i prezzi

Soluzione commentata

# Raccolta dati
prodotto = input("Nome del prodotto: ")
prezzo_unitario = float(input("Prezzo unitario (€): "))
quantita = int(input("Quantità: "))

# Calcoli
subtotale = prezzo_unitario * quantita
iva = subtotale * 0.22
totale = subtotale + iva

# Formattazione con controllo decimali
print("\n" + "="*30)
print("         SCONTRINO")
print("="*30)
print("Prodotto: {}".format(prodotto))
print("Prezzo unitario: €{:.2f}".format(prezzo_unitario))
print("Quantità: {}".format(quantita))
print("-"*30)
print("Subtotale: €{:.2f}".format(subtotale))
print("IVA (22%): €{:.2f}".format(iva))
print("="*30)
print("TOTALE: €{:.2f}".format(totale))

Spiegazione teorica

Formattazione numerica: Il formato {:.2f} serve per:

  • : indica l’inizio delle specifiche di formato
  • .2 specifica 2 cifre decimali
  • f indica formato float (numero decimale)

Altri formati utili:

  • {:.0f} – nessun decimale
  • {:10.2f} – larghezza totale 10 caratteri, 2 decimali
  • {:,} – separatore delle migliaia

Esercizio 3 – Livello Intermedio: f-string e Formattazione Avanzata

Testo dell’esercizio

Un sistema meteorologico deve generare un report giornaliero. Scrivi un programma che:

  1. Memorizzi in variabili: città, temperatura minima, massima, umidità e condizioni meteo
  2. Generi un report usando f-string con formattazione appropriata
  3. La temperatura deve essere allineata a destra su 5 caratteri
  4. L’umidità deve essere mostrata come percentuale

Soluzione commentata

# Dati meteorologici (simulati)
citta = "Milano"
temp_min = 8.5
temp_max = 15.2
umidita = 0.68  # 68% come decimale
condizioni = "Nuvoloso"

# Formattazione con f-string (Python 3.6+)
report = f"""
╔═══════════════════════════════════════╗
║           REPORT METEOROLOGICO        ║
╠═══════════════════════════════════════╣
║ Città: {citta:<30} ║
║ Temperatura min: {temp_min:>5.1f}°C           ║
║ Temperatura max: {temp_max:>5.1f}°C           ║
║ Umidità: {umidita:>6.1%}                   ║
║ Condizioni: {condizioni:<25} ║
╚═══════════════════════════════════════╝
"""

print(report)

# Esempio con calcoli diretti nell'f-string
escursione = temp_max - temp_min
print(f"Escursione termica: {escursione:.1f}°C")
print(f"Temperatura media: {(temp_min + temp_max)/2:.1f}°C")

Spiegazione teorica

f-string (formatted string literals) è il metodo più moderno e leggibile per formattare stringhe in Python 3.6+. Sintassi: f"testo {variabile:formato}"

Allineamento:

  • < allineamento a sinistra
  • > allineamento a destra
  • ^ allineamento centrato
  • Numero dopo : indica la larghezza totale

Formattazione percentuale: .1% moltiplica per 100 e aggiunge il simbolo %


Esercizio 4 – Livello Intermedio-Avanzato: Tabella Dinamica

Testo dell’esercizio

Una scuola deve stampare una tabella dei voti di uno studente. Scrivi un programma che:

  1. Memorizzi in una lista di tuple: (materia, voto, crediti)
  2. Calcoli la media ponderata sui crediti
  3. Stampi una tabella allineata con intestazioni
  4. Evidenzi in modo diverso i voti insufficienti (< 6)

Soluzione commentata

# Dati studente
nome_studente = "Alessandro Bianchi"
voti = [
    ("Matematica", 8.5, 4),
    ("Fisica", 7.0, 3),
    ("Italiano", 5.5, 4),
    ("Storia", 6.5, 2),
    ("Inglese", 9.0, 3),
    ("Informatica", 8.0, 2)
]

# Calcolo media ponderata
somma_voti_pesati = sum(voto * crediti for materia, voto, crediti in voti)
somma_crediti = sum(crediti for materia, voto, crediti in voti)
media_ponderata = somma_voti_pesati / somma_crediti

# Stampa tabella formattata
print(f"PAGELLA DI {nome_studente.upper()}")
print("="*50)
print(f"{'MATERIA':<15} {'VOTO':<8} {'CREDITI':<8} {'STATUS'}")
print("-"*50)

for materia, voto, crediti in voti:
    # Formattazione condizionale per voti insufficienti
    if voto < 6:
        status = "INSUFFICIENTE"
        print(f"{materia:<15} {voto:<8.1f} {crediti:<8} {status}")
    else:
        status = "SUFFICIENTE"
        print(f"{materia:<15} {voto:<8.1f} {crediti:<8} {status}")

print("-"*50)
print(f"MEDIA PONDERATA: {media_ponderata:.2f}")

# Valutazione finale
if media_ponderata >= 6:
    print(f"ESITO: PROMOSSO ✓")
else:
    print(f"ESITO: RESPINTO ✗")

PAGELLA DI ALESSANDRO BIANCHI
==================================================
MATERIA VOTO CREDITI STATUS
————————————————–
Matematica 8.5 4 SUFFICIENTE
Fisica 7.0 3 SUFFICIENTE
Italiano 5.5 4 INSUFFICIENTE
Storia 6.5 2 SUFFICIENTE
Inglese 9.0 3 SUFFICIENTE
Informatica 8.0 2 SUFFICIENTE
————————————————–
MEDIA PONDERATA: 7.39
ESITO: PROMOSSO ✓

Forse potrebbe interessarti anche:  Metodo Montecarlo: Cos'è, Come Funziona e Applicazioni Pratiche (con Esempi in Python)

Spiegazione teorica

Formattazione tabellare: È importante mantenere l’allineamento usando la sintassi {:<larghezza} per creare colonne ordinate.

List comprehension: sum(voto * crediti for materia, voto, crediti in voti) è una forma compatta per calcolare somme su iterabili.

Formattazione condizionale: Permette di modificare l’output in base al valore dei dati (utile per evidenziare informazioni importanti).


Esercizio 5 – Livello Avanzato: Sistema di Logging con Timestamp

Testo dell’esercizio

Crea un sistema di logging per un’applicazione che:

  1. Registri eventi con timestamp, livello di priorità e messaggio
  2. Formatti i log in modo professionale con larghezze fisse
  3. Utilizzi diversi livelli: INFO, WARNING, ERROR
  4. Includa un contatore progressivo per ogni log

Soluzione commentata

from datetime import datetime

# Classe per gestire il logging
class Logger:
    def __init__(self):
        self.counter = 0
        self.logs = []
    
    def log(self, level, message):
        self.counter += 1
        timestamp = datetime.now()
        
        # Creazione del record di log
        log_entry = {
            'id': self.counter,
            'timestamp': timestamp,
            'level': level,
            'message': message
        }
        
        self.logs.append(log_entry)
        
        # Formattazione e stampa immediata
        formatted_log = self._format_log(log_entry)
        print(formatted_log)
    
    def _format_log(self, log_entry):
        # Formattazione timestamp
        time_str = log_entry['timestamp'].strftime("%Y-%m-%d %H:%M:%S")
        
        # Formattazione con larghezze fisse e colori simulati
        level_colors = {
            'INFO': '🔵',
            'WARNING': '🟡', 
            'ERROR': '🔴'
        }
        
        icon = level_colors.get(log_entry['level'], '⚪')
        
        # f-string con formattazione complessa
        formatted = f"[{log_entry['id']:03d}] {time_str} {icon} {log_entry['level']:<7} | {log_entry['message']}"
        
        return formatted
    
    def print_summary(self):
        print("\n" + "="*60)
        print("RIEPILOGO SESSIONE DI LOGGING")
        print("="*60)
        
        # Conteggio per livello
        level_counts = {}
        for log in self.logs:
            level = log['level']
            level_counts[level] = level_counts.get(level, 0) + 1
        
        print(f"{'Livello':<10} {'Conteggio':<10} {'Percentuale'}")
        print("-"*35)
        
        for level, count in level_counts.items():
            percentage = (count / len(self.logs)) * 100
            print(f"{level:<10} {count:<10} {percentage:>6.1f}%")
        
        print(f"\nTotale eventi registrati: {len(self.logs)}")

# Esempio di utilizzo
logger = Logger()

# Simulazione di eventi
logger.log("INFO", "Applicazione avviata correttamente")
logger.log("INFO", "Connessione al database stabilita")
logger.log("WARNING", "Memoria disponibile sotto il 20%")
logger.log("INFO", "Utente 'admin' ha effettuato l'accesso")
logger.log("ERROR", "Errore di connessione al server esterno")
logger.log("WARNING", "Tentativo di accesso con credenziali errate")
logger.log("INFO", "Backup completato con successo")

# Stampa riepilogo
logger.print_summary()

[007] 2025-07-10 15:51:36 🔵 INFO | Backup completato con successo

============================================================
RIEPILOGO SESSIONE DI LOGGING
============================================================
Livello Conteggio Percentuale
———————————–
INFO 4 57.1%
WARNING 2 28.6%
ERROR 1 14.3%

Spiegazione teorica

Formattazione avanzata di date: Il metodo strftime() permette di formattare timestamp in modo personalizzato.

Formattazione con zeri iniziali: {:03d} assicura che il numero abbia sempre 3 cifre, riempiendo con zeri se necessario.

Dizionari per mapping: Usare dizionari per associare livelli di log a icone o colori migliora la leggibilità.

Metodi privati: _format_log() è un metodo privato (convenzione Python) per separare la logica di formattazione.


Esercizio 6 – Livello Esperto: Report Finanziario Multi-valuta

Testo dell’esercizio

Crea un sistema per generare report finanziari che:

  1. Gestisca transazioni in multiple valute (EUR, USD, GBP)
  2. Applichi tassi di cambio per convertire tutto in EUR
  3. Generi un report dettagliato con formattazione professionale
  4. Includa grafici ASCII per visualizzare i dati
  5. Calcoli statistiche avanzate (media, deviazione, trend)

Soluzione commentata

from datetime import datetime, timedelta
import random

class FinancialReportGenerator:
    def __init__(self):
        # Tassi di cambio simulati (rispetto all'EUR)
        self.exchange_rates = {
            'EUR': 1.0,
            'USD': 0.85,
            'GBP': 1.15
        }
        
        self.transactions = []
    
    def add_transaction(self, amount, currency, description, date=None):
        if date is None:
            date = datetime.now()
        
        # Conversione in EUR
        amount_eur = amount * self.exchange_rates.get(currency, 1.0)
        
        transaction = {
            'amount': amount,
            'currency': currency,
            'amount_eur': amount_eur,
            'description': description,
            'date': date
        }
        
        self.transactions.append(transaction)
    
    def generate_report(self):
        if not self.transactions:
            print("Nessuna transazione disponibile")
            return
        
        # Ordinamento per data
        sorted_transactions = sorted(self.transactions, key=lambda x: x['date'])
        
        # Calcoli statistici
        amounts_eur = [t['amount_eur'] for t in sorted_transactions]
        total = sum(amounts_eur)
        average = total / len(amounts_eur)
        
        # Calcolo deviazione standard semplificata
        variance = sum((x - average) ** 2 for x in amounts_eur) / len(amounts_eur)
        std_dev = variance ** 0.5
        
        # Generazione report
        self._print_header()
        self._print_transactions_table(sorted_transactions)
        self._print_statistics(total, average, std_dev)
        self._print_currency_breakdown()
        self._print_ascii_chart(amounts_eur)
    
    def _print_header(self):
        now = datetime.now()
        print("╔" + "═" * 78 + "╗")
        print("║" + " " * 25 + "REPORT FINANZIARIO" + " " * 35 + "║")
        print("║" + f" Generato il: {now.strftime('%d/%m/%Y alle %H:%M:%S')}" + " " * 32 + "║")
        print("╠" + "═" * 78 + "╣")
    
    def _print_transactions_table(self, transactions):
        print("║ DETTAGLIO TRANSAZIONI:" + " " * 55 + "║")
        print("╠" + "═" * 78 + "╣")
        
        # Intestazioni
        header = f"║ {'DATA':<12} {'IMPORTO':<15} {'VALUTA':<6} {'EUR':<12} {'DESCRIZIONE':<25} ║"
        print(header)
        print("╠" + "─" * 78 + "╣")
        
        for t in transactions:
            date_str = t['date'].strftime('%d/%m/%Y')
            amount_str = f"{t['amount']:>8.2f}"
            amount_eur_str = f"{t['amount_eur']:>8.2f}"
            desc_truncated = t['description'][:23] + ".." if len(t['description']) > 25 else t['description']
            
            row = f"║ {date_str:<12} {amount_str:<15} {t['currency']:<6} {amount_eur_str:<12} {desc_truncated:<25} ║"
            print(row)
        
        print("╚" + "═" * 78 + "╝")
    
    def _print_statistics(self, total, average, std_dev):
        print(f"\n📊 STATISTICHE GENERALI:")
        print(f"┌{'─' * 40}┐")
        print(f"│ {'Totale:':<20} {total:>15.2f} EUR │")
        print(f"│ {'Media per transazione:':<20} {average:>15.2f} EUR │")
        print(f"│ {'Deviazione standard:':<20} {std_dev:>15.2f} EUR │")
        print(f"│ {'Numero transazioni:':<20} {len(self.transactions):>15} │")
        print(f"└{'─' * 40}┘")
    
    def _print_currency_breakdown(self):
        # Raggruppamento per valuta
        currency_totals = {}
        for t in self.transactions:
            curr = t['currency']
            if curr not in currency_totals:
                currency_totals[curr] = {'count': 0, 'total': 0, 'total_eur': 0}
            
            currency_totals[curr]['count'] += 1
            currency_totals[curr]['total'] += t['amount']
            currency_totals[curr]['total_eur'] += t['amount_eur']
        
        print(f"\n💱 RIPARTIZIONE PER VALUTA:")
        print(f"┌{'─' * 60}┐")
        print(f"│ {'VALUTA':<8} {'TRANSAZIONI':<12} {'TOTALE ORIG.':<15} {'TOTALE EUR':<15} │")
        print(f"├{'─' * 60}┤")
        
        for currency, data in currency_totals.items():
            print(f"│ {currency:<8} {data['count']:>11} {data['total']:>12.2f} {data['total_eur']:>12.2f} │")
        
        print(f"└{'─' * 60}┘")
    
    def _print_ascii_chart(self, amounts):
        print(f"\n📈 GRAFICO TRANSAZIONI (ultimi 10):")
        
        # Prendi le ultime 10 transazioni
        recent_amounts = amounts[-10:] if len(amounts) > 10 else amounts
        
        if not recent_amounts:
            return
        
        # Normalizzazione per il grafico
        max_amount = max(recent_amounts)
        min_amount = min(recent_amounts)
        chart_width = 50
        
        print("┌" + "─" * (chart_width + 10) + "┐")
        
        for i, amount in enumerate(recent_amounts):
            # Calcola la larghezza della barra
            if max_amount == min_amount:
                bar_width = chart_width // 2
            else:
                normalized = (amount - min_amount) / (max_amount - min_amount)
                bar_width = int(normalized * chart_width)
            
            # Crea la barra
            bar = "█" * bar_width
            
            # Stampa la riga del grafico
            print(f"│ {i+1:2d} │{bar:<{chart_width}} │ {amount:>8.2f} EUR │")
        
        print("└" + "─" * (chart_width + 10) + "┘")

# Esempio di utilizzo completo
def demo_financial_report():
    reporter = FinancialReportGenerator()
    
    # Dati di esempio
    sample_transactions = [
        (1200.50, 'EUR', 'Stipendio gennaio'),
        (-45.30, 'EUR', 'Spesa supermercato'),
        (850.00, 'USD', 'Freelance project'),
        (-120.75, 'GBP', 'Abbonamento software'),
        (-67.20, 'EUR', 'Benzina'),
        (2300.00, 'EUR', 'Bonus aziendale'),
        (-89.99, 'USD', 'Acquisto online'),
        (-156.40, 'EUR', 'Assicurazione'),
        (445.80, 'GBP', 'Rimborso spese'),
        (-234.50, 'EUR', 'Affitto parcheggio')
    ]
    
    # Aggiunta transazioni con date simulate
    base_date = datetime.now() - timedelta(days=30)
    for i, (amount, currency, desc) in enumerate(sample_transactions):
        transaction_date = base_date + timedelta(days=i*3)
        reporter.add_transaction(amount, currency, desc, transaction_date)
    
    # Generazione report
    reporter.generate_report()

# Esecuzione demo
demo_financial_report()

╔══════════════════════════════════════════════════════════════════════════════╗
║ REPORT FINANZIARIO ║
║ Generato il: 10/07/2025 alle 15:54:05 ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ DETTAGLIO TRANSAZIONI: ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ DATA IMPORTO VALUTA EUR DESCRIZIONE ║
╠──────────────────────────────────────────────────────────────────────────────╣
║ 10/06/2025 1200.50 EUR 1200.50 Stipendio gennaio ║
║ 13/06/2025 -45.30 EUR -45.30 Spesa supermercato ║
║ 16/06/2025 850.00 USD 722.50 Freelance project ║
║ 19/06/2025 -120.75 GBP -138.86 Abbonamento software ║
║ 22/06/2025 -67.20 EUR -67.20 Benzina ║
║ 25/06/2025 2300.00 EUR 2300.00 Bonus aziendale ║
║ 28/06/2025 -89.99 USD -76.49 Acquisto online ║
║ 01/07/2025 -156.40 EUR -156.40 Assicurazione ║
║ 04/07/2025 445.80 GBP 512.67 Rimborso spese ║
║ 07/07/2025 -234.50 EUR -234.50 Affitto parcheggio ║
╚══════════════════════════════════════════════════════════════════════════════╝

Forse potrebbe interessarti anche:  Guida a Pytrends in Python: estrarre dati da Google Trends e gestire l'errore 429

📊 STATISTICHE GENERALI:
┌────────────────────────────────────────┐
│ Totale: 4016.92 EUR │
│ Media per transazione: 401.69 EUR │
│ Deviazione standard: 775.48 EUR │
│ Numero transazioni: 10 │
└────────────────────────────────────────┘

💱 RIPARTIZIONE PER VALUTA:
┌────────────────────────────────────────────────────────────┐
│ VALUTA TRANSAZIONI TOTALE ORIG. TOTALE EUR │
├────────────────────────────────────────────────────────────┤
│ EUR 6 2997.10 2997.10 │
│ USD 2 760.01 646.01 │
│ GBP 2 325.05 373.81 │
└────────────────────────────────────────────────────────────┘

📈 GRAFICO TRANSAZIONI (ultimi 10):
┌────────────────────────────────────────────────────────────┐
│ 1 │████████████████████████████ │ 1200.50 EUR │
│ 2 │███ │ -45.30 EUR │
│ 3 │██████████████████ │ 722.50 EUR │
│ 4 │█ │ -138.86 EUR │
│ 5 │███ │ -67.20 EUR │
│ 6 │██████████████████████████████████████████████████ │ 2300.00 EUR │
│ 7 │███ │ -76.49 EUR │
│ 8 │█ │ -156.40 EUR │
│ 9 │██████████████ │ 512.67 EUR │
│ 10 │ │ -234.50 EUR │
└────────────────────────────────────────────────────────────┘

Spiegazione teorica

Formattazione complessa: Questo esercizio combina diverse tecniche:

  • Box drawing characters: Caratteri Unicode per creare tabelle eleganti
  • Allineamento multiplo: Combinazione di allineamento a destra e sinistra
  • Formattazione condizionale: Diversi formati basati sui dati
  • Grafici ASCII: Visualizzazione dati con caratteri

Principi di design:

  • Separazione delle responsabilità: Ogni metodo ha un compito specifico
  • Riutilizzo: Metodi privati per evitare duplicazione di codice
  • Scalabilità: Struttura che può essere facilmente estesa

Tecniche avanzate:

  • List comprehension: Per calcoli statistici
  • Sorting personalizzato: sorted() con funzione lambda
  • Normalizzazione dati: Per il grafico ASCII
  • Gestione opzionale: Parametri con valori default

Concetti Chiave da Ricordare:

  1. Tre metodi principali: %, .format(), f-string
  2. f-string è preferibile per codice moderno (Python 3.6+)
  3. Formattazione numerica: :.2f, :,, :.1%
  4. Allineamento: :<, :>, :^
  5. Larghezza fissa: utile per tabelle e report

Errori Comuni da Evitare:

  • Confondere l’ordine dei parametri in .format()
  • Dimenticare i due punti : nella sintassi di formattazione
  • Non gestire la conversione di tipi (str/int/float)
  • Trascurare l’allineamento in output tabulari

In Sintesi: Formattazione delle Stringhe in Python

1. I Tre Metodi Principali

Metodo 1: Formattazione con % (Stile C)

# Sintassi base
nome = "Marco"
eta = 25
frase = "Ciao %s, hai %d anni" % (nome, eta)

# Specifiche di formato comuni
"%s"    # stringa
"%d"    # intero
"%f"    # float
"%.2f"  # float con 2 decimali
"%10s"  # stringa con larghezza 10
"%-10s" # stringa allineata a sinistra

Vantaggi: Veloce, compatibile con versioni molto vecchie di Python Svantaggi: Sintassi poco leggibile, limitato, propenso agli errori

Forse potrebbe interessarti anche:  Matrici di Adiacenza: Guida Completa, Esempi e Utilizzo in Python

Metodo 2: Metodo .format()

# Sintassi base
nome = "Marco"
eta = 25
frase = "Ciao {}, hai {} anni".format(nome, eta)

# Con indici posizionali
frase = "Ciao {0}, hai {1} anni. {0} è un bel nome!".format(nome, eta)

# Con nomi
frase = "Ciao {nome}, hai {eta} anni".format(nome=nome, eta=eta)

# Formattazione avanzata
prezzo = 19.99
"Il prezzo è €{:.2f}".format(prezzo)      # €19.99
"Il prezzo è €{:>10.2f}".format(prezzo)   # €     19.99
"Il prezzo è €{:0>10.2f}".format(prezzo)  # €0000019.99

Vantaggi: Molto flessibile, riutilizzo parametri, formattazione avanzata Svantaggi: Sintassi più verbosa rispetto alle f-string

Metodo 3: f-string (Formatted String Literals)

# Sintassi base (Python 3.6+)
nome = "Marco"
eta = 25
frase = f"Ciao {nome}, hai {eta} anni"

# Con espressioni dirette
numeri = [1, 2, 3, 4, 5]
risultato = f"La somma è {sum(numeri)}"

# Con formattazione
prezzo = 19.99
f"Il prezzo è €{prezzo:.2f}"
f"Il prezzo è €{prezzo:>10.2f}"

# Con chiamate a funzioni
from datetime import datetime
f"Ora: {datetime.now():%H:%M:%S}"

Vantaggi: Sintassi più pulita, performance migliori, espressioni inline

Svantaggi: Disponibile solo da Python 3.6+

2. Specifiche di Formato Dettagliate

Sintassi Generale

{[campo]:[riempimento][allineamento][segno][#][0][larghezza][,][.precisione][tipo]}

Allineamento

testo = "Python"
f"{testo:<10}"    # "Python    " (sinistra)
f"{testo:>10}"    # "    Python" (destra)
f"{testo:^10}"    # "  Python  " (centro)
f"{testo:*^10}"   # "**Python**" (centro con riempimento)

Numeri

numero = 1234567.89

# Formattazione di base
f"{numero:f}"      # 1234567.890000
f"{numero:.2f}"    # 1234567.89
f"{numero:.0f}"    # 1234568

# Separatori
f"{numero:,}"      # 1,234,567.89
f"{numero:_.2f}"   # 1_234_567.89

# Notazione scientifica
f"{numero:e}"      # 1.234568e+06
f"{numero:.2e}"    # 1.23e+06

# Percentuali
percentuale = 0.1234
f"{percentuale:.1%}"  # 12.3%

Numeri con Segno

positivo = 42
negativo = -42

f"{positivo:+d}"   # +42
f"{negativo:+d}"   # -42
f"{positivo: d}"   # " 42" (spazio per positivi)

Rappresentazione Numerica

numero = 255

f"{numero:b}"      # 11111111 (binario)
f"{numero:o}"      # 377 (ottale)
f"{numero:x}"      # ff (esadecimale minuscolo)
f"{numero:X}"      # FF (esadecimale maiuscolo)

3. Casi d’Uso Pratici

Tabelle Allineate

def stampa_tabella(dati):
    print(f"{'Nome':<15} {'Età':<5} {'Stipendio':<10}")
    print("-" * 30)
    for nome, eta, stipendio in dati:
        print(f"{nome:<15} {eta:<5} €{stipendio:>8,.2f}")

# Esempio d'uso
dipendenti = [
    ("Alice Rossi", 28, 35000),
    ("Bob Verdi", 35, 45000),
    ("Charlie Blu", 42, 55000)
]
stampa_tabella(dipendenti)

Report Finanziari

def report_vendite(vendite):
    totale = sum(vendite)
    media = totale / len(vendite)
    
    print("=" * 40)
    print("REPORT VENDITE")
    print("=" * 40)
    
    for i, vendita in enumerate(vendite, 1):
        percentuale = (vendita / totale) * 100
        print(f"Mese {i:2d}: €{vendita:>8,.2f} ({percentuale:5.1f}%)")
    
    print("-" * 40)
    print(f"Totale:  €{totale:>8,.2f}")
    print(f"Media:   €{media:>8,.2f}")
    print("=" * 40)

Formattazione Date e Ore

from datetime import datetime

ora = datetime.now()

# Formati comuni
f"{ora:%d/%m/%Y}"           # 15/03/2024
f"{ora:%Y-%m-%d}"           # 2024-03-15
f"{ora:%H:%M:%S}"           # 14:30:25
f"{ora:%d %B %Y}"           # 15 March 2024
f"{ora:%A, %d %B %Y}"       # Friday, 15 March 2024

4. Tecniche Avanzate

Formattazione Condizionale

def formato_voto(voto):
    if voto >= 18:
        return f"✓ {voto}/30 (Sufficiente)"
    else:
        return f"✗ {voto}/30 (Insufficiente)"

# Uso in f-string
voto = 24
messaggio = f"Risultato: {formato_voto(voto)}"

Formattazione Annidata

larghezza = 15
precisione = 2
numero = 123.456

# Formattazione dinamica
f"{numero:{larghezza}.{precisione}f}"

Escape di Caratteri Speciali

# Per includere { } letterali in f-string
percentuale = 0.85
f"Risultato: {percentuale:.1%} (tra {{parentesi grafffe}})"
# Output: "Risultato: 85.0% (tra {parentesi grafffe})"

5. Best Practices e Consigli

Scegliere il Metodo Giusto

  • f-string: Prima scelta per Python 3.6+
  • .format(): Quando serve riutilizzo parametri o compatibilità
  • %: Solo per codice legacy

Leggibilità del Codice

# ❌ Evitare: troppo complesso
messaggio = f"Utente {utente['nome']} ({utente['eta']} anni) ha {len(utente['ordini'])} ordini per un totale di €{sum(ord['prezzo'] for ord in utente['ordini']):.2f}"

# ✅ Meglio: spezzare in passaggi
nome = utente['nome']
eta = utente['eta']
num_ordini = len(utente['ordini'])
totale_ordini = sum(ord['prezzo'] for ord in utente['ordini'])

messaggio = f"Utente {nome} ({eta} anni) ha {num_ordini} ordini per un totale di €{totale_ordini:.2f}"

Gestione Errori

def formato_sicuro(valore, formato=".2f"):
    try:
        return f"{valore:{formato}}"
    except (ValueError, TypeError):
        return "N/A"

# Uso
prezzo = "non_un_numero"
print(f"Prezzo: €{formato_sicuro(prezzo)}")  # Prezzo: €N/A

6. Trucchi e Suggerimenti 

Formattazione Rapida Numeri

# Memorizza questi pattern comuni
n = 1234.5678

f"{n:.0f}"    # 1235 (arrotondato)
f"{n:.2f}"    # 1234.57
f"{n:,.2f}"   # 1,234.57
f"{n:>10.2f}" # "   1234.57"
f"{n:010.2f}" # "001234.57"

Debug con f-string

# Trucco per debug rapido (Python 3.8+)
x = 42
y = 3.14
print(f"{x=}, {y=}")  # x=42, y=3.14

Formattazione Multi-linea

# Per stringhe lunghe
nome = "Alessandro"
cognome = "Rossi"
eta = 25

messaggio = (
    f"Gentile {nome} {cognome}, "
    f"la informiamo che all'età di {eta} anni "
    f"ha diritto ai seguenti benefici..."
)

Questa guida copre tutti gli aspetti essenziali della formattazione stringhe in Python, dalle basi alle tecniche avanzate, con esempi pratici pronti per l’uso in esami e progetti reali.

Pubblicità