Tancàvem la lliçó anterior amb TascaFàcil calculant dies restants, percentatges d'avanç i urgències, però amb dues mancances molt visibles: la fitxa s'imprimia a raó d'una línia per dada, il·legible, i totes les dades continuaven escrites dins del codi. Per registrar la tasca d'un altre client calia obrir l'editor.
Aquesta lliçó arregla les dues coses, i amb això el teu programa creua una frontera important: deixa de ser una cosa que s'edita per convertir-se en una cosa que es fa servir. Un programa que es fa servir té dos punts de contacte amb el món: l'entrada (les dades que rep) i la sortida (els resultats que mostra). En Python aquests dos punts es diuen input() i print().
Ja coneixes print() des del mòdul 1, però només en la seva forma més simple. Aquí el veuràs a fons: diversos arguments, els paràmetres sep i end, els caràcters d'escapada, i sobretot les f-strings, l'eina amb què es compon text en el Python modern i amb la qual per fi podràs barrejar paraules i variables en una sola línia, alinear columnes i mostrar decimals amb la precisió que vulguis. Després arribarà input(), i amb ell un detall que condiciona tot el que ve: input() retorna sempre text, encara que l'usuari teclegi un número.
Contingut
- Entrada i sortida: els dos punts de contacte d'un programa
print()amb diversos arguments- Els paràmetres
sepiend - Caràcters d'escapada:
\n,\ti les cometes - f-strings: interpolació de variables
- Expressions dins d'una f-string
- Especificadors de format: decimals i alineació
- Altres maneres de formatar que veuràs en codi aliè
input(): demanar dades per teclat- El punt capital:
input()sempre retorna text - TascaFàcil: la fitxa es demana i es presenta
- Errors comuns i consells
- Exercicis
- Conclusió
- Entrada i sortida: els dos punts de contacte d'un programa
Qualsevol programa, des del més simple fins a un sistema bancari, segueix el mateix esquema de tres fases:
flowchart LR
A["ENTRADA<br/>dades que arriben"] --> B["PROCES<br/>calculs i decisions"]
B --> C["SORTIDA<br/>resultats que es mostren"]
Fins ara has treballat al centre: variables (02-01) i expressions (02-02) són procés pur. L'entrada estava fixada al codi i la sortida era rudimentària. Anem a cobrir els dos extrems.
Les dades poden entrar per moltes vies —teclat, fitxers, xarxa, sensors— i sortir per unes altres tantes. En aquest curs comencem per la més directa: el teclat per entrar i la pantalla (concretament, el terminal) per sortir. Llegir i escriure fitxers arribarà a Desar dades en fitxers.
Un advertiment de fons que convé tenir present des del primer dia: tot el que entra des de fora és sospitós. L'usuari pot teclejar un número on esperaves un nom, deixar el camp buit o escriure «ALTA» en majúscules. Comprovar que les dades són correctes s'anomena validar, i és el tema de la propera lliçó. Aquí ens ocupem de rebre-les i mostrar-les.
print() amb diversos arguments
print() amb diversos argumentsFins ara has fet servir print() amb un sol valor. Però admet diversos, separats per comes:
titol = "Logotip Forn Sole"
responsable = "Luis"
print("Titol:", titol)
print("Responsable:", responsable)Sortida:
Això resol de cop el problema que vam deixar pendent a la lliçó anterior: recorda que "Titol: " + titol funcionava només amb textos, i que "Dies: " + 3 donava TypeError. Amb comes no hi ha problema, perquè print() converteix cada valor a text automàticament:
dies_restants = 7
percentatge = 37.5
completada = False
data_lliurament = None
print("Dies restants:", dies_restants) # Dies restants: 7
print("Percentatge:", percentatge) # Percentatge: 37.5
print("Completada:", completada) # Completada: False
print("Lliurament:", data_lliurament) # Lliurament: NoneNúmeros, booleans, None: print() els mostra tots sense protestar.
Hi ha dos detalls a observar. Primer: entre cada argument apareix un espai, posat per Python, no per tu. Per això "Titol:" no porta espai final i tot i així la sortida es veu bé. Segon: no hi ha límit d'arguments.
Fixa't en el resultat: el % apareix separat del número perquè l'espai automàtic es posa entre tots els arguments. Aquest espai automàtic és còmode però també rígid; l'apartat següent explica com controlar-lo.
I un print() sense arguments imprimeix una línia en blanc:
És més net que print(""), que fa el mateix.
- Els paràmetres
sep i end
sep i endprint() admet dos paràmetres amb nom que en modifiquen el comportament.
sep canvia el separador que es posa entre els arguments. Per defecte és un espai.
print("alta", "mitjana", "baixa") # alta mitjana baixa
print("alta", "mitjana", "baixa", sep=" / ") # alta / mitjana / baixa
print("alta", "mitjana", "baixa", sep="") # altamitjanabaixa
print("2026", "08", "04", sep="-") # 2026-08-04Aquest últim exemple és l'ús típic: compondre una data o una ruta sense repetir el separador a mà.
end canvia el que s'imprimeix al final, després de l'últim argument. Per defecte és un salt de línia, "\n"; per això cada print() comença en una línia nova.
Sortida, tota en una sola línia:
En posar end="" li dius a print() que no salti de línia, així que la instrucció següent continua on es va quedar l'anterior. És el mecanisme de les barres de progrés i de qualsevol sortida que es construeix per parts.
Combinant totes dues:
| Paràmetre | Valor per defecte | Què controla |
|---|---|---|
sep |
" " (un espai) |
Què es posa entre els arguments |
end |
"\n" (salt de línia) |
Què es posa després de l'últim |
Els paràmetres amb nom com aquests s'anomenen arguments per paraula clau, i s'estudien a fons a Paràmetres i retorn de valors. De moment n'hi ha prou de saber que s'escriuen nom=valor i que van al final de la crida.
- Caràcters d'escapada:
\n, \t i les cometes
\n, \t i les cometesDins d'una cadena de text, la barra invertida \ té un significat especial: junt amb el caràcter següent forma una seqüència d'escapada que representa alguna cosa que no es pot teclejar directament.
| Escapada | Significat | Ús típic |
|---|---|---|
\n |
Salt de línia | Diverses línies en un sol print |
\t |
Tabulador | Separar columnes |
\" |
Cometa doble literal | Cometes dins d'un text entrecometat amb dobles |
\' |
Cometa simple literal | Ídem amb simples |
\\ |
Barra invertida literal | Rutes de Windows |
Salts de línia. Un sol print pot produir diverses línies:
Tabuladors. \t avança fins a la següent parada de tabulació, cosa que dóna un efecte de columnes:
Funciona, però amb una limitació important: les parades de tabulació són fixes (normalment cada 8 caràcters), així que si un nom és més llarg que la parada, la columna es desquadra. Per alinear de debò es fan servir els especificadors d'amplada de les f-strings, que veuràs a l'apartat 7.
Cometes dins de text. Hi ha tres maneres de resoldre-ho:
# 1. Cometes diferents per dins i per fora
print("El client va dir: 'ho vull per divendres'")
# 2. Escapant les cometes
print("El client va dir: \"ho vull per divendres\"")
# 3. Cometes simples fora, dobles dins
print('El client va dir: "ho vull per divendres"')La primera i la tercera són les més llegibles; la segona és útil quan el text conté els dos tipus de cometa.
Barra invertida literal. Com que \ inicia una escapada, per escriure una barra cal duplicar-la:
Existeix també la cadena crua, que desactiva les escapades: es marca amb una r al davant. És molt pràctica per a rutes de Windows:
I per a textos llargs de diverses línies, les cometes triples conserven el format tal com l'escrius:
- f-strings: interpolació de variables
Arribem a l'eina central d'aquesta lliçó. Una f-string (cadena formatada) és una cadena precedida per la lletra f en la qual pots inserir variables entre claus {}.
responsable = "Luis"
dies_restants = 7
print(f"La tasca es del {responsable} i queden {dies_restants} dies.")Compara les tres maneres de fer el mateix:
| Forma | Codi | Problema |
|---|---|---|
| Concatenació | "La tasca es del " + responsable |
No admet números sense convertir-los |
Arguments de print |
print("La tasca es del", responsable) |
Espais automàtics difícils de controlar |
| f-string | f"La tasca es del {responsable}" |
Cap: es llegeix com el resultat |
L'avantatge decisiu de la f-string és que el codi s'assembla al resultat. Veus la frase completa i, a dins, al seu lloc exacte, el buit que ocuparà la dada. I funciona amb qualsevol tipus, sense conversions:
titol = "Logotip Forn Sole"
hores = 9.5
completada = False
data = None
print(f"Tasca: {titol}") # Tasca: Logotip Forn Sole
print(f"Hores: {hores}") # Hores: 9.5
print(f"Feta: {completada}") # Feta: False
print(f"Lliurament: {data}") # Lliurament: NoneLa f va enganxada a la cometa d'obertura, i pot anar amb cometes simples, dobles o triples. Si oblides la f, no hi ha error: s'imprimeixen les claus literalment, cosa que és un descuit molt comú.
print("Queden {dies_restants} dies") # Queden {dies_restants} dies <- falta la f
print(f"Queden {dies_restants} dies") # Queden 7 diesSi necessites una clau literal dins d'una f-string, duplica-la: {{ produeix {.
- Expressions dins d'una f-string
Dins de les claus no només hi caben variables: hi cap qualsevol expressió de les que vas aprendre a la lliçó anterior.
hores_dedicades = 9
hores_estimades = 24
dia_actual = 12
dia_lliurament = 19
prioritat = "alta"
completada = False
print(f"Avanc: {hores_dedicades / hores_estimades * 100} %")
print(f"Queden {dia_lliurament - dia_actual} dies")
print(f"Hores per fer: {hores_estimades - hores_dedicades}")
print(f"Urgent: {prioritat == 'alta' and not completada}")Fixa't en l'última línia: dins de les claus hi ha una expressió lògica completa, i a la f-string s'han fet servir cometes simples per a 'alta' perquè les dobles ja estan ocupades per la cadena exterior. Barrejar els dos tipus de cometa és la manera d'evitar el conflicte.
Ara bé, un consell d'estil: que puguis ficar-hi expressions complexes no significa que ho hagis de fer. Aquesta línia és correcta però il·legible:
És molt millor calcular abans, amb un nom que expliqui què és, i limitar la f-string a mostrar:
percentatge_avanc = hores_dedicades / hores_estimades * 100
dies_restants = dia_lliurament - dia_actual
va_just = percentatge_avanc > 60 and dies_restants < 5
print(f"Va just de termini: {va_just}")La regla pràctica: dins d'una f-string, expressions curtes i evidents; la resta, en una variable amb nom.
Un truc útil per depurar: si poses un = després de l'expressió, la f-string mostra també el codi que la va generar.
És comodíssim quan estàs buscant per què un valor no és el que esperaves.
- Especificadors de format: decimals i alineació
Dins de les claus pots afegir, després de dos punts, un especificador de format que controla com es presenta el valor. La sintaxi general és {valor:format}.
Controlar els decimals
El problema és evident tan bon punt calcules un percentatge:
percentatge = 37.333333333333336
print(f"Avanc: {percentatge} %") # Avanc: 37.333333333333336 %
print(f"Avanc: {percentatge:.2f} %") # Avanc: 37.33 %
print(f"Avanc: {percentatge:.1f} %") # Avanc: 37.3 %
print(f"Avanc: {percentatge:.0f} %") # Avanc: 37 %.2f significa «format de coma flotant amb 2 decimals». Arrodoneix, no trunca: 37.336 amb .2f dóna 37.34.
És l'especificador que més faràs servir. Qualsevol quantitat calculada amb / que s'hagi de mostrar a una persona n'hauria de portar.
Alinear en columnes
Aquí és on les f-strings superen definitivament el tabulador \t. Pots fixar una amplada mínima i una alineació:
| Especificador | Significat | Exemple amb "Luis" |
|---|---|---|
{text:<10} |
Alinea a l'esquerra en 10 caràcters | Luis______ |
{text:>10} |
Alinea a la dreta en 10 caràcters | ______Luis |
{text:^10} |
Centra en 10 caràcters | ___Luis___ |
{text:<10} amb farciment |
{text:.<10} omple amb punts |
Luis...... |
(Els guions baixos representen espais.)
Vegem-ho component una taula de l'equip d'Estudi Alba:
print(f"{'RESPONSABLE':<12}{'TASQUES':>8}{'HORES':>8}")
print("-" * 28)
print(f"{'Marta':<12}{3:>8}{12.5:>8}")
print(f"{'Luis':<12}{5:>8}{27.0:>8}")
print(f"{'Nuria':<12}{2:>8}{9.25:>8}")El text s'alinea a l'esquerra (<) perquè així es llegeixen les paraules; els números a la dreta (>) perquè així s'alineen les unitats, les desenes i les centenes. És la convenció de qualsevol taula ben feta.
I es poden combinar amplada i decimals, posant l'amplada primer i la precisió després:
print(f"{'Marta':<12}{12.5:>8.2f}")
print(f"{'Luis':<12}{27.0:>8.2f}")
print(f"{'Nuria':<12}{9.25:>8.2f}")Ara sí: columna perfecta, amb dos decimals en tots els casos.
| Especificador | Què fa |
|---|---|
{x:.2f} |
2 decimals |
{x:>8} |
Amplada 8, alineat a la dreta |
{x:<15} |
Amplada 15, alineat a l'esquerra |
{x:^20} |
Amplada 20, centrat |
{x:>10.2f} |
Amplada 10, a la dreta, 2 decimals |
{x:,} |
Separador de milers: 1250000 → 1,250,000 |
{x:.1%} |
Com a percentatge: 0.375 → 37.5% |
Aquest últim mereix una nota: {0.375:.1%} multiplica per 100 i afegeix el símbol. Si el teu valor ja és en escala 0-100, fes servir .1f i escriu el % tu.
- Altres maneres de formatar que veuràs en codi aliè
Les f-strings existeixen des de Python 3.6 i són la forma recomanada avui. Però trobaràs codi —tutorials antics, projectes heretats— escrit amb les dues formes anteriors, i convé reconèixer-les.
El mètode .format(), de Python 3.0 endavant:
responsable = "Luis"
dies = 7
print("La tasca es del {} i queden {} dies.".format(responsable, dies))
print("La tasca es del {0} i queden {1} dies.".format(responsable, dies))
print("Avanc: {:.2f} %".format(37.333))Els buits {} s'omplen en ordre amb els arguments de .format(). Els especificadors després dels dos punts són els mateixos que a les f-strings, així que l'après a l'apartat anterior et serveix igual.
L'operador %, heretat del llenguatge C i encara present en molt codi antic:
print("La tasca es del %s i queden %d dies." % (responsable, dies))
print("Avanc: %.2f %%" % 37.333)Aquí %s és un buit per a text, %d per a enter i %.2f per a decimal amb dues xifres. És el més críptic dels tres i el més propens a errors.
| Forma | Aspecte | Quan fer-la servir |
|---|---|---|
| f-string | f"Hola {nom}" |
Sempre, en codi nou |
.format() |
"Hola {}".format(nom) |
Només si mantens codi antic |
% |
"Hola %s" % nom |
Mai en codi nou; reconèixer-lo n'hi ha prou |
Queda't amb això: escriu f-strings, i si topes amb les altres dues, ja saps què fan.
input(): demanar dades per teclat
input(): demanar dades per teclatinput() és la funció que atura el programa i espera que l'usuari teclegi alguna cosa i premi Intro.
Aquest programa es queda esperant sense dir res, cosa que és una pèssima experiència d'ús. Per això input() admet un argument: el missatge d'indicació o prompt, que es mostra abans d'esperar.
Execució (el que teclega l'usuari va subratllat pel cursor, aquí ho marquem a part):
El funcionament pas a pas:
flowchart TD
A["El programa arriba a input()"] --> B["Mostra el missatge del prompt"]
B --> C["S'ATURA i espera"]
C --> D["L'usuari tecleja i prem Intro"]
D --> E["input() retorna el que ha teclejat<br/>com a text"]
E --> F["Aquest text s'assigna a la variable"]
Tres detalls d'ús que marquen la diferència:
1. Acaba el prompt amb espai o dos punts i espai. Sense això, el que teclegi l'usuari apareixerà enganxat al missatge:
nom = input("Responsable:") # Responsable:Nuria <- lleig
nom = input("Responsable: ") # Responsable: Nuria <- correcte2. Digues exactament què esperes. Un prompt vague genera dades inservibles:
prioritat = input("Prioritat: ") # l'usuari no sap que posar
prioritat = input("Prioritat (alta/mitjana/baixa): ") # molt millor3. El resultat s'ha de desar. Escriure input("Nom: ") sense assignar-ho a res demana la dada i la llença. És un descuit habitual.
I una conseqüència que es nota en executar: input() bloqueja el programa. Res més no passa fins que l'usuari prem Intro. Si el teu programa sembla «penjat», comprova si està esperant una entrada.
- El punt capital:
input() sempre retorna text
input() sempre retorna textAquí hi ha la idea més important de la lliçó, i convé que la llegeixis dues vegades:
input()retorna SEMPRE un valor de tipusstr, sense excepcions, encara que l'usuari teclegi un número.
Comprova-ho:
L'usuari ha teclejat 3, a la pantalla es veu 3, però el que hi ha desat és el text "3", no el número 3. I això té conseqüències immediates i desconcertants:
dies = input("Dies estimats: ") # l'usuari tecleja 3
print(dies * 2) # 33 <- repeteix el text, no multiplica!"3" * 2 és repetició de cadena, que ja vas veure a la lliçó anterior: produeix "33". No és una fallada de Python; és que estàs multiplicant text.
I si intentes aritmètica de debò, el programa s'atura:
És el mateix TypeError de la lliçó anterior, vist ara des de l'altre costat. Resumim què passa segons el que s'intenti:
Operació amb dies = input() (l'usuari tecleja 3) |
Resultat |
|---|---|
print(dies) |
Mostra 3 — sembla un número |
type(dies) |
<class 'str'> — no ho és |
dies + 1 |
TypeError |
dies * 2 |
"33" (repetició, no multiplicació) |
dies > 2 |
TypeError — no es pot comparar text amb número |
f"Dies: {dies}" |
Dies: 3 — funciona, perquè només es mostra |
Fixa't en l'última fila: mostrar la dada funciona perfectament. El problema apareix només quan vols calcular amb ella.
Per això, a l'aplicació d'aquesta lliçó, TascaFàcil demanarà únicament dades que són text per naturalesa —títol, responsable, prioritat— i no demanarà els dies estimats ni les hores. Tan bon punt calgui un número, l'haurem de convertir, i aquesta conversió, juntament amb el que passa si l'usuari teclega «tres» en lloc de «3», és exactament el contingut de Conversió de tipus i validació.
Deixem, doncs, dos caps solts anotats:
input()retorna text i de vegades necessitem números.- L'usuari pot escriure
"ALTA"," alta "o"urgent", i cap dels tres no coincideix amb"alta"(aquell descobriment de la prova d'escriptori de 01-05).
Tots dos es lliguen a la propera lliçó.
- TascaFàcil: la fitxa es demana i es presenta
Versió 0.4 de tascafacil.py. El programa demana per teclat les tres dades de text de la tasca i mostra una fitxa alineada en columnes amb f-strings. Les dades numèriques continuen al codi, a l'espera de saber-les convertir.
# tascafacil.py - Estudi Alba
# Versio 0.4: les dades de text es demanen per teclat
# i la fitxa es presenta amb f-strings
NOM_APP = "TascaFacil"
VERSIO = "0.4"
ESTUDI = "Estudi Alba"
AMPLE = 46
HORES_PER_JORNADA = 8
# --- Capcalera ---
print("=" * AMPLE)
print(f"{NOM_APP + ' v' + VERSIO:^{AMPLE}}")
print(f"{'Gestor de tasques - ' + ESTUDI:^{AMPLE}}")
print("=" * AMPLE)
print()
# --- ENTRADA: dades que teclega l'usuari ---
print("Introdueix les dades de la tasca:")
print()
titol = input(" Titol : ")
descripcio = input(" Descripcio : ")
responsable = input(" Responsable (Marta/Luis/Nuria): ")
prioritat = input(" Prioritat (alta/mitjana/baixa): ")
# --- Dades que encara no podem demanar (son numeros) ---
dia_actual = 12
dia_lliurament = 19
hores_estimades = 24
hores_dedicades = 9
completada = False
# --- PROCES: calculs amb les dades ---
dies_restants = dia_lliurament - dia_actual
percentatge_avanc = hores_dedicades / hores_estimades * 100
hores_restants = hores_estimades - hores_dedicades
jornades_restants = hores_restants / HORES_PER_JORNADA
es_urgent = prioritat == "alta" and not completada
# --- SORTIDA: fitxa alineada ---
print()
print("=" * AMPLE)
print(f"{'FITXA DE TASCA':^{AMPLE}}")
print("=" * AMPLE)
print(f"{'Titol':<16}{titol:>{AMPLE - 16}}")
print(f"{'Responsable':<16}{responsable:>{AMPLE - 16}}")
print(f"{'Prioritat':<16}{prioritat:>{AMPLE - 16}}")
print(f"{'Completada':<16}{str(completada):>{AMPLE - 16}}")
print("-" * AMPLE)
print(f"{'Dies restants':<16}{dies_restants:>{AMPLE - 16}}")
print(f"{'Hores fetes':<16}{hores_dedicades:>{AMPLE - 16}.1f}")
print(f"{'Hores totals':<16}{hores_estimades:>{AMPLE - 16}.1f}")
print(f"{'Avanc':<16}{percentatge_avanc:>{AMPLE - 18}.1f} %")
print(f"{'Jornades rest.':<16}{jornades_restants:>{AMPLE - 16}.2f}")
print("-" * AMPLE)
print(f"{'Urgent':<16}{str(es_urgent):>{AMPLE - 16}}")
print("=" * AMPLE)
print()
print(f"Descripcio: {descripcio}")Una execució completa, amb la Marta registrant l'encàrrec del client Vidal:
==============================================
TascaFacil v0.4
Gestor de tasques - Estudi Alba
==============================================
Introdueix les dades de la tasca:
Titol : Targetes de visita Vidal
Descripcio : 300 uts, doble cara, paper reciclat
Responsable (Marta/Luis/Nuria): Nuria
Prioritat (alta/mitjana/baixa): alta
==============================================
FITXA DE TASCA
==============================================
Titol Targetes de visita Vidal
Responsable Nuria
Prioritat alta
Completada False
----------------------------------------------
Dies restants 7
Hores fetes 9.0
Hores totals 24.0
Avanc 37.5 %
Jornades rest. 1.88
----------------------------------------------
Urgent True
==============================================
Descripcio: 300 uts, doble cara, paper reciclatRepassem les tècniques emprades, perquè l'exemple condensa tota la lliçó:
"=" * AMPLEdibuixa els separadors. És la repetició de cadenes de la lliçó anterior, aquí amb un ús molt pràctic.{text:^{AMPLE}}centra el títol en l'amplada total. Fixa't en el detall avançat: l'amplada no està escrita a mà, és una altra variable entre claus. Així, canviantAMPLEa la primera línia, tota la fitxa es reajusta.{'Titol':<16}reserva 16 caràcters per a l'etiqueta, alineada a l'esquerra.{titol:>{AMPLE - 16}}ocupa la resta de la línia amb el valor alineat a la dreta. Dins de les claus d'amplada hi ha una expressió,AMPLE - 16, perfectament vàlida.{percentatge_avanc:>{AMPLE - 18}.1f} %combina amplada, alineació i un decimal; el- 18en comptes de- 16deixa lloc per als dos caràcters del%que van al darrere, de manera que la línia continua mesurant exactamentAMPLE.str(completada)converteix el booleà a text. És necessari perquè els especificadors d'alineació<i>funcionen de manera diferent amb booleans que amb cadenes; convertint-lo primer, s'alinea com qualsevol altre text. La funcióstr()és, precisament, el primer que veuràs a la propera lliçó.
El que continua sense funcionar
Prova aquesta execució i observa el resultat:
La fitxa es genera igual de bonica, però a sota hi diu Urgent False. La comparació prioritat == "alta" ha fallat perquè l'usuari va escriure en majúscules. I si escriu urgentissima, o deixa el camp en blanc prement Intro, el programa tampoc no protesta: desa la brossa i continua.
Aquesta és exactament la feina pendent.
Errors Comuns i Consells
Oblidar la f de la f-string. print("Queden {dies} dies") imprimeix les claus tal qual. No dóna error, així que cal veure-ho a la sortida. Si veus claus a la pantalla, falta la f.
Fer servir cometes dobles dins d'una f-string delimitada per dobles. f"Es {x == "alta"}" trenca la cadena. Fes servir cometes simples a dins: f"Es {x == 'alta'}".
Confondre .2f amb «dos dígits». .2f són dos decimals, no dues xifres en total. Per a l'amplada total es fa servir el número abans del punt: {x:8.2f}.
Alinear números a l'esquerra. Queda desalineat i costa comparar magnituds. Text a l'esquerra (<), números a la dreta (>).
Confiar en \t per fer taules. Funciona mentre tots els valors mesurin menys que la parada de tabulació; tan bon punt un se'n passa, la columna es desquadra. Fes servir amplades explícites.
No assignar el resultat d'input(). input("Nom: ") sense variable = al davant demana la dada i la descarta.
Prompt sense espai final. input("Nom:") fa que el que es teclegi s'enganxi al missatge. Deixa sempre un espai.
Donar per fet que input() retorna un número. És l'error que defineix aquesta lliçó: sempre retorna str. Si has de calcular, hauràs de convertir.
Prompts que no expliquen les opcions. Si només s'admeten tres prioritats, escriu-les al prompt. El cost d'un prompt clar és zero i estalvia la meitat de les entrades errònies.
Consell: separa entrada, procés i sortida. Mira l'estructura del programa d'aquesta lliçó: primer tots els input(), després tots els càlculs, i al final tota la presentació. És més fàcil de llegir, de provar i de modificar que si estan entremesclats. Aquesta separació és un principi de disseny que es manté en programes de qualsevol mida.
Consell: defineix l'amplada com a constant. AMPLE = 46 en lloc de repetir 46 en quinze línies. Canviar el disseny de la fitxa passa a ser qüestió d'una línia.
Consell: prova amb dades incòmodes. Executa el teu programa i teclega un títol llarguíssim, o prem Intro sense escriure res. La fitxa es desquadrarà o quedarà buida. Anota el que has vist: això és el que cal validar.
Exercicis
Exercici 1: Predir la sortida
Escriu exactament què imprimeix cada bloc, parant atenció a espais i salts de línia.
# a)
print("Marta", "Luis", "Nuria", sep=" | ")
# b)
print("Tasca", end=" -> ")
print("completada")
# c)
hores = 7.456
print(f"{hores:.2f}")
print(f"{hores:.0f}")
# d)
nom = "Luis"
print(f"[{nom:<10}]")
print(f"[{nom:>10}]")
print(f"[{nom:^10}]")
# e)
print("Linia 1\n\tLinia 2 tabulada")
# f)
dies = 5
print("Queden {dies} dies")
print(f"Queden {dies} dies")
# g)
print(f"{'Total':<8}{1250:>10,}")Exercici 2: Fitxa de l'equip d'Estudi Alba
Escriu un programa resum_equip.py que mostri aquesta taula fent servir només f-strings (res de \t), amb aquestes dades ja escrites en variables:
| Persona | Tasques pendents | Hores dedicades | Percentatge de càrrega |
|---|---|---|---|
| Marta | 3 | 12.5 | 0.25 |
| Luis | 5 | 27.0 | 0.45 |
| Nuria | 2 | 9.25 | 0.30 |
Requisits:
- Capçalera centrada en una amplada de 44 caràcters, amb línies de
=a dalt i a baix. - Noms alineats a l'esquerra; números a la dreta.
- Hores amb un decimal; el percentatge de càrrega mostrat com a percentatge amb un decimal (recorda
{x:.1%}). - L'amplada total ha d'estar en una constant i fer-se servir a totes les línies.
Exercici 3: Registre interactiu de tasca
Escriu registre_tasca.py que:
- Mostri una capçalera de benvinguda.
- Demani per teclat, amb prompts clars: títol, client, responsable i prioritat.
- Mostri una fitxa amb les quatre dades alineades en dues columnes.
- Al final, mostri en una sola línia, fent servir una f-string amb una expressió a dins, si la tasca és de prioritat alta.
- Imprimeixi el
type()de la variableprioritati expliqui en un comentari què significa el resultat.
Solucions
Solució 1.
a) Marta | Luis | Nuria — el sep substitueix l'espai per " | ".
b)
Una sola línia: el primer print no salta perquè end=" -> ".
c)
.2f arrodoneix a dos decimals (7.456 → 7.46) i .0f a zero decimals (7.456 → 7).
d)
Deu caràcters d'amplada en els tres casos; canvia on es col·loca el text. En centrar amb amplada sobrant senar, el buit extra va a la dreta.
e)
\n salta de línia i \t fica un tabulador al principi de la segona.
f)
Sense la f, les claus són text literal. És el descuit més comú.
g) Total 1,250 — Total ocupa 8 caràcters a l'esquerra, i 1250 es mostra amb separador de milers en 10 caràcters a la dreta.
Solució 2.
# resum_equip.py - Estudi Alba
AMPLE = 44
marta_tasques = 3
marta_hores = 12.5
marta_carrega = 0.25
luis_tasques = 5
luis_hores = 27.0
luis_carrega = 0.45
nuria_tasques = 2
nuria_hores = 9.25
nuria_carrega = 0.30
print("=" * AMPLE)
print(f"{'RESUM PER RESPONSABLE - Estudi Alba':^{AMPLE}}")
print("=" * AMPLE)
print(f"{'PERSONA':<14}{'TASQUES':>8}{'HORES':>11}{'CARREGA':>11}")
print("-" * AMPLE)
print(f"{'Marta':<14}{marta_tasques:>8}{marta_hores:>11.1f}{marta_carrega:>11.1%}")
print(f"{'Luis':<14}{luis_tasques:>8}{luis_hores:>11.1f}{luis_carrega:>11.1%}")
print(f"{'Nuria':<14}{nuria_tasques:>8}{nuria_hores:>11.1f}{nuria_carrega:>11.1%}")
print("=" * AMPLE)Sortida:
============================================
RESUM PER RESPONSABLE - Estudi Alba
============================================
PERSONA TASQUES HORES CARREGA
--------------------------------------------
Marta 3 12.5 25.0%
Luis 5 27.0 45.0%
Nuria 2 9.2 30.0%
============================================Fixa't en les amplades escollides: 14 + 8 + 11 + 11 = 44, exactament AMPLE. Quan les columnes sumen l'amplada total, les línies de = i - encaixen amb la taula i el resultat sembla fet expressament, que és justament el que busquem.
Observa també que 9.25 amb .1f es mostra com a 9.2 i no com a 9.3: davant d'un empat exacte, Python arrodoneix al dígit parell més proper (l'anomenat arrodoniment bancari). No és un error, però convé saber-ho quan presentis xifres a un client.
Solució 3.
# registre_tasca.py - Estudi Alba
AMPLE = 44
print("=" * AMPLE)
print(f"{'REGISTRE DE NOVA TASCA':^{AMPLE}}")
print(f"{'Estudi Alba':^{AMPLE}}")
print("=" * AMPLE)
print()
titol = input("Titol de la tasca : ")
client = input("Client : ")
responsable = input("Responsable (Marta/Luis/Nuria): ")
prioritat = input("Prioritat (alta/mitjana/baixa): ")
print()
print("-" * AMPLE)
print(f"{'FITXA':^{AMPLE}}")
print("-" * AMPLE)
print(f"{'Titol':<14}{titol:>{AMPLE - 14}}")
print(f"{'Client':<14}{client:>{AMPLE - 14}}")
print(f"{'Responsable':<14}{responsable:>{AMPLE - 14}}")
print(f"{'Prioritat':<14}{prioritat:>{AMPLE - 14}}")
print("-" * AMPLE)
print(f"Es de prioritat alta: {prioritat == 'alta'}")
# <class 'str'>: input() retorna SEMPRE text, encara que l'usuari
# teclegi un numero. Per aixo la comparacio de dalt nomes funciona
# si escriu exactament "alta" en minuscules.
print(type(prioritat))Exemple d'execució:
============================================
REGISTRE DE NOVA TASCA
Estudi Alba
============================================
Titol de la tasca : Cartell fira del llibre
Client : Associacio de llibreters
Responsable (Marta/Luis/Nuria): Nuria
Prioritat (alta/mitjana/baixa): mitjana
--------------------------------------------
FITXA
--------------------------------------------
Titol Cartell fira del llibre
Client Associacio de llibreters
Responsable Nuria
Prioritat mitjana
--------------------------------------------
Es de prioritat alta: False
<class 'str'>Prova d'executar-lo de nou escrivint ALTA a la prioritat: la fitxa sortirà igual de correcta, però Es de prioritat alta continuarà dient False. Aquest és el problema que resolem tot seguit.
Conclusió
El teu programa ja parla amb el món. Saps que print() accepta diversos arguments separats per comes —convertint cadascun a text automàticament— i que els seus paràmetres sep i end controlen què es posa entre els valors i què es posa al final. Manegues els caràcters d'escapada \n, \t, \" i \\, i saps resoldre les cometes dins d'un text de tres maneres diferents.
Sobretot, domines les f-strings: interpolar variables i expressions entre claus, arrodonir decimals amb .2f, i alinear columnes amb <, > i ^ per produir taules llegibles sense dependre del tabulador. Reconeixes a més .format() i l'antic % quan els trobis en codi aliè, encara que escriguis sempre f-strings.
I coneixes input(): com atura el programa, com se li posa un missatge útil i —el punt que governa la propera lliçó— que retorna sempre un str, encara que l'usuari teclegi un número.
TascaFàcil és a la seva versió 0.4 i ja s'assembla a una eina: la Marta l'executa, teclega el títol, la descripció, el responsable i la prioritat de l'encàrrec, i obté una fitxa alineada amb els càlculs de termini i avanç. Ningú no ha d'obrir l'editor per registrar una tasca nova.
Però hem deixat dos caps solts ben visibles. El primer: les dades numèriques —dies estimats, hores dedicades— continuen escrites al codi, perquè el que arriba d'input() és text i "3" + 1 dóna TypeError. El segon: el programa s'empassa qualsevol cosa que li teclegi l'usuari. Si la Marta escriu ALTA, la comparació falla; si escriu urgentissima, es desa tal qual; si prem Intro sense escriure, la tasca es queda sense títol.
Tots dos són el mateix problema vist de dues maneres: les dades que vénen de fora no són de fiar. A Conversió de tipus i validació aprendràs a convertir-les al tipus correcte amb int(), float() i str(), a sanejar-les amb .strip() i .lower() —cosa que per fi farà que "ALTA" valgui tant com "alta", el cap que vam deixar solt a la lliçó 01-05— i a comprovar que són vàlides abans de fer-les servir. Amb això tancarem el mòdul 2 i TascaFàcil serà, per primera vegada, un programa robust.
Fonaments de la Programació
Mòdul 1: Introducció a la Programació
- Què és la programació?
- Història de la programació
- Llenguatges de programació
- Entorns de desenvolupament
- Del problema a l'algorisme
Mòdul 2: Conceptes Bàsics
- Variables i tipus de dades
- Operadors i expressions
- Entrada i sortida de dades
- Conversió de tipus i validació de dades
Mòdul 3: Estructures de Control
Mòdul 4: Funcions i Procediments
- Definició i ús de funcions
- Paràmetres i retorn de valors
- Àmbit de variables
- Descompondre un programa en funcions
- Funcions com a valors: lambda i ordre superior
Mòdul 5: Estructures de Dades
- Llistes i arrays
- Cadenes de caràcters
- Diccionaris i conjunts
- Tuples i estructures imbricades
- Desar dades en fitxers: text, CSV i JSON
Mòdul 6: Algorismes Bàsics
Mòdul 7: Objectes i Organització del Codi
- De les dades als objectes: classes i instàncies
- Atributs, mètodes i constructor
- Col·leccions d'objectes
- Mòduls, paquets i importacions
Mòdul 8: Bones Pràctiques i Eines
- Documentació i comentaris
- Depuració i gestió d'errors
- Control de versions
- Proves automatitzades
- Estil, llegibilitat i refactorització
