Jump to content

[Haskell] Calcular média de floats numa lista dinâmica


Recommended Posts

Posted

Em determinado exercício tenho o seguinte definido:

type Aluno = (Int, String, Float) -- Nº Aluno, Nome, Nota
type Curso = [Aluno]

listaAlunos :: Curso
listaAlunos = [(1234, "Jose Azevedo", 13.2), (2345, "Carlos Lopes", 9.7), (3456, "Rosa Mota", 17.9)]

O objectivo é calcular a média das notas deste 3 alunos. Eu fiz da seguinte forma:

mediaNotas :: Curso -> Float
mediaNotas [] = 0
mediaNotas (x) = (somaNotas x)/3

somaNotas :: Curso -> Float
somaNotas [] = 0
somaNotas ((_,_,x):xs) = x + (somaNotas xs)

As minhas dúvidas/problemas:

a) No caso de eu modificar listaAlunos removendo ou adicionando alunos, terei de mudar o cálculo da média, alterando o 3 para o número total de alunos. Como é que é possível eu saber este número automaticamente no caso de ter uma lista de alunos dinâmica em que eu esteja constantemente a adicionar/remover alunos?

😄 É possível fazer o calcula da média de algo (como no exemplo que eu dei) sem usar uma função auxiliar como a somaNotas? Ou tenho mesmo de ter smpre uma função auxiliar que vai somar as notas todas e só depois dividir pelo total noutra função? É que eu tentei na função de somar, englobar o "x + (somaNotas xs)" dentro () e dps / 3, mas o resultado não era o mesmo, não é suposto? A mim parece-me que ele vai somar tudo primeiro, chamado a função recursivamente e, só no fim é que divide por 3. Não funciona, mas não devia? Não tem lógica?

Posted

a)

media :: [(Int,String,Float)]->Float
media l=(sum (map (\(_,_,n)->n) l))/(lenght l)

pegas na lista de alunos, através de um 'map' retiras a nota de cada aluno (eu recorri a funções lambda mas podes usar uma função auxiliar), soma todas as notas ('sum') e divide pelo comprimento da lista.

😄 não percebi muito bem o que queres dizer, coloca aqui a outra versão da função e posso tentar ver qual é o problema.

Posted

a) mas eu ainda não dei o map nem funções lambda e não queria estar a usar isso sem ter dado... uma função auxiliar foi o que eu usei como podes ver no tópico inicial. eu tentei usar o length na meu código mas deu-me erros, não devo tar aplicar isso correctamente...

😄 o que eu tentei fazer foi isto:

media :: Curso -> Float
media [] = 0
media ((_,_,x):xs) = (x + (media xs))/3

mas os calculos não foram feitos correctamente...

Posted

relativamente ao (a) podes usar a função 'somaNotas' que funciona na mesma...

quanto ao (😄 , tu estás a dividir por 3 em todas as chamadas da função...

suponhamos que as notas eram 1,2 e 3:

media [1,2,3]

= (1 + (media [2,3]))/3

= (1 + ( (2 + (media [3]))/3 ))/3

= (1 + ( (2 + ( (3+media [])/3 ))/3))/3

que é diferente de (1+2+3)/3...

Posted

eu sei que é diferente, mas sempre pensei que ele fizesse mais algo do género:

media [1,2,3]

= (1 + (media [2,3]))/3

= (1 + (2 + (media [3])))/3

= (1 + (2 + (3 + (media []))))/3

anyway, vou tentar usar o length a ver se consigo chegar lá, se não conseguir, depois digo qq coisa...

Posted

pronto, já consegui usando uma função auxiliar para somar as notas mais o length. o meu problema no length é que o gajo tava a devolver um inteiro e o divisor tinha de ser float, usei a função "fromIntegral" e já está a funcionar.

thanks 😄

  • 2 weeks later...
Posted

podes mostrar como é que meteste o fromInt na funçao?

Qd tento meter esta funçao:

media :: Float -> Float -> Float -> Float
media a b c = (a + b + c) / 3

mas assim:

media :: Int -> Int -> Int -> Float
media a b c = fromInt (a + b + c) / 3

dá erro (Undefined variable "fromInt")  e nao consigo perceber pq, visto que foi assim que me foida da na aula.

Posted

Pois, assim já dá, já tinha tentado com fromInteger devido a umas coisas que tive a ver a net mas tb nao tinha dado, pensei que fosse preciso mais que isso, sou um noob nisto.

Obrigado 🙂

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.