CSC/ECE 517 Fall 2023 - E2356. Refactor review mapping controller.rb: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
 
(56 intermediate revisions by 3 users not shown)
Line 7: Line 7:


== About Controller ==
== About Controller ==
The functionality of review_mapping_controller is to provide mapping for the reviewer and assignment. Basically, the controller handles the assignment of reviews to different teams or single student users, such as the event of peer review and self-review. Also, this controller is responsible to respond student user requests for extra bonus reviews based on assignment policy.
The functionality of '''review_mapping_controller''' is to map the reviewer to an assignment. Basically, the controller handles the assignment of reviews to different teams or individual student users, covering scenarios like peer reviews and self-reviews. Additionally, the controller plays a crucial role in handling requests from student users, facilitating extra bonus reviews in alignment with the assignment policy.


== Problem Statement==
== Problem Statement==
Line 18: Line 18:


== Design Pattern ==
== Design Pattern ==
We followed several design patterns while refactoring our code. One of the most common ones is the “Extract Method.” There were several instances where the method was too long and complex. We moved some of the functionality to a different method to make it more readable. This way, it became easier and clearer to understand what the method achieved.  
During the code refactoring process, we conscientiously followed various design patterns to enhance the overall structure. One of the most common ones is the “Extract Method.” There were several instances where certain methods became overly lengthy and intricate. By extracting specific functionalities into separate methods, we significantly improved the code's readability and comprehension. This way, it became easier and clearer to understand what the method achieved. Furthermore, we tackled the issue of excessive conditional statements by employing the "Refactoring Conditionals" design pattern. This approach involves isolating the block of code within a conditional statement into a distinct method and subsequently invoking that method. This strategic refactoring not only streamlined our code but also contributed to a more readable and maintainable codebase.
Another issue we observed with the code was that it had too many conditional statements. We used the “Refactoring conditionals” design pattern, which aims to place the block of code in the conditional statement in a different method and call that method. This improves the readability of our code.
 
[[File:flow_Diagram_review_mapping_controller.png]]
[[File:flow_Diagram_review_mapping_controller.png|1000px]]


== File(s) Modified ==
== File(s) Modified ==
1. review_mapping_controller.rb
1. <code>review_mapping_controller.rb</code><br>
2. <code>review_mapping_controller_spec.rb</code><br>
Changes can be seen in the pull request created [https://github.com/expertiza/expertiza/pull/2657/files here].


==Solutions/Details of Changes Made==
==Solutions/Details of Changes Made==
1. Changes to variable names to make them reflect what they actually do.
'''1. Changes to variable names to make them reflect what they actually do.'''


i) Changed variable name from mmappings to meta_review_mappings to provide more context.
i) Changed variable name from '''mmappings''' to '''meta_review_mappings''' to provide more context.


[[File:Variable_commit1_review_mapping.png]]
[[File:Variable_commit1_review_mapping.png|1000px]]


ii) Used assignment_id which is declared before, instead of hardcoding params[:id].to_i
ii) Used '''assignment_id''' which is declared before, instead of hardcoding '''params[:id].to_i
'''
[[File:Variable_commit2_review_mapping.png|1000px]]


[[File:Variable_commit2_review_mapping.png]]
'''2. Added/Edited comments to improve the readability of code and make commenting proper.'''


2. Added/Edited comments to improve the readability of code and make commenting proper.
a) Adding comments


a) Adding comments
Elaborate commenting has been performed for every method present in the review_mapping_comtroller. A few examples include:


i) Explains the functionality of add_calibration method in a simple manner.
i) Explains the functionality of '''add_calibration''' method in a simple manner.


[[File:Comment1_commit_review_mapping.png]]
[[File:Comment1_commit_review_mapping.png|1000px]]


ii) Inform that an assignment can have multiple topics which need to be taken care of.
ii) Inform that an assignment can have multiple topics which need to be taken care of.


[[File:Comment2_commit_review_mapping.png]]
[[File:Comment2_commit_review_mapping.png|1000px]]


iii) Explains the functionality of automatic_review_mapping
iii) Explains the functionality of '''automatic_review_mapping'''


[[File:Comment3_commit_review_mapping.png]]
[[File:Comment3_commit_review_mapping.png|1000px]]


iv) Describes an error encountered in the stable version of Expertiza, and suggests potential fix.
iv) Describes an error encountered in the stable version of Expertiza, and suggests potential fix.


[[File:Comment4_commit_review_mapping.png]]
[[File:Comment4_commit_review_mapping.png|1000px]]
 
v) Describe functionality of '''delete_reviewer''', '''delete_metareviewer''', '''delete_metareview''', and several other functions.
 
[[File:Comment4_review_mapping.png|1000px]]
 
[[File:Comment1_review_mapping.png|1000px]]
 
[[File:Comment3_review_mapping.png|1000px]]


b) Edit Comments
b) Edit Comments


i) Describes the working of assign_reviewer_dynamically in a concise manner  
i) Describes the working of '''assign_reviewer_dynamically''' in a concise manner  


[[File:Edit_comment1_commit_review_mapping.png]]
[[File:Edit_comment1_commit_review_mapping.png|1000px]]


ii) Explains the function review_allowed? better, the previous comment was too repetitive.
ii) Explains the function '''review_allowed?''' better, the previous comment was too repetitive.


[[File:Edit_comment2_commit_review_mapping.png]]
[[File:Edit_comment2_commit_review_mapping.png|1000px]]


iii) Precisely mentions the criteria for requesting reviews by the user.
iii) Precisely mentions the criteria for requesting reviews by the user.


[[File:Edit_comment3_commit_review_mapping.png]]
[[File:Edit_comment3_commit_review_mapping.png|1000px]]


c) Deleting Comments
c) Deleting Comments
Line 74: Line 86:
Comments about previous teams progress and other redundant comments were removed to improve readability and maintainability.
Comments about previous teams progress and other redundant comments were removed to improve readability and maintainability.


[[File:Delete_comment1_commit_review_mapping.png]]
[[File:Delete_comment1_commit_review_mapping.png|1000px]]
 
 
[[File:Delete_comment2_commit_review_mapping.png]]
 
 
[[File:Delete_comment3_commit_review_mapping.png]]
 


[[File:Delete_comment4_commit_review_mapping.png]]


[[File:Delete_comment3_commit_review_mapping.png|1000px]]


3. Reducing cyclomatic complexity of functions by dividing them into smaller methods.


i)
[[File:Delete_comment4_commit_review_mapping.png|1000px]]


[[File:Refactor1_commit_review_mapping.png]]


ii)
'''3. Reducing cyclomatic complexity of functions by dividing them into smaller methods.'''


[[File:Refactor2_commit_review_mapping.png]]
Changes were made to the '''automatic_review_mapping''' method, keeping the single responsibilty principle in mind.


iii)
i) Modularized the functionality of previous version in a private method called '''handle_review_assignment''' which checks conditions to proceed with assigning reviewers to artifacts.


[[File:Refactor3_commit_review_mapping.png]]
[[File:Refactor2_commit_review_mapping.png|1000px]]


iv)
ii) Different components of the method are now encapsulated in their respective private functions


[[File:Refactor4.1_commit_review_mapping.png]]
[[File:Refactor3_commit_review_mapping.png|1000px]]


[[File:Refactor4.1_commit_review_mapping.png|1000px]]


v)
[[File:Refactor4.2_commit_review_mapping.png|1000px]]


[[File:Refactor4.2_commit_review_mapping.png]]
'''NOTE:''' Private functions are used to increase maintainability of the codebase since these do not break already existing test suites.


4. Reshuffling parts of code to make the method look consistent and easy to read and understand
vi)


[[File:Refactor1_commit_review_mapping.png]]
[[File:Assign_reviewer_with_topic.png|1000px]]


5. Test Report
vii)


[[File:Test_report_review_mapping.png]]
[[File:Assign_reviewer_without_topic.png|1000px]]


viii) Dividing long peer_review_strategy method in smaller modular functions
[[File:3_Peer_Review_1.png|1000px]]


1. The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.
[[File:3_Peer_Review_2.png|1000px]]


2. Refactoring the Update method
[[File:3_Peer_Review_3.png|1000px]]


'''Before refactoring'''
[[File:3_Peer_Review_4.png|1000px]]
  def update
    @topic = SignUpTopic.find(params[:id])
    if @topic
      @topic.topic_identifier = params[:topic][:topic_identifier]
      update_max_choosers @topic
      @topic.category = params[:topic][:category]
      @topic.topic_name = params[:topic][:topic_name]
      @topic.micropayment = params[:topic][:micropayment]
      @topic.description = params[:topic][:description]
      @topic.link = params[:topic][:link]
      @topic.save
      undo_link("The topic: \"#{@topic.topic_name}\" has been successfully updated. ")
    else
      flash[:error] = 'The topic could not be updated.'
    end
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'
  end


'''After refactoring'''
def update
    @topic = SignUpTopic.find(params[:id])
    if @topic
      update_max_choosers @topic
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )
      undo_link("The topic: \"#{@topic.topic_name}\" has been successfully updated. ")
      flash[:success] = 'The topic has been updated.'
    else
      flash[:error] = 'The topic could not be updated.'
    end
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'
  end


3.  
'''4. Reshuffling parts of code to make the method look consistent and easy to read and understand'''


4.
The declarations for the '''automatic_review_mapping''' are grouped together for better readability.


5. signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.
[[File:Refactor1_commit_review_mapping.png|1000px]]


''' signup_as_instructor_action '''
Making changes in peer_review_strategy method to make the code look inline with other parts
[[File:4_1.png|1000px]]


  def signup_as_instructor_action
    user = User.find_by(name: params[:username])
    if user.nil? # validate invalid user
      flash[:error] = 'That student does not exist!'
    else
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])
          flash[:success] = 'You have successfully signed up the student for the topic!'
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)
        else
          flash[:error] = 'The student has already signed up for a topic!'
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')
        end
      else
        flash[:error] = 'The student is not registered for the assignment!'
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' << user.id)
      end
    end
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]
  end


''' signup_as_instructor function'''
'''5. Bug Fixes'''


def signup_as_instructor; end
Changes made to '''check_outstanding_reviews''' method to return the correct results. Previously if all the reviews were completed by a participant, the method returned true (num_reviews_in_progress = 0), which would not be the right output. This is fixed by ensuring a return value of true only if num_reviews_in_progress > 0.


[[File:BugFix1ReviewMapingController.png|1000px]]


6.


7.
'''6. Test Cases Addition'''


8.
Test Cases have been added to improve test coverage. Additional details can be found in Test Plan section - https://wiki-expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2023_-_E2356._Refactor_review_mapping_controller.rb#Test_Plan


9. Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function handle_signup_deletion to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user.
== Test Plan==
=== Test Plan, Testing Strategy and Results===
In the realm of Test-Driven Development (TDD) research, our team made the strategic decision to '''utilize Mustafa Olmez's meticulously crafted test skeletons'''. These skeletons provided us with invaluable guidance, outlining the essential tests required for our unit. '''By incorporating 20 of these meticulously designed test skeletons into our work, we were able to conduct rigorous testing of our controller module.''' This approach allowed us to delve deeply into the functionality of our controller, ensuring thorough examination and validation of its behavior. The integration of these test skeletons not only provided a robust framework for our unit tests but also enhanced the overall quality and reliability of our codebase.


'''Before Refactoring Delete_signup and delete_signup_as_instructor'''
For a detailed view of the changes made, please refer to the complete file at the following link:


def delete_signup
https://github.com/expertiza/expertiza/pull/2657/files#diff-bccc23eb7ba2a55b74837eed3f4c85aa1d8c55d356ce0e0bc7de7afd50121b13
    participant = AssignmentParticipant.find(params[:id])
    assignment = participant.assignment
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)
    # A student who has already submitted work should not be allowed to drop his/her topic!
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)
    # If there is a drop topic deadline, student cannot drop topic after this deadline.
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)
    elsif !drop_topic_deadline.nil? && (Time.now > drop_topic_deadline.due_at)
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)
    else
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)
      flash[:success] = 'You have successfully dropped your topic!'
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)
    end
    redirect_to action: 'list', id: params[:id]
  end


  def delete_signup_as_instructor
The additional tests ensure every method of review_mapping_controller is tested. By adopting this approach we have '''increased the overall coverage from 47.65% to 47.8%'''.
    # find participant using assignment using team and topic ids
The changes made passed all the necessary Travis CI/CD Pipeline tests.
    team = Team.find(params[:id])
    assignment = Assignment.find(team.parent_id)
    user = TeamsUser.find_by(team_id: team.id).user
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)
    elsif !drop_topic_deadline.nil? && (Time.now > drop_topic_deadline.due_at)
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)
    else
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)
      flash[:success] = 'You have successfully dropped the student from the topic!'
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)
    end
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id
  end


[[File:Test1ReviewMapping.png|750px]]


'''After Refactoring Delete_signup and delete_signup_as_instructor'''   
===SimpleCov Coverage Detail Report of <code>review_mapping_controller.rb</code>===
  def delete_signup
    handle_signup_deletion(params[:id], session[:user].id)
  end


  def delete_signup_as_instructor
Tests prior to the changes covered 69.65 % of <code>review_mapping_controller.rb</code>
    team = Team.find(params[:id])
[[File:Old_coverage_report_simplecov.png|1000px]]
    user = TeamsUser.find_by(team_id: team.id).user
    assignment = Assignment.find(team.parent_id)
    handle_signup_deletion(user.id, session[:user].id, assignment.id)
  end


  private def handle_signup_deletion(participant_id, user_id, assignment_id = nil)
    participant = AssignmentParticipant.find(participant_id)
    assignment ||= participant.assignment
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)
    error_message = check_signup_eligibility(participant.team, drop_topic_deadline, user_id, params[:topic_id])
    if error_message
      flash[:error] = error_message
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, "Drop failed for #{error_message}: #{params[:topic_id]}")
    else
      delete_signup_for_topic(assignment.id, params[:topic_id], user_id)
      flash[:success] = 'You have successfully dropped the topic!'
      ExpertizaLogger.info LoggerMessage.new(controller_name, user_id, "Student has dropped the topic: #{params[:topic_id]}")
    end
    redirect_to redirect_path(participant_id, assignment_id)
  end
 
  def check_signup_eligibility(team, drop_topic_deadline, user_id, topic_id)
    if !team.submitted_files.empty? || !team.hyperlinks.empty?
      'You have already submitted your work, so you are not allowed to drop your topic.'
    elsif !drop_topic_deadline.nil? && (Time.now > drop_topic_deadline.due_at)
      'You cannot drop your topic after the drop topic deadline!'
    end
  end


  def redirect_path(participant_id, assignment_id)
After adding tests, the tests covered 69.76 % of refactored <code>review_mapping_controller.rb</code>. It improved slightly to be an even better coverage.
    if assignment_id
[[File:New_coverage_report_simplecov.png|1000px]]
      controller: 'assignments', action: 'edit', id: assignment_id
    else
      action: 'list', id: participant_id
    end
  end


10.
== Relevant Links ==
* '''Github Repository:''' https://github.com/amit-99/NCSU_OODD_expertiza
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2657
* '''VCL Server:''' http://152.7.178.252:8080/


== Team ==
== Team ==

Latest revision as of 19:17, 30 November 2023

This wiki page is for information regarding the changes made for the E2356 Refactor review_mapping_controller.rb OSS assignment for Fall 2023, CSC/ECE 517.

Introduction

Expertiza is an open-source project developed on Ruby on Rails. This web application is maintained by the students and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.

About Controller

The functionality of review_mapping_controller is to map the reviewer to an assignment. Basically, the controller handles the assignment of reviews to different teams or individual student users, covering scenarios like peer reviews and self-reviews. Additionally, the controller plays a crucial role in handling requests from student users, facilitating extra bonus reviews in alignment with the assignment policy.

Problem Statement

  • Refactor the long methods in review_mapping_controller.rb like assign_reviewer_dynamically, add_reviewer, automatic_review_mapping,peer_review_strategy etc.
  • Some variables in review_mapping_controller.rb are not named properly. Rename variable names to convey what they are used for.
  • Functions are lengthy and difficult to read. Replace switch statements with subclasses methods, if any.
  • Create subclasses and models wherever necessary.
  • Add meaningful comments and edit/remove unnecessary comments.
  • Ensure that code changes do not break any functionality. Refactoring method names might cause cascaded updates in other files.

Design Pattern

During the code refactoring process, we conscientiously followed various design patterns to enhance the overall structure. One of the most common ones is the “Extract Method.” There were several instances where certain methods became overly lengthy and intricate. By extracting specific functionalities into separate methods, we significantly improved the code's readability and comprehension. This way, it became easier and clearer to understand what the method achieved. Furthermore, we tackled the issue of excessive conditional statements by employing the "Refactoring Conditionals" design pattern. This approach involves isolating the block of code within a conditional statement into a distinct method and subsequently invoking that method. This strategic refactoring not only streamlined our code but also contributed to a more readable and maintainable codebase.

File(s) Modified

1. review_mapping_controller.rb
2. review_mapping_controller_spec.rb
Changes can be seen in the pull request created here.

Solutions/Details of Changes Made

1. Changes to variable names to make them reflect what they actually do.

i) Changed variable name from mmappings to meta_review_mappings to provide more context.

ii) Used assignment_id which is declared before, instead of hardcoding params[:id].to_i

2. Added/Edited comments to improve the readability of code and make commenting proper.

a) Adding comments

Elaborate commenting has been performed for every method present in the review_mapping_comtroller. A few examples include:

i) Explains the functionality of add_calibration method in a simple manner.

ii) Inform that an assignment can have multiple topics which need to be taken care of.

iii) Explains the functionality of automatic_review_mapping

iv) Describes an error encountered in the stable version of Expertiza, and suggests potential fix.

v) Describe functionality of delete_reviewer, delete_metareviewer, delete_metareview, and several other functions.

b) Edit Comments

i) Describes the working of assign_reviewer_dynamically in a concise manner

ii) Explains the function review_allowed? better, the previous comment was too repetitive.

iii) Precisely mentions the criteria for requesting reviews by the user.

c) Deleting Comments

Comments about previous teams progress and other redundant comments were removed to improve readability and maintainability.




3. Reducing cyclomatic complexity of functions by dividing them into smaller methods.

Changes were made to the automatic_review_mapping method, keeping the single responsibilty principle in mind.

i) Modularized the functionality of previous version in a private method called handle_review_assignment which checks conditions to proceed with assigning reviewers to artifacts.

ii) Different components of the method are now encapsulated in their respective private functions

NOTE: Private functions are used to increase maintainability of the codebase since these do not break already existing test suites.

vi)

vii)

viii) Dividing long peer_review_strategy method in smaller modular functions


4. Reshuffling parts of code to make the method look consistent and easy to read and understand

The declarations for the automatic_review_mapping are grouped together for better readability.

Making changes in peer_review_strategy method to make the code look inline with other parts


5. Bug Fixes

Changes made to check_outstanding_reviews method to return the correct results. Previously if all the reviews were completed by a participant, the method returned true (num_reviews_in_progress = 0), which would not be the right output. This is fixed by ensuring a return value of true only if num_reviews_in_progress > 0.


6. Test Cases Addition

Test Cases have been added to improve test coverage. Additional details can be found in Test Plan section - https://wiki-expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2023_-_E2356._Refactor_review_mapping_controller.rb#Test_Plan

Test Plan

Test Plan, Testing Strategy and Results

In the realm of Test-Driven Development (TDD) research, our team made the strategic decision to utilize Mustafa Olmez's meticulously crafted test skeletons. These skeletons provided us with invaluable guidance, outlining the essential tests required for our unit. By incorporating 20 of these meticulously designed test skeletons into our work, we were able to conduct rigorous testing of our controller module. This approach allowed us to delve deeply into the functionality of our controller, ensuring thorough examination and validation of its behavior. The integration of these test skeletons not only provided a robust framework for our unit tests but also enhanced the overall quality and reliability of our codebase.

For a detailed view of the changes made, please refer to the complete file at the following link:

https://github.com/expertiza/expertiza/pull/2657/files#diff-bccc23eb7ba2a55b74837eed3f4c85aa1d8c55d356ce0e0bc7de7afd50121b13

The additional tests ensure every method of review_mapping_controller is tested. By adopting this approach we have increased the overall coverage from 47.65% to 47.8%. The changes made passed all the necessary Travis CI/CD Pipeline tests.

SimpleCov Coverage Detail Report of review_mapping_controller.rb

Tests prior to the changes covered 69.65 % of review_mapping_controller.rb


After adding tests, the tests covered 69.76 % of refactored review_mapping_controller.rb. It improved slightly to be an even better coverage.

Relevant Links

Team

Mentor

  • Ameya Vaichalikar (agvaicha)

Team Members

  • Chirag Bheemaiah Palanganda Karumbaiah (cpalang)
  • Shanmukh Pawan Moparthi (smopart2)
  • Amit Bhujbal (abhujba)