<jupyter_start><jupyter_text>Execução Condicional e ErrosExpressões Relacionais    Expressões Lógicas    Execução Condicional    Erros Previsíveis (Exceções)  1. Expressões RelacionaisUma expressão relacional (ou booleana) é uma expressão que terá como resultado um verdadeiro ou um falso.  Os operadores relacionais da Ling. Python:| Operador |Descrição || :---:    | :---:    || >        |Maior que || <        |Menor que || ==       |Igual a   || !=       |Não igual || >=       |Maior ou igual a|| <=       |Menor ou igual a|| is       |É o mesmo objeto|| is not   |Não é o mesmo objeto|| in       |Pertence à sequência|**Obs.1**: Um único sinal de igualdade `=` é um **operador de atribuição** e dois sinais de igualdade `==` é um **operador de comparação** de igualdade.  **Obs.2**: O operador de Igualdade `==` compara a igualdade dos **valores** de ambos os operandos, enquanto o operador `is` verifica se os operandos se referem ao **mesmo objeto** ou não (presente na mesma localização da memória).<jupyter_code>print(15 == 15)                                 # comparação: verdadeira
print(15 == 16)                                 # comparação: falsa
print(type(True))                               # cte booleana (classe 'bool')
print('' == True, '' == False, '' == None)      # cte string nula
a = 'ok'
b = 'tchau'
print(a, b, a is b)
b = a                                           # 'b' referencia 'a'
print(a, b, a is b)
a = 20                                          # 'a' assume nova referência, onde fica armazenado o valor 20
print(a, b, a is b)
a = 'ok'
print(a, b, a is b)<jupyter_output>True
False
<class 'bool'>
False False False
ok tchau False
ok ok True
20 ok False
ok ok True<jupyter_text>2. Expressões LógicasUma expressão lógica tem operandos booleanos (`True, False`) e terá como resultado também um valor booleano. Existem três operadores lógicos: `and`, `or`, e `not`. A semântica de cada um desses operadores é similar ao seu significado em Inglês.Considere que a variável `A` contém a constante `True` (verdadeiro) e a variável `B` contém a constante `False` (falso) nos exemplos mostrados na tabela dos **operadores lógicos** da Ling. Python:|Operador | Descrição  | Exemplo || :---:   | :---:      | :---    || and     | Operador E | `(A and B) --> False`| or      | Operador OU| `(A or B)  --> True`| not     | Operador NÃO| `not(A and B) --> True`Os operandos desses operadores deveriam ser exclusivamente expressões booleanas, mas o Python não é muito rigoroso. Qualquer número diferente de zero é interpretado como `True` e zero é interpretado como `False`.<jupyter_code>20 and True, 0 or 5 > 10, not 11, not(2-3)<jupyter_output><empty_output><jupyter_text>3. Execução CondicionalAs **Declarações Condicionais** nos permitem checar condições e mudar o comportamento do programa de acordo com o resultados delas. 3.1 Condicional Simples``` pythonif condicao:    comando1    comando2    ...    comandoN```A expressão booleana depois da declaração **`if`** é chamada de `condição` e a declaração termina com um sinal de dois pontos `:`. Sempre depois desse sinal, a(s) linha(s) deve(m) ser indentada(s) (recuada(s) da margem esquerda).  - Se a condição lógica resultar em **verdadeiro**, então o comando ou bloco de comandos (mais de um comando) indentado é executado.  - Se a condição lógica resultar em **falso**, o comando ou bloco de comandos indentado é ignorado.<jupyter_code># Raízes da Equação quadrática:   a.x^2 + b.x + c = 0
# Ex.: x^2 - 6x + 5 = 0
a, b, c = 1, -6, 5                # a = 1; b = -6; c = 5
delta = b**2 - 4*a*c              # discriminante
if delta > 0:
    r1 = (-b + (delta**0.5))/2/a
    r2 = (-b - (delta**0.5))/2/a
    print("Duas raízes reais distintas:", r1, r2)
print('Fim')<jupyter_output>Duas raízes reais distintas: 5.0 1.0
Fim<jupyter_text>3.2 Condicional Composta``` pythonif condicao:            if (condicao) {    comandoN1               comandoN1;    comandoN2               comandoN2;    ...                     ...    comandoN                comandoN;else:                   } else {    comandoM1               comandoM1;    comandoM2               comandoM2;    ...                     ...    comandoM                comandoM;                        }      ```Uma segunda forma da declaração **`if`** é conhecida por condicional composta, na qual existem duas possibilidades e o resultado da condição determina qual delas será executada.<jupyter_code># Par ou ímpar?
x = int(input("Digite um valor numérico inteiro:"))
if x % 2 == 0 :
    print('Valor digitado é par.')
else :
    print('Valor digitado é ímpar.')
# Raízes da Equação quadrática:   a.x^2 + b.x + c = 0
# Ex.: x^2 - 6x + 9 = 0
a, b, c = 1, -6, 9
delta = b**2 - 4*a*c              # discriminante
if delta > 0:
    r1 = -b/2/a + (delta**0.5)/2/a
    r2 = -b/2/a - (delta**0.5)/2/a
    print("Duas raízes reais distintas:", r1, r2)
else:
    print("Duas raízes reais iguais ou complexas.")<jupyter_output>Duas raízes reais iguais ou complexas.<jupyter_text>3.3 Condicional Encadeada``` pythonif condicao1:    comandoN1    ...    comandoNelif condicao2:    comandoM1    ...    comandoMelse:    comandoP1    ...    comandoP```Execuções **condicionais encadeadas** são várias condições em cascatas, ou seja, um **`if`** dentro de outro **`if`**. A declaração **`elif`** é a junção das declarações **`else + if`**.  SE os resultados da `condicao1` e `condicao2` forem falsos, então o comando ou bloco de comando depois da declaração `else` será executado.  Não há limite para o número de declarações **`elif`**. Se houver uma cláusula **`else`**, ela tem que estar no final da declaração, mas não há a necessidade de haver uma. Cada condição é verificada em ordem. Se a primeira for falsa, a próxima é verificada, e assim por diante. Se ao menos uma delas for verdadeira, a ramificação correspondente será executada e a declaração condicional terminará. Ainda que mais de uma condição seja verdadeira, somente a primeira delas será executada.<jupyter_code># Raízes da Equação quadrática:   a.x^2 + b.x + c = 0
# Ex.: x^2 - 6x + 10 = 0
a, b, c = 1, -1, 5
delta = b**2 - 4*a*c                    # discriminante
if delta > 0:                           # raízes reais distintas
    r1 = -b/2/a + (delta**0.5)/2/a
    r2 = -b/2/a - (delta**0.5)/2/a
    print("Duas raízes reais distintas:", r1, r2)
elif delta == 0:                        # raízes reais iguais 
    r1 = -b/2/a
    r2 = r1
    print("Duas raízes reais iguais:", r1, r2)
else:                                   # raízes complexas conjugadas
    r1 = -b/2/a + (delta**0.5)/2/a
    r2 = -b/2/a - (delta**0.5)/2/a
    print("Duas raízes complexas conjugadas:", r1, r2)
print('Fim')<jupyter_output>Duas raízes complexas conjugadas: (0.5000000000000001+2.179449471770337j) (0.4999999999999999-2.179449471770337j)
Fim<jupyter_text>3.4 Condicional Aninhada``` pythonif condicao1:    comando1 (ou bloco de comandos)else:    if condicao2:        comando2 (ou bloco de comandos)    else:        comando3 (ou bloco de comandos)```Uma declaração condicional pode ser aninhada a outra declaração aninhada.<jupyter_code># Valores formam triângulo?
# a, b, c = 12, 1, 6              # não formam
a, b, c = 12, 7, 6                # formam
if a+b > c:
    if c+b > a:
        if c+a > b:
            print("Valores formam triângulo:", a, b, c)
        else:
            print("Valores não formam triângulo:", a, b, c)
    else:
        print("Valores não formam triângulo:", a, b, c)
else:
    print("Valores não formam triângulo:", a, b, c)<jupyter_output>Valores formam triângulo: 12 7 6<jupyter_text>Sempre que possível, é uma boa ideia evitar as condicionais aninhadas, pois elas dificultam a leitura do script. O uso de **operadores lógicos** indicam um meio de simplificar condições aninhadas.<jupyter_code># Valores formam triângulo?
#a, b, c = 12, 1, 6              # não formam
a, b, c = 12, 7, 6               # formam
if (a+b > c) and (c+b > a) and (c+a > b):
    print("Valores formam triângulo:", a, b, c)
else:
    print("Valores não formam triângulo:", a, b, c)<jupyter_output>Valores formam triângulo: 12 7 6<jupyter_text>ExercícioCrie variáveis para armazenar uma string, um número inteiro e um número de ponto flutuante. A var. string deve ser nomeada `cumprimento`  e deve conter as palavras `'boa tarde!'`. A var. do número de ponto flutuante deve ser denominada `peso` e deve conter o número 10.5, e a var. do número inteiro deve ser nomeada como `idade` e deve conter o valor 20. Depois de armazenar os valores mostre-os com a função `print()`.<jupyter_code>peso, cumprimento, idade = 10.5, "boa tarde!", 20
print(cumprimento, peso, idade)<jupyter_output>boa tarde! 10.5 20<jupyter_text>4. Erros Previsíveis (Exceções)Sempre que possível devemos tratar os erros previsíveis do nosso código, recuperar da situação de parada do *script*. Vimos um exemplo que determinou se um dado valor numérico era par ou ímpar, no qual usamos a função de entrada de dados `input()`, a qual sempre retorna o valor digitado em forma de string, e por isso, usamos outra função `int()` para converter a string num valor numérico inteiro.  O que acontece se o usuário não perceber a indicação de entrada de um valor numérico e fornecer um valor não numérico?<jupyter_code>x = int(input("Digite um valor numérico inteiro:"))
print(x)<jupyter_output>Digite um valor numérico inteiro:Como assim?<jupyter_text>Se esse código for colocado num programa em Python (*script*) e esse erro ocorrer, seu programa para imediatamente com uma mensagem de rastreamento (*Traceback*) indicando o ponto do programa no qual o tal erro ocorreu. Isso faz com que os próximos comandos do seu programa não sejam executados.Exemplo: Conversão de temperatura em Fahrenheit para Celsius.<jupyter_code>entrada = input('Entre a Temperatura em Fahrenheit: ')
print(type(entrada), entrada)
temperF = float(entrada)
temperC = (temperF - 32.0)*5/9
print("Fahrenheit:", temperF, "Celsius:", temperC)<jupyter_output>Entre a Temperatura em Fahrenheit: 22
<class 'str'> 22
Fahrenheit: 22.0 Celsius: -5.555555555555555<jupyter_text>Se o usuário entrar um valor não numérico:<jupyter_code>entrada = input('Entre a Temperatura em Fahrenheit: ')
temperF = float(entrada)
temperC = (temperF - 32.0)*5/9
print("Fahrenheit:", temperF, "Celsius:", temperC)<jupyter_output>Entre a Temperatura em Fahrenheit:  muito quente!<jupyter_text>4.1 Try/ExceptTrata-se de uma estrutura de execução condicional do Python que trata os erros previsíveis. A ideia é prever que uma sequência de instruções pode ter um problema e adicionar comandos para serem executados caso um desses erros previsíveis ocorra. Esses comandos extra, localizados no bloco `except` serão ignorados se não houver erro na instrução depois do `try:`.  Sintaxe:``` pythontry:    comando_perigosoexcept :    comando_recuperacao```<jupyter_code>entrada = input('Entre a Temperatura em Fahrenheit: ')
try:
    temperF = float(entrada)
    temperC = (temperF - 32.0)*5/9
    print("Fahrenheit:", temperF, "Celsius:", temperC)
except Exception as e:
    print(f"Favor digitar um valor numérico! \nErro: {e}")<jupyter_output>Entre a Temperatura em Fahrenheit: re
Favor digitar um valor numérico! 
Erro: could not convert string to float: 're'<jupyter_text>Exercício (desafio)Crie um script que continue a solicitar a temperatura em Fahrenheit até que o usuário informe um valor numérico, considerando o exemplo anterior.<jupyter_code># Solução
temperF = None
while type(temperF) != float:
    entrada = input('Entre a Temperatura em Fahrenheit: ')
    try:
        temperF = float(entrada)
    except:
        print("Favor digitar um valor numérico!")
temperC = (temperF - 32.0)*5/9
print("Fahrenheit:", temperF, "Celsius:", temperC)<jupyter_output>Entre a Temperatura em Fahrenheit: só o valor, ou a unidade tbm?
Favor digitar um valor numérico!
Entre a Temperatura em Fahrenheit: 45
Fahrenheit: 45.0 Celsius: 7.222222222222222
{'fraction_non_alphanumeric': 0.1053557958259995, 'fraction_numerical': 0.02765903947699271, 'mean_word_length': 3.2538324420677363, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 58, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 4, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '13', 'dir': 'jupyter-structured-clean-dedup', 'id': '529504', 'license': 'Apache-2.0', 'n_tokens_mistral': 4476, 'n_tokens_neox': 4251, 'n_words': 1468, 'path': 'notebooks/1_Basic/slides3_Condicional_Erros.ipynb', 'repo_name': 'kaw19/python', 'size': '11931'}