1
votes

I have an issue that makes me crazy!!! I want to calculate the grades average of some students by their id. I wrote the code below, but it stacks after the first calculation :

list_sum([], 0).

list_sum([Head | Tail], TotalSum) :-
    list_sum(Tail, Sum1),TotalSum is Head + Sum1.

find_student_avg(Student,Year,Avg):- 
    findall(X, grades(_,student(id(Student),_,_,_,_,_),year(Year),normal(X)), L),
    %% not(resit_grades(_,student(id(Student),_,_,_,_,_),_,_)),
    list_sum(L,Sum), 
    length(L,N), N>0, 
    Avg is Sum / N.

find_all_avgs([Head|Tail],Year,L):-
    find_student_avg(Head,Year,Avg),append(L1,[Head|Avg],L),find_all_avgs(Tail,Year,L2).

I need my result to be something like L=[[id1|avg1],[id2|avg2],[id3|avg3]]. Can somenone help?????

Pleaseeeee!!!!

Any idea on how to sort this list by avg?

1

1 Answers

1
votes

Consider rewriting find_all_avgs/3 as a typical recursive predicate (Base case + recursive step) The base case would be when the first parameter (the list of students) is an empty list. In this case the result would be also an empty list. The recursive step clasuse would be one that takes the head of the input list, computes the student average for that student and then computes the rest of the averages (recursion). Note that the computed average can be put as the head of the output list instead of using append/3.

So, the resulting predicate would be something like:

find_all_avgs([],_,[]).   % Base case
find_all_avgs([Head|Tail],Year,[[Head,Avg]|L]):-
    find_student_avg(Head,Year,Avg),
    find_all_avgs(Tail,Year,L). % Recursion step

This predicate yields results of the form L= [[Student1,Average1], ...., [StudentN,AverageN]] which is not what you stated. However, I believe that would be the proper output format.

If you really need the other output format then the head of the second clause should be

find_all_avgs([Head|Tail],Year,[[Head|Avg]|L]):-