CS50 : Semana 6 | Lab: Copa do Mundo
Tags: braziliandevs, python, cs50
Published: 2023-05-05 19:29:20

Retornando após uma pausa na escrita, a última vez que escrevi sobre o CS50 foi para o desáfio de pluralidade da Semana 3.

Eu vi que neste ano, o curso adicionou uns laboratórios muito interessantes para se fazer, e vou buscar realizar eles e trazer para cá.

## Semana 6: Python

A semana 6 é bem interessante, o curso introduz a **linguagem dinâmica** *Python* e refaz uma releitura de todo o curso, só que agora, nesta nova linguagem.

Trata as dificuldades antes enfrentadas na **linguagem C** e escancara as facilidades que uma linguagem como Python oferece, mas é claro **apresenta o trade-off**.

Ao final, apresentam-se duas modalidades de atividades:
- Lab: Uma atividade que, em tese, é esperado que se faça junto com um ou dois amigos. **Vamos tratar deste laboratório nesta postagem**.

- Problem Sets: Série de atividades com dois níveis de dificuldades. Nesta semana em específico, é refazer os mesmos desafios feitos em C, só que agora em Python.

> Como eu já falei destes exercícios em C, no momento não planejo traze-los aqui em Python, mas se tiver alguma dúvida, é só falar.

## Laboratório: Copa do Mundo

Eu achei essa atividade muito legal, é para rodar simulações da Copa do Mundo.

- Existem duas planilhas `.csv` com duas colunas (seleções, ratings).
- Fará a simulação usando conceitos de `funções`, `leitura de arquivos`, manipulação de `listas` e `dicionários`, e todos os outros blocos fundamentais de programação

O resultado esperado é um **output** como este informando a probabilidade da equipe ser campeã.
```bash
$ python tournament.py 2018m.csv
Belgium: 20.9% chance of winning
Brazil: 20.3% chance of winning
Portugal: 14.5% chance of winning
Spain: 13.6% chance of winning
Switzerland: 10.5% chance of winning
Argentina: 6.5% chance of winning
England: 3.7% chance of winning
France: 3.3% chance of winning
Denmark: 2.2% chance of winning
Croatia: 2.0% chance of winning
Colombia: 1.8% chance of winning
Sweden: 0.5% chance of winning
Uruguay: 0.1% chance of winning
Mexico: 0.1% chance of winning
```

## Detalhes da Implementação

Seguindo exatamente as etapas de implementação oferecida pelo [site do cs50](https://cs50.harvard.edu/x/2023/labs/6/). 

**PRIMEIRA ETAPA**. Primeiro, na **main**, leia as informações sobre as seleções no **arquivo `csv`** para a memória do seu programa (*armazenar em uma variável*) e adicione cada time a sua **lista** times.

```python
def main():
    # Ensure correct usage
    if len(sys.argv) != 2:
        sys.exit("Usage: python tournament.py FILENAME")
    teams = []
    # TODO: Read teams into memory from file
    counts = {}
    # TODO: Simulate N tournaments and keep track of win counts
    # Print each team's chances of winning, according to simulation
    for team in sorted(counts, key=lambda team: counts[team], reverse=True):
        print(f"{team}: {counts[team] * 100 / N:.1f}% chance of winning")
```

- Podemos notar que é esperado que se passe na **linha de comando** dois argumento, sendo um deles o **arquivo `.csv`**.
- Será **lido** esse arquivo, no **modo leitura**.
- Para cada linha, vamos criar um par **key:value** onde teremos uma seleção e seu respectivo *rating* (nota)
- Para cada par criado, vamos **adicionar** na **lista `teams`**.

```python
teams = []
    # TODO: Read teams into memory from file
    with open(sys.argv[1], "r") as csvfile:
        reader = csv.DictReader(csvfile)
        for row in reader:
            team = {"team": row["team"], "rating": int(row["rating"])}
            teams += [team] #append each team in csv in teams list
```

**SEGUNDA ETAPA**. Em seguida, **implementar a função `simulate_tournament`**. Essa função vai **receber como parâmetro** a lista com as equipes e **simulará rodadas** até que **sobre apenas uma equipe**. Essa função **deve retornar o nome desta equipe**.

```python
def simulate_tournament(teams):
    """Simulate a tournament. Return name of winning team."""
    # TODO
```

- Já **existe uma função `simulate_round(teams)`** que simula as rodadas.
- A minha lógica diz que, simular rodadas até que sobre apenas uma equipe, ou seja, até que o **tamanho** desta lista seja de **apenas uma equipe**.

```python
def simulate_tournament(teams):
    """Simulate a tournament. Return name of winning team."""
    # TODO
    while len(teams) != 1:
        teams = simulate_round(teams)

    return teams
```
**TERCEIRA ETAPA**. Retorne a **função main**, rode a **`simulate_tournament`** N vezes, e mantenha um registro de **quantas vezes** cada equipe **ganhou** dentro de um **`dicionário` chamado counts**.

```python
counts = {}
    # TODO: Simulate N tournaments and keep track of win counts
```
- Será **realizado `loops`** N vezes **chamando a função `simulate_tournament`**.
- A **função `simulate_tournament`** retorna uma lista neste formato:
```json
[{'team': Brazil, 'rating': 1384}]
```
- Usando uma conotação para extrair apenas o **valor** da chave `team`, **verificamos** se o **`dicionário` counts** já contêm esta equipe.
- Se existir, soma-se 1 (um). Se não, adiciona-se esta equipe ao dicionário de contagens.
```python
counts = {}
    # TODO: Simulate N tournaments and keep track of win counts
    for i in range(N):
        winner = simulate_tournament(teams)
        print(winner[0]["team"])
        if winner[0]["team"] not in counts:
            counts.update({winner[0]["team"]: 1})
        else:
            counts[winner[0]["team"]] += 1
```
Assim está terminado o desafio.

## Conclusão

Este exercicio de laboratório foi muito divertido de se fazer, e pelas possibilidades de poder ensaiar confrontos para outras modalidades e competições que você queira utilizar.

Considero este laboratório muito bom para aprender e praticar os conceitos fundamentais da *linguagem python*.

Se estiver com dúvidas, ou caso tenha gostado.
Deixe seu comentário aí embaixo, e me adicione nas redes.

Github: [repositório da atividade](https://github.com/mpfdev/cs50/tree/main/week6/lab6) | [mpfdev (pessoal)](https://github.com/mpfdev)