Funções

Função é uma sequência de instruções que executa uma operação de computação. Ao definir uma função, você especifica o nome e a sequência de instruções. Depois, pode utilizar (“chamar”) a função pelo nome.

A ideia é similar às funções matemáticas! Mas funções em uma linguagem de programação não realizam necessariamente apenas cálculos.

Vimos o type(), um exemplo de função:

>>> type(23)
<class 'int'>

>>> type('textinho')
<class 'str'>

Definindo funções

Se quisermos uma função que ainda não existe em Python, temos que definí-la.

Criando uma função simples:

def NOME_DA_FUNÇÃO(LISTA DE PARÂMETROS):
    COMANDOS

Aviso

Coloque os dois pontos após definir a função!

Nota

Faça a indentação nas linhas abaixo da definição da função!

>>> def soma():
...     print(1 + 1)
...
>>> soma()
2

>>> def soma():
...     return 1 + 1
...
>>> soma()
2

Qual a diferença entre utilizar print() e return() aqui em cima?!?

>>> def imprime_letra():
...     print("If you didn't care what happened to me. And I didn't care for you")
...
>>> imprime_letra()
If you didn't care what happened to me. And I didn't care for you

>>> type(imprime_letra)
<class 'function'>

>>> def repete_letra():
...     imprime_letra()
...     imprime_letra()
...
>>> repete_letra()
If you didn't care what happened to me. And I didn't care for you
If you didn't care what happened to me. And I didn't care for you

Funções com argumentos

Queremos somar 3 com um número qualquer que insiro na função. Bora lá:

>>> def soma_valor(x):
...     return 3 + x
...
>>> soma_valor(5)
8

>>> z = soma_valor(10)
>>> z
13

Que sem graça! Quero somar dois números quaisquer!

>>> def soma_dois_numeros(x, y):
...     return x + y
...
>>> soma_dois_numeros(7, 4)
11

Tenho dificuldade com a tabuada do 7! Ajude-me!

>>> def tabuada_do_7():
...     for i in range(11):
...         print (7 * i)
...
>>> tabuada_do_7()
0
7
14
21
28
35
42
49
56
63
70

Mai tá legal isso! Quero a tabuada do 1 ao 10 agora! Bora!

>>> def tabuadas():
...     for i in range(1, 11):
...         for j in range(1, 11):
...             print("{} * {} = {}".format(i, j, i * j))
...
>>> tabuadas()
1 * 1 = 1
1 * 2 = 2
1 * 3 = 3
1 * 4 = 4
1 * 5 = 5
1 * 6 = 6
1 * 7 = 7
1 * 8 = 8
1 * 9 = 9
1 * 10 = 10
2 * 1 = 2
2 * 2 = 4
2 * 3 = 6
2 * 4 = 8
2 * 5 = 10
2 * 6 = 12
2 * 7 = 14
2 * 8 = 16
2 * 9 = 18
2 * 10 = 20
3 * 1 = 3
3 * 2 = 6
3 * 3 = 9
3 * 4 = 12
3 * 5 = 15
3 * 6 = 18
3 * 7 = 21
3 * 8 = 24
3 * 9 = 27
3 * 10 = 30
4 * 1 = 4
4 * 2 = 8
4 * 3 = 12
4 * 4 = 16
4 * 5 = 20
4 * 6 = 24
4 * 7 = 28
4 * 8 = 32
4 * 9 = 36
4 * 10 = 40
5 * 1 = 5
5 * 2 = 10
5 * 3 = 15
5 * 4 = 20
5 * 5 = 25
5 * 6 = 30
5 * 7 = 35
5 * 8 = 40
5 * 9 = 45
5 * 10 = 50
6 * 1 = 6
6 * 2 = 12
6 * 3 = 18
6 * 4 = 24
6 * 5 = 30
6 * 6 = 36
6 * 7 = 42
6 * 8 = 48
6 * 9 = 54
6 * 10 = 60
7 * 1 = 7
7 * 2 = 14
7 * 3 = 21
7 * 4 = 28
7 * 5 = 35
7 * 6 = 42
7 * 7 = 49
7 * 8 = 56
7 * 9 = 63
7 * 10 = 70
8 * 1 = 8
8 * 2 = 16
8 * 3 = 24
8 * 4 = 32
8 * 5 = 40
8 * 6 = 48
8 * 7 = 56
8 * 8 = 64
8 * 9 = 72
8 * 10 = 80
9 * 1 = 9
9 * 2 = 18
9 * 3 = 27
9 * 4 = 36
9 * 5 = 45
9 * 6 = 54
9 * 7 = 63
9 * 8 = 72
9 * 9 = 81
9 * 10 = 90
10 * 1 = 10
10 * 2 = 20
10 * 3 = 30
10 * 4 = 40
10 * 5 = 50
10 * 6 = 60
10 * 7 = 70
10 * 8 = 80
10 * 9 = 90
10 * 10 = 100

Exercícios

  1. Faça uma função que determina se um número é par ou ímpar. Use o % para determinar o resto de uma divisão. Por exemplo: 3 % 2 = 1 e 4 % 2 = 0

  2. Faça uma função que calcule a área de um círculo. Insira o raio como argumento.

    Dica: faça a importação de math e use \(\pi\) de lá.

    \[A = \pi R^2\]
  3. Crie uma função que receba um valor de temperatura em Fahrenheit e transforme em Celsius.

    Relembrar é viver:

    \[\frac{C}{5} = \frac{F - 32}{9}\]
  4. Alanderson quer saber se um endereço IP é válido. Faça um programa para ajudar Alanderson a testar se um endereço é válido.

    Para isso, a entrada deve ser um endereço IP (digitado pelo usuário) e o programa deve escrever na tela se é válido ou não. Um endereço IPv4 é composto por 4 números inteiros entre 0 e 255, separados por um ponto.

    Por exemplo, o endereço 123.123.123.123 é válido, mas 666.123.k.3 não é.

  5. Crie uma função que receba 3 valores e calcula as raízes da fórmula de Bhāskara.

    \[x = \frac{-b \pm \sqrt{b^2 - 4 \cdot a \cdot c}}{2 \cdot a}\]

    Dica: raiz quadrada é sqrt(), importando math: math.sqrt()

    Faça um teste com bhaskara(1, -4, -5) e o programa deve obter as raízes: (5.0, -1.0)

  6. Dada a função: \(y = 5x + 2\), determine os valores de \(y\) para \(x\) entre -10 a +10, onde \(x\) é inteiro

  7. Escreva uma função chamada has_duplicates que tome uma lista e retorne True se houver algum elemento que apareça mais de uma vez. Ela não deve modificar a lista original.

  8. Duas palavras são um “par inverso” se uma for o contrário da outra. Escreva uma função que dado duas palavras, retorne True caso sejam.

  9. Escreva uma função que imprime todos os números primos entre 1 e 50

    Dica: um número é primo se ele for divisível apenas por 1 e ele mesmo, use o operador % (resto da divisão) para isso.

  10. Duas palavras são anagramas se você puder soletrar uma rearranjando as letras da outra. Escreva uma função chamada is_anagram que tome duas strings e retorne True se forem anagramas ou False caso contrário.

  11. Escreva uma função que dado um número, calcule o fatorial desse número. Por exemplo, fatorial de 5:

    \[5! = 5 \cdot 4 \cdot 3 \cdot 2 \cdot 1 = 120\]
  12. Crie uma função que aproxima a função matemática seno, utilizando a seguinte equação:

    \[\sin(x) = \sum_{n=0}^{\infty} \frac{(-1)^n}{(2n+1)!} x^{2n+1}\]

    Essa é a expansão em Série de Taylor da função. Note que esta é uma série infinita! A sua função deve truncar a série em algum momento, ou seja, sua função vai calcular uma aproximação para o seno de um ângulo:

    \[\sin(x) \approx \sum_{n=0}^{N} \frac{(-1)^n}{(2n+1)!} x^{2n+1} = \sum_{n=0}^{N} a_n = S_N\]

    Note que, quanto maior o valor de N, melhor é a aproximação. Mas isso tem um custo: maior vai ser o número de termos nessa série e consequentemente, maior o tempo de execução desse código.

    Uma possibilidade é estipular previamente uma precisão a ser atingida pelo código. Ou seja, definimos o desvio máximo \(\epsilon\) que nossa aproximação tem com relação ao valor exato! Isso é feito comparando dois termos consecutivos da série: se a diferença \(\delta\) entre eles (em valor absoluto!) for menor que \(\epsilon\), atingimos a precisão desejada:

    \[\delta = | S_N - S_{N-1} |\]

    Implemente, então, uma função que receba como argumentos:

    • \(x\): o ângulo (em radianos!!).
    • \(N_\mathrm{max}\): o número máximo de iterações.
    • \(\epsilon\): a precisão da aproximação.

    e calcule uma aproximação para \(\sin(x)\) usando duas condições de parada: número máximo de termos na série é \(N_\mathrm{max}\) e precisão \(\epsilon\). Ou seja, sua aproximação terá no máximo \(N_\mathrm{max}\) termos, mas pode ter menos termos caso a precisão desejada seja atingida ( \(\delta < \epsilon\)).

  13. Calcule \(\pi\) usando um método de Monte Carlo.

    Monte Carlo é uma classe de métodos para resolver problemas usando estatística. Aqui você vai implementar uma função usando um desses algoritmos para calcular o número \(\pi\).

    Dado um círculo de raio \(R\) dentro de um quadrado de lados \(2R\), a razão entre a área do círculo para a área do quadrado é:

    \[\frac{A_\bigcirc}{A_\square} = \frac{\pi R^2}{4 R^2} = \frac{\pi}{4}\]

    Ou seja, se você escolher aleatoriamente um ponto dentro do quadrado, a probabilidade dele cair dentro do círculo é de \(\pi / 4\). Se você escolher \(N\) pontos aleatórios dentro do quadrado, cerca de \(N \pi / 4\) estarão dentro do círculo.

    Então, basta escolher pontos aleatórios dentro do quadrado e ver se estão dentro do círculo

    Um ponto \((x, y)\) está dentro do círculo se \(x^2 + y^2 \leq R^2\).

    Faça uma função que receba como argumento um número \(N\) de pontos \((x, y)\) (aleatórios) a serem sorteados. Dentro dessa função, você deve fazer um laço que sorteie esses \(N\) pontos e veja quantos estão dentro do círculo. Se \(M\) pontos caírem dentro do círculo, então a probabilidade de um ponto aleatório estar dentro do círculo é aproximadamente \(M / N\). Então, podemos estimar \(\pi\) como:

    \[\pi \approx \frac{4 M}{N}\]

    Para sortear um número aleatório entre \(a\) e \(b\) utilize a função uniform(a, b) do módulo random. Exemplo:

    >>> import random
    >>> random.uniform(1, 2) # número aleatório entre 1 e 2
    1.8740445361226983
    

    Perceba que ao executar a função pi() várias vezes seguidas, o resultado é sempre diferente. Então faça um laço para calcular pi() \(K\) vezes, salve os resultados em uma lista e calcule o valor médio e o desvio padrão.