DEV Community

Ahmed Nadar
Ahmed Nadar

Posted on • Originally published at ahmednadar.com

A simple way to efficiently calculate and represent average data in Rails

I'm working on a project and I encountered a scenario where I need to calculate the average marks of students and create a simple visualization indicator to represent the calculated average. After a few iterations, I found this can be accomplished through a simple implementation and subsequent refactoring of the code.

Scenario
Let's say you have a Student model studen.rb and AcadmicReport model academic_report.rb . You want to show student's average marks in student show view, but the marks are an attribute of the academic_report model.
Initially, you may write a method to calculate the average marks, which can be done by iterating through the student's academic reports and summing the marks. You can then divide the sum by the number of academic reports to get the average marks.

# student.rb
def average_marks(marks)   
    marks.sum / marks.length 
end
Enter fullscreen mode Exit fullscreen mode

Next, you can create a method to assign the stars for the calculated average marks. This can be done through a simple case a statement that assigns a certain number of stars based on the range of the average marks.

# academic_reports_helper.rb
def 
    stars_for_average_marks(average) 
    case average 
    when 0..40 
        stars = 1 
    when 41..60 
        stars = 2
    when 61..80 
        stars = 3 
    when 81..90 
        stars = 4 
    else stars = 5 
    end 

    "⭐ " * stars
end
Enter fullscreen mode Exit fullscreen mode

Finally, you can render the stars in your student show view using the two methods.

# views/students/show.html.erb
<%= stars_for_average_marks(average_marks(@student.academic_reports.map { |report| report.marks })) %>
Enter fullscreen mode Exit fullscreen mode

Refactor
While this implementation works, it can be further optimized and refactored. For example, you can add a method in the Student model to calculate the average marks and then call that method in the view. This helps keep your code clean and organized and makes it easier to maintain and understand when you visit it later.

# in the Student model 
def average_academic_marks   
    academic_reports.sum(:marks) / academic_reports.count 
end  

# in the student show view 
<%= stars_for_average_marks(@student.average_academic_marks) %>
Enter fullscreen mode Exit fullscreen mode

As you see, Rails helps calculate the average marks of students (or a model you work with), and create a simple visualization indicator, and it can be done through a simple implementation. By refactoring the code and moving the calculation to the Student model, you can improve the readability and maintainability of your code.

Bounce
In addition to the average_academic_marks method, we can also calculate the average marks in percentage form. This is easily done with the use of the average_academic_marks method. Simply create a new method called average_academic_marks_percentage and add the necessary calculation as below:

# student.rb
def average_academic_marks_percentage
    (average_academic_marks * 100 / 100).to_s + '%' # 100 is the maximum marks 
end
Enter fullscreen mode Exit fullscreen mode

With this new method, we now have the ability to access both the average marks in numerical form as well as in percentage form. This adds another layer of insight and information that can be used to better understand and analyze student performance. And it is a nice feature, teachers love it.
In conclusion, by refactoring our initial code and moving the calculation logic into the Student model, we have made our code cleaner, more maintainable, and easily extendable for future needs.

And as usual, Happy Coding 😀 💻

Top comments (0)