Percursos
/
Python
Python
/
Exercícios
/
Passar de ano
Passar de ano

Passar de ano

Exercício de aprendizagem

Introdução

O Python tem duas construções para criar ciclos. Os ciclos while servem para iteração indefinida (não contada) e os ciclos for para iteração definida (contada). As palavras-chave break, continue e else ajudam a personalizar o comportamento dos ciclos. range() e enumerate() ajudam na contagem e na indexação dos ciclos.

While

Os ciclos while continuam a executar-se enquanto a loop expression ou «teste» for avaliada como True num boolean context, e terminam quando for avaliada como False:


# Lists are considered "truthy" in a boolean context if they
# contain one or more values, and "falsy" if they are empty.

>>> placeholders = ["spam", "ham", "eggs", "green_spam", "green_ham", "green_eggs"]

>>> while placeholders:
...     print(placeholders.pop(0))
...
'spam'
'ham'
'eggs'
'green_spam'
'green_ham'
'green_eggs'

For

O for loop básico do Python é mais bem descrito como um for each, que percorre os valores de qualquer objeto iterável, terminando quando não há valores devolvidos ao chamar next():


>>> word_list = ["bird", "chicken", "barrel", "bongo"]

>>> for word in word_list:
...    if word.startswith("b"):
...        print(f"{word.title()} starts with a B.")
...    else:
...        print(f"{word.title()} doesn't start with a B.")
...
'Bird starts with a B.'
'Chicken doesn\'t start with a B.'
'Barrel starts with a B.'
'Bongo starts with a B.'

O objeto sequência range()

Quando não é dado um iterable específico, usa-se a sequência especial range() como contador do ciclo. range() exige um int que define o stop da sequência, e pode opcionalmente receber os parâmetros start e step. Se não for indicado nenhum número start, a sequência começa em 0. Os objetos range() são lazy (os valores são gerados a pedido), suportam todas as operações comuns de sequência e ocupam uma quantidade fixa de memória, independentemente do comprimento da sequência especificada.

# Here we use range to produce some numbers, rather than creating a list of them in memory.
# The values will start with 1 and stop *before* 7

>>> for number in range(1, 7):
...    if number % 2 == 0:
...       print(f"{number} is even.")
...    else:
...       print(f"{number} is odd.")
'1 is odd.'
'2 is even.'
'3 is odd.'
'4 is even.'
'5 is odd.'
'6 is even.'

# range() can also take a *step* parameter.
# Here we use range to produce only the "odd" numbers, starting with 3 and stopping *before* 15.

>>> for number in range(3, 15, 2):
...    if number % 2 == 0:
...       print(f"{number} is even.")
...    else:
...       print(f"{number} is odd.")
...
'3 is odd.'
'5 is odd.'
'7 is odd.'
'9 is odd.'
'11 is odd.'
'13 is odd.'

Valores e índices com enumerate()

Se precisares tanto dos valores como dos seus índices, a função incorporada enumerate(<iterable>) devolve pares (index, value):


>>> word_list = ["bird", "chicken", "barrel", "apple"]

# *index* and *word* are the loop variables.
# Loop variables can be any valid python name.

>>> for index, word in enumerate(word_list):
...    if word.startswith("b"):
...        print(f"{word.title()} (at index {index}) starts with a B.")
...    else:
...        print(f"{word.title()} (at index {index}) doesn't start with a B.")
...
'Bird (at index 0) starts with a B.'
'Chicken (at index 1) doesn\'t start with a B.'
'Barrel (at index 2) starts with a B.'
'Apple (at index 3) doesn\'t start with a B.'


# The same method can be used as a "lookup" for pairing items between two lists.
# Of course, if the lengths or indexes don't line up, this doesn't work.

>>> word_list = ["cat", "chicken", "barrel", "apple", "spinach"]
>>> category_list = ["mammal", "bird", "thing", "fruit", "vegetable"]

>>> for index, word in enumerate(word_list):
...    print(f"{word.title()} is in category: {category_list[index]}.")
...
'Cat is in category: mammal.'
'Chicken is in category: bird.'
'Barrel is in category: thing.'
'Apple is in category: fruit.'
'Spinach is in category: vegetable.'

Alterar o comportamento dos ciclos

A palavra-chave continue pode ser usada para saltar para o ciclo de iteração seguinte:

word_list = ["bird", "chicken", "barrel", "bongo", "sliver", "apple", "bear"]

# This will skip *bird*, at index 0
for index, word in enumerate(word_list):
    if index == 0:
        continue
    if word.startswith("b"):
        print(f"{word.title()} (at index {index}) starts with a b.")

'Barrel (at index 2) starts with a b.'
'Bongo (at index 3) starts with a b.'
'Bear (at index 6) starts with a b.'

A palavra-chave break (como em muitas linguagens relacionadas com o C) pode ser usada para parar a iteração e «sair» do loop mais interior que a envolve:

>>>  word_list = ["bird", "chicken", "barrel", "bongo", "sliver", "apple"]

>>> for index, word in enumerate(word_list):
...    if word.startswith("b"):
...        print(f"{word.title()} (at index {index}) starts with a B.")
...    elif word == "sliver":
...       break
...    else:
...       print(f"{word.title()} doesn't start with a B.")
... print("loop broken.")
...
'Bird (at index 0) starts with a B.'
'Chicken doesn\'t start with a B.'
'Barrel (at index 2) starts with a B.'
'Bongo (at index 3) starts with a B.'
'loop broken.'

Instruções

És assistente de ensino e estás a corrigir exames de alunos. Manter o registo dos resultados manualmente está a tornar-se aborrecido e propenso a erros. Decides tornar as coisas um pouco mais interessantes criando algumas funções para contar e calcular os resultados da turma.

1. Arredondar as notas

Embora possas dar "pontuação parcial" às questões do exame, as notas finais do exame têm de ser ints. Por isso, antes de fazeres mais alguma coisa com as notas da turma, tens de percorrer as notas e converter as notas de float em ints. Felizmente para ti, o Python tem a função integrada round() que podes usar.

Cria a função round_scores(student_scores), que recebe uma list de student_scores. Esta função deve consumir a list de entrada e return uma nova lista com todas as notas convertidas em ints. A ordem das notas na list resultante não é importante.

>>> student_scores = [90.33, 40.5, 55.44, 70.05, 30.55, 25.45, 80.45, 95.3, 38.7, 40.3]
>>> round_scores(student_scores)
...
[40, 39, 95, 80, 25, 31, 70, 55, 40, 90]

2. Alunos sem nota positiva

Enquanto corrigias o exame, reparaste que alguns alunos não estavam a ter um desempenho tão bom como esperavas. Mas distraíste-te e esqueceste-te de anotar exatamente quantos alunos.

Cria a função count_failed_students(student_scores), que recebe uma list de student_scores. Esta função deve contar o número de alunos que não têm nota positiva e devolver essa contagem como um número inteiro. Para ter nota positiva no exame, um aluno precisa de uma nota superior a 40.

>>> count_failed_students(student_scores=[90,40,55,70,30,25,80,95,38,40])
5

3. Os "melhores"

O professor a quem estás a dar assistência quer encontrar o grupo de alunos que teve o melhor desempenho neste exame. O que conta como "melhor" varia, por isso tens de encontrar as notas que sejam maiores ou iguais ao limiar atual.

Cria a função above_threshold(student_scores, threshold), que recebe student_scores (uma list de notas) e threshold (o limiar da "nota mais alta") como parâmetros. Esta função deve devolver uma list com todas as notas que sejam >= a threshold.

>>> above_threshold(student_scores=[90,40,55,70,30,68,70,75,83,96], threshold=75)
[90,75,83,96]

4. Calcular as notas com letras

O professor a quem estás a dar assistência gosta de atribuir notas com letras, além de notas numéricas. Como é raro os alunos tirarem 100 num exame, os limiares inferiores das "notas com letras" são calculados com base na nota mais alta obtida e aumentam de forma uniforme entre a nota mais alta e o limiar de reprovação de <= 40.

Cria a função letter_grades(highest), que recebe a nota "mais alta" do exame como argumento e devolve uma list de limiares inferiores de notas para cada intervalo de notas "ao estilo americano": ["D", "C", "B", "A"].

"""Where the highest score is 100, and failing is <= 40.
       "F" <= 40
 41 <= "D" <= 55
 56 <= "C" <= 70
 71 <= "B" <= 85
 86 <= "A" <= 100
"""

>>> letter_grades(highest=100)
[41, 56, 71, 86]


"""Where the highest score is 88, and failing is <= 40.
       "F" <= 40
 41 <= "D" <= 52
 53 <= "C" <= 64
 65 <= "B" <= 76
 77 <= "A" <= 88
"""

>>> letter_grades(highest=88)
[41, 53, 65, 77]

5. Associar nomes a notas

Tens uma lista de notas de exame por ordem decrescente e outra lista com os nomes dos alunos, também ordenada por ordem decrescente das respetivas notas. Gostarias de associar cada nome de aluno à sua nota e imprimir a classificação geral da turma.

Cria a função student_ranking(student_scores, student_names), com os parâmetros student_scores e student_names. Associa cada nome de aluno da list student_names à respetiva nota da list student_scores. Podes assumir que cada list de argumentos estará ordenada da nota mais alta para a mais baixa. A função deve devolver uma list de strings com o formato <rank>. <student name>: <student score>.

>>> student_scores = [100, 99, 90, 84, 66, 53, 47]
>>> student_names =  ['Joci', 'Sara','Kora','Jan','John','Bern', 'Fred']
>>> student_ranking(student_scores, student_names)
...
['1. Joci: 100', '2. Sara: 99', '3. Kora: 90', '4. Jan: 84', '5. John: 66', '6. Bern: 53', '7. Fred: 47']

6. Uma nota "perfeita"

Embora uma nota "perfeita" de 100 seja rara num exame, é interessante saber se pelo menos um aluno a alcançou.

Cria a função perfect_score(student_info), com o parâmetro student_info. student_info é uma list de listas com o nome e a nota de cada aluno: [["Charles", 90], ["Tony", 80]]. A função deve return o primeiro par [<name>, <score>] do aluno que tirou 100 no exame.

Se não houver nenhuma nota de 100 em student_info, deve ser devolvida uma lista vazia [].

>>> perfect_score(student_info=[["Charles", 90], ["Tony", 80], ["Alex", 100]])
["Alex", 100]

>>> perfect_score(student_info=[["Charles", 90], ["Tony", 80]])
[]
Editar via GitHub A ligação abre numa nova janela ou separador
Python Exercism

Estás pronto para começar Passar de ano?

Inscreve-te no Exercism para aprenderes e dominares Python com 17 conceitos146 exercícios, e mentoria humana real, tudo grátis.