# Python 3 per a no programadors/Expressions booleanes

Aquí hi ha un petit exemple d'expressions booleanes:
L'execució d'aquest codi origina la següent resposta:
Què és el que passa? El programa consisteix en un seguit de valoracions print) de declaracions. Cada declaració print retorna un número i una expressió. El número serveix per ajudar-nos a fer el seguiment de quina resposta correspon a cada declaració. Vegeu que cada expressió es resol amb una resposta que és False (Fals) o True (Veritat). En Python false també es pot escriure amb un 0 i true amb un 1.
Les línies:
donen com a resposta True i False respectivament ja que la primera expressió és veritat i la segona és falsa. La tercera resposta, print(3, a == 6 and b == 7), és una mica diferent. L'operador and condiciona a que ambdues expressions siguin veritables perquè el valor del conjut de l'expressió sigui veritable. Si una o les dues expressions són False aleshores el resultat de l'expressió serà False. La línia següent, print(4, a == 7 and b == 7), permet comprovar que si una part d'una expressió amb un and és falsa, aleshores el conjunt és fals. El comportament de l'operador and es pot resumir de la següent manera:
Vegeu que si la primera expressió és falsa Python ja no comprova la segona expressió perquè el conjunt serà fals. Proveu d'executar False and print("Hi") i compareu-ho amb l'execució de True and print("Hi") El terme tècnic per això és Evaluació a curt circuit
La línia següent, print(5, not a == 7 and b == 7), fa servir l'operador not. not simplemet retorna l'oposat de l'expressió. (L'expressió es podria reescriure com a print(5, a != 7 and b == 7)).
Aquesta és la taula:
Les dues línies següents, print(6, a == 7 or b == 7) i print(7, a == 7 or b == 6), fan servir l'operador or. L'operador or retorna true si la primera expressió és true, o si la segona expressió és true o ambdues són true. Si cap de les expressions és true aleshores retorna false. Aquesta és la taula:
Vegeu que si la primera expressió és true aleshores Python ja no comprova la segona expressió perquè ja sap que el conjunt de l'expressió serà true (per l'operador or). Això funciona de manera que or és true si com a mínim algun dels elements de l'expressió és cert (true). La primera part és certa (true) de manera que la segona part podria ser certa o falsa, però el conjunt de l'expressió continuaria essent cert (perquè la condició és que algun sigui cert).
Les dues línies següents, print(8, not (a == 7 and b == 6)) i print(9, not a == 7 and b == 6), permeten comprovar que els parèntesis es poden fer servir per agrupar expressions i forçar que s'evaluï primer una de les parts. Vegeu que els parèntesis canvien el resultat de l'expressió de fals a cert. Això passa perquè els parèntesis fan que s'apliqui el not a tota l'expressió en comptes d'aplicar-se només a la porció de l'expressió a == 7.
A continuació es mostra un exemple d'utilització d'una expressió booleana:
L'execució d'aquest codi origina la següent resposta:
Aquest programa el que fa és anar comprovant determinades condicions while comptador < len(copia) i copia[comptador] no és igual a prev. Si comptador és més gran que el darrer index de copia o bé copia[comptador] és igual a prev aleshores l'and deixa de ser cert i surt del bucle. L'if simplement fa una comprovació per assegurar que el while ha sortit perquè s'ha trobat una coincidència.
L'altra característica de l'and es fa servir en aquest exemple. Si mireu la taula per l'and podeu veure que la tercera entrada és "false and false". Si comptador >= len(copia) (en altres paraules comptador < len(copia) és false) aleshores mai es mirarà copia[comptador]. Això és així perquè Python sap que si el primer és fals aleshores ambdós no poden ser veritat. Això es coneix com a curt circuit i és útil si la segona meitatde l'and pot causar un error si hi ha alguna cosa que no és correcta. S'ha fet servir la primera expressió (comptador < len(copia)) per comprovar i veure si comptador era un índex vàlid per a copia. (Si teniu algun dubte que això sigui així podeu suprimir les coicidències "Jill" i "Life", comprovar que encara funcionai aleshores capgirar l'ordre de comptador < len(copia) and copia[comptador] != prev perquè sigui copia[comptador] != prev and comptador < len(copia).)
Les expressions booleanes es poden fer servir quan és necesasri comprovar dues o més coses diferents a la vegada.

### Notes sobre Operadors Booleans

Un error comú entre els programadors més novells és la mala interpretació sobre la manera com funcionen els operadors booleans, que ve de la manera com l'intèrpret de python llegeix aquestes expressions. Per exemple, després de l'aprenentatge inicial sobre les declaracions "and " i "or", es pot assumir que l'expressió x == ('a' or 'b') comprovarà si la variable x és equivalent a una de les dues cadenes 'a' o 'b'. Això no és així. Per veure què és el que realment passa, obriu una sessió amb l'intèrpret i introduïu les expressions següents:
I aquest serà el resultat intuïtiu:
En aquest punt, els operadors and i or semblen erronis. No sembla que tingui sentit que, per les dues primeres expressions, 'a' sigui equivalent a 'a' o 'b' mentre que 'b' no ho sigui. A més a més, no té cap sentit que 'b' sigui equivalent a 'a' i 'b'. Després d'examinar què fa l'intèrpret amb els operadors booleans, aquests resultats fan de fet exactament el que se'ls demana, que no és el mateix que el que penses que estàs demanant.
Quan l'intèrpret Python mira l'expressió or, agafa la primera declaració i fa la comprovació per veure si és certa (true). Si la primera declaració és certa (true), aleshores Python retorna aquest valor de l'objecte sense comprovar la segona declaració. Això és així perquè per una expressió or, el conjunt és cert si un dels valors és cert; el programa no té per què molestar-se a mirar la segona declaració. D'altra banda, si el primer valor és evaluat com a fals Python comprova la segona meitat i retorna aquest valor. Aquesta segona meitat determina el valor veritable del conjunt de l'expressió des del moment en què la primera meitat era falsa. Aquesta "mandra" per part de l'intèrpret s'anomena "curt circuit" i és una manera comuna d'avaluar les expressions booleanes en molts llenguatges de programació.
De manera similar, per una expressió and, Python fa servir la tècnica del curt circuit per accelerar l'avaluació del valor veritable. Si la primera declaració és falsa aleshores el conjunt ha de ser fals, de manera que retorna aquest valor. D'altra banda si el primer valor és veritat (true), aleshores comprova el segon i retorna aquest valor.
Una cosa a tenir en compte en aquest punt és que l'expressió booleana retorna un valor indicant True o False, però Python considera un número de coses diferents per assignar-hi un valor cert. Per comprovar el valor cert de qualsevol objecte donat x, es pot fer servir la funció bool(x) per veure els seus valors veritables.
A continuació es mostra una taula amb exemples de valors veritables de diversos objectes:
Ara és possible entendre el resultats confusos que s'han obtingut fent la prova de les expressions booleanes anteriors. Fem un cop d'ull al que "veu" l'intèrpret tal com va llegint el codi:
Primer cas:
Segon cas:
Tercer cas:
Quart cas:
Per la qual cosa Python estava fent realment la seva feina quan ens donava aquells resultats aparentment sorprenents. Tal com s'ha esmentant anteriorment, el que és important e´s reconèixer quin serà el valor que retornarà l'expressió quan s'avaluï, perquè no sempre és obvi.
Tornant enrere cap a les expressions inicials, així és com s'hauria d'haver escrit per obtenir el que amb tota probabilitat volíeu obtenir:
Quan s'avaluen aquestes comparacions retornen valors veritables en termes de True o False, no pas cadenes de text, i per tant obtenim els resultats adients.

### Exemples

password1.py
L'exemple funciona de la següent manera

### Exercicis

Escriure un programa perquè un usuari encerti el vostre nom, però que només tingui tres oportunitats abans que el programa surti.