-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPy1.py
More file actions
474 lines (327 loc) · 14.8 KB
/
Copy pathPy1.py
File metadata and controls
474 lines (327 loc) · 14.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
import marimo
__generated_with = "0.23.6"
app = marimo.App()
@app.cell
def _():
import marimo as mo
return (mo,)
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
---
**Universidade da Costa Rica** | Escola de Engenharia Elétrica
*IE0405 - Modelos Probabilísticos de Sinais e Sistemas*
### `PyX` - Série de tutoriais em Python para análise de dados
# `Py1` - *Funções e bibliotecas padrão*
> Dentro das bibliotecas padrão do Python há ferramentas úteis para operações numéricas básicas, para o manuseio de arquivos como os que serão aplicados no curso e outras funções úteis para programação em geral.
*Fabián Abarca Calderón*
---
""")
return
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
## Funções, bibliotecas e métodos
Em programação, geralmente se aceita que "não há que reinventar a roda" e também que "não há que se repetir", e além disso que "é preciso mantê-lo simples". Para não esquecer isso, existem estes acrônimos:
* **DRY**, *don't repeat yourself*
* **KISS**, *keep it simple, stupid*
Uma forma de seguir estes bons conselhos é criando funções que são invocadas quando há tarefas repetitivas, e também utilizando peças de código ("bibliotecas") que já foram desenvolvidas para resolver aplicações específicas.
A existência de funções e bibliotecas (com seus módulos e métodos associados), desenvolvidas por uma imensa comunidade global, agrega muitas funcionalidades poderosas ao Python.
""")
return
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
---
## 1.1 - Funções
Em Python, a sintaxe para a criação de uma função é:
```python
def nome_da_funcao():
<ação da função>
```
""")
return
@app.cell
def _():
def soma(x, y):
z = x + y
return z
print(soma(1, 2))
return
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
## 1.2 - Bibliotecas, módulos, métodos e atributos
As bibliotecas são grupos de funções predefinidas, que podem ser importadas para o código em conjunto e utilizadas para realizar tarefas de forma mais simples, reduzindo assim o tamanho do código próprio e simplificando-o.
Para importá-las, utiliza-se
```python
import <libreria>
```
onde também se utiliza um "alias": um nome curto (bem curto, como `np` para `numpy`) para se referir a ele pelo resto do programa.
```python
import <libreria> as <alias>
```
Entretanto, em algumas ocasiões, não se deseja importar toda a biblioteca, mas apenas alguns componentes ou "módulos":
```python
from <libreria> import <modulo o metodo>
```
Depois de importá-las, seus atributos e métodos são chamados com a notação de ponto. Por exemplo, a função cosseno da biblioteca NumPy é `np.cos()` (um método) e o número $\pi$ é `np.pi` (um atributo). Se um método for importado diretamente, a notação de ponto não é necessária, por exemplo: `randint()` (uma função de `random`).
""")
return
@app.cell
def _():
import math
import numpy as np
from random import randint
from scipy.constants import c
print("4! =", math.factorial(4))
print("C/D =", np.pi)
print("Um número aleatório =", randint(50, 60))
print("Velocidade da luz =", c)
return (math,)
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
### 1.2.1 - Biblioteca `math`
Estas são funções matemáticas comuns. Há uma grande [variedade](https://docs.python.org/3/library/math.html), entre as quais se incluem:
##### Redondeo
* `math.ceil(x)`: retorna o "teto" de `x`, o menor inteiro maior ou igual a `x`.
* `math.floor(x)`: retorna o "piso" de `x`, o maior inteiro menor ou igual a `x`.
##### Análisis combinatorio
* `math.comb(n, k)`: retorna o coeficiente binomial $C(n,k)$, correspondente ao número de combinações de `k` elementos que podem ser obtidas de um grupo de `n` elementos, onde a **ordem não importa**.
$$
n \choose k
$$
* `math.perm(n, k)`: retorna o número de formas de escolher `k` elementos de `n` elementos sem repetição, onde a **ordem importa**.
##### Outras funções úteis
* `math.factorial(x)`: retorna o fatorial de `x`: $x!$.
* `math.pow(x, y)`: retorna o valor de $x^y$.
* `math.sqrt(x)`: retorna a raiz quadrada de `x`: $\sqrt{x}$.
* `math.erf(x)`: retorna o valor da função erro (a função de distribuição normal padrão) avaliada em `x`. Esta função será de grande utilidade neste curso.
""")
return
@app.cell
def _(math):
print(math.ceil(2.3))
print(math.floor(2.3))
print(math.erf(1.1))
return
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
### 1.2.2 - Biblioteca `random`
Geração de números pseudoaleatórios, com diferentes distribuições. Há uma grande [variedade](https://docs.python.org/3/library/random.html), entre as quais se incluem:
* `random.randint(a, b)`: retorna um número aleatório inteiro entre `a` e `b` (intervalo fechado).
* `random.uniform(a, b)`: retorna um número aleatório em ponto flutuante para uma distribuição uniforme entre `a` e `b`.
* `random.sample(population, k)`: retorna uma lista com `k` amostras aleatórias retiradas da lista `population`.
* `random.expovariate(lambd)`: retorna um número aleatório em ponto flutuante para uma distribuição exponencial com parâmetro `lambd`.
* `random.gauss(mu, sigma)`: retorna um número aleatório (em ponto flutuante) para uma distribuição normal com média `mu` e desvio padrão `sigma`.
""")
return
@app.cell
def _():
import random as rd
print(rd.gauss(1, 3))
print(rd.randint(0, 100))
print(rd.uniform(0, 100))
return
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
### 1.2.3 - Biblioteca `statistics`
Ferramentas estatísticas para aplicar a um conjunto de dados. Há uma grande [variedade](https://docs.python.org/3/library/statistics.html), entre as quais se incluem:
* `statistics.mean(data)`: retorna o valor esperado de um conjunto de dados `data`.
* `statistics.pstdev(data)`: retorna o desvio padrão populacional do conjunto de dados `data`.
* `statistics.stdev(data)`: retorna o desvio padrão amostral do conjunto de dados `data`.
* `statistics.pvariance(data)`: retorna a variância populacional do conjunto de dados `data`.
* `statistics.variance(data)`: retorna a variância amostral do conjunto de dados `data`.
Entre outras. Consulte a documentação anexa.
""")
return
@app.cell
def _():
import statistics
data = range(1, 60)
print(statistics.mean(data))
print(statistics.variance(data))
return
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
### 1.2.4 - Biblioteca `collections`
Apresenta alternativas às listas, sets, tuplas e dicionários incluídos no Python por padrão. Inclui diferentes estruturas para armazenar e manipular dados, definidas por classes, cada uma com seus métodos específicos. Há uma grande [variedade](https://docs.python.org/3/library/collections.html), entre as quais se incluem:
* `collections.deque`: adiciona funcionalidades a uma lista convencional, como `pop` e `append`.
* `collections.OrderedDict`: dicionário que registra a ordem em que os objetos foram adicionados.
* `collections.UserString`: adiciona funcionalidades para o manejo de objetos do tipo `String`.
""")
return
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
A seguir, há um exemplo para a solução "elegante" de um problema comum.
> Qual é a probabilidade de que, ao lançar dois dados, a soma dos dados seja 7? [2]
(O resultado é fácil de deduzir: de 36 combinações possíveis, seis somam sete (1 + 6, 2 + 5, 3 + 4, 4 + 3, 5 + 2, 6 + 1), então 6/36 = 1/6 $\approx$ 0.16667).
Primeiro, o objeto `defaultdict` do [módulo](https://docs.python.org/2/library/collections.html) `collections` cria dicionários com valores padrão quando encontra uma nova chave. Seu uso prático é o de **"dicionário preenchível"**.
""")
return
@app.cell
def _():
from collections import defaultdict
return (defaultdict,)
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
Agora, é possível criar um dicionário com todas as combinações possíveis e a soma de cada uma, com um duplo laço `for`:
""")
return
@app.cell
def _():
d = {(i, j): i + j for i in range(1, 7) for j in range(1, 7)}
print(d)
return (d,)
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
Em seguida, cria-se um `defaultdict` vazio. Isso implica que, mais adiante, se uma chave não for encontrada no dicionário, em vez de um `KeyError` será criada uma nova entrada (um novo `key:value`).
""")
return
@app.cell
def _(defaultdict):
dinv = defaultdict(list)
print(dinv)
return (dinv,)
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
É possível extrair do dicionário as combinações que somam 7. O método `.items()` gera uma lista de pares de "tuplas" (uma tupla é um conjunto ordenado e imutável de elementos) a partir do dicionário de combinações criado em `d`. "Preenchemos" o `defaultdict` com os elementos do dicionário criado anteriormente e o método `.append()`, isso com um laço `for` em que os índices `i,j` representam os pares de combinações e sua soma. A vantagem é que agora estão todos agrupados.
""")
return
@app.cell
def _(d, dinv):
print("Antes...\n")
print(d.items())
for i, j in d.items():
dinv[j].append(i)
print("\nDespués...")
dinv
return
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
O `for` anterior pode ser lido como: "para cada par na lista de itens, na posição `j` (a soma das combinações) adicione a combinação correspondente (em `i`)".
Extraímos os pares que somam sete e obtemos a quantidade deles.
""")
return
@app.cell
def _(dinv):
print("Combinaciones que suman 7:", dinv[7])
print("Elementos:", len(dinv[7]))
return
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
Por fim, e de forma mais geral, obtém-se a probabilidade para todas as somas na forma de um único dicionário:
""")
return
@app.cell
def _(dinv):
probabilidades = {i: len(j) / 36 for i, j in dinv.items()}
print("O vetor de probabilidades das somas é =", probabilidades)
print("A probabilidade de a soma ser 7 é =", probabilidades[7])
return
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
### 1.2.5 - Biblioteca `csv`
Esta biblioteca implementa classes para o manejo de arquivos do tipo CSV (*Comma Separated Values*), com atividades típicas como *ler* dados de e *escrever* dados em um arquivo CSV ou outros similares.
Entre suas funções estão:
* `csv.reader(csvfile, dialect='excel', **fmtparams)`: cria um objeto do tipo `reader` com os dados do arquivo `csvfile` para o "dialeto" (formato) especificado. `fmtparams` são "parâmetros de formato" adicionais para modificar a configuração do formato.
* `csv.writer(csvfile, dialect='excel', **fmtparams)`: cria um objeto do tipo `writer` para escrever dados no arquivo `csvfile` com o "dialeto" (formato) especificado. `fmtparams` são "parâmetros de formato" adicionais para modificar a configuração do formato.
A [documentação](https://docs.python.org/3/library/csv.html) completa tem todos os detalhes.
""")
return
@app.cell
def _():
import csv
unos = [1] * 10
with open("unos.csv", "w", newline="") as archivo:
escribir = csv.writer(archivo)
escribir.writerow(unos)
return
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
### 1.2.6 - Biblioteca `os`
Permite manipular arquivos e caminhos do sistema operacional como se fossem comandos no terminal. A lista completa de funções é apresentada na [documentação](https://docs.python.org/3/library/os.html). Os métodos mais importantes são:
* `os.getcwd()`: retorna o diretório de trabalho atual.
* `os.chdir(path)`: altera o diretório de trabalho para o especificado por `path`.
* `os.path` é um módulo para manipulação de endereços (caminhos) do sistema.
""")
return
@app.cell
def _():
import os
print(os.getcwd())
return
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
### 1.2.7 - Outras bibliotecas
#### 1.2.7.1 - Biblioteca `datetime`
Apresenta classes para manipulação de datas e tempo. Tem dois módulos: `calendar` e `time`, cada um com suas funções, e permitem gerar informações como a data e hora atuais, o fuso horário, entre outras. A documentação completa está [aqui](https://docs.python.org/3/library/datetime.html) e há excelentes exemplos no [Programiz](https://www.programiz.com/python-programming/datetime).
""")
return
@app.cell
def _():
import datetime
_ahora = datetime.datetime.now()
print(_ahora)
print(_ahora.month)
return (datetime,)
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
#### 1.2.7.2 - Módulo `calendar`
Apresenta uma classe `Calendar` que permite criar objetos que representem calendários e inclui métodos para manipulá-los. A documentação completa está [aqui](https://docs.python.org/3/library/calendar.html).
""")
return
@app.cell
def _(datetime):
import calendar
_ahora = datetime.datetime.now()
es_bisiesto = calendar.isleap(_ahora.year)
calendario = calendar.month(_ahora.year, _ahora.month)
print("Ano bissexto:", es_bisiesto)
print(calendario)
return
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
---
## 1.3 - Como criar uma biblioteca própria?
Uma biblioteca consiste simplesmente em uma série de arquivos de código (extensão `.py`) com definições das funções a serem utilizadas. Depois de importar a biblioteca para um código, essas funções podem ser acessadas e utilizadas. Os arquivos da biblioteca podem ser distribuídos de forma hierárquica, tendo assim "subbibliotecas" e permitindo classificar as funções.
Para criar um pacote são necessários dois elementos:
* Todos os arquivos `.py` com as funções em uma única pasta, com o nome da biblioteca
* Um arquivo `__init__.py` (que normalmente é deixado vazio) para que o interpretador identifique a pasta como uma biblioteca
Há muitos [recursos](https://www.tutorialsteacher.com/python/python-package) on-line que explicam e exemplificam este procedimento.
""")
return
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
---
### Mais informações
* [Documentação oficial do Python](https://docs.python.org/3/)
""")
return
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
---
**Universidade da Costa Rica** | Faculdade de Engenharia | Escola de Engenharia Elétrica
© 2021
---
""")
return
if __name__ == "__main__":
app.run()