CSC/ECE 517 Spring 2024 - E2410. View for Results of Bidding

From Expertiza_Wiki
Jump to navigation Jump to search

Introduction

The Expertiza project is a dynamic collaboration between students and faculty at NC State University, built on the Ruby on Rails platform. It serves as a hub for fostering cooperative learning and academic collaboration, offering a suite of tools for efficient course and assignment management.

Expertiza empowers instructors with comprehensive control over the learning process, providing insights into various academic facets such as user profiles, courses, assignments, questionnaires, and reviews. With its user-friendly interface and innovative features, Expertiza revolutionizes collaborative learning, facilitating seamless topic creation, group formation, and peer review. Join us in embracing the transformative potential of digital collaboration to redefine the educational experience.

Test Login Credentials

  • UserId: instructor6
  • Password: password
  • Problem Statement:

    1. Instructors currently lack comprehensive visibility into the bidding process, hindering their ability to understand which topics are most sought after by teams and how teams prioritize their choices.
    2. The current system does not provide instructors with essential details such as which teams have bid on specific topics and the percentage of teams assigned their top-choice project.
    3. As a result, instructors resort to inefficient workarounds, such as logging in as students to view topic details, which complicates the process and delays access to critical bidding information.
    4. This lack of functionality fails to meet instructors' needs for a comprehensive overview of the bidding process, preventing them from effectively managing and allocating projects to teams.
    5. Enhancing the topics page and providing instructors with a summary view of the bidding process would empower them with valuable insights, streamline their workflow, and ensure they have the necessary tools to facilitate a fair and efficient project allocation process.

    Previous Implementations

    1. E2360 Github Repository
    2. E2360 Pull Request
    3. E2360 Wiki Page
    4. Demo Video
    1. E2245 Github Repository
    2. E2245 Pull Request
    3. E2245 Wiki Page
    4. Demo Video

    E2410 Current Implementation

    1. E2410 Github Repository
    2. E2410 Pull Request
    3. Demo Video

    Issues With Previous Implementation

    1. Functions directly fetch and process bids in the controller, which could be better managed through model methods for improved organization.
    2. The use of instance variables for bid counts is not scalable and can become problematic with changes in the bidding process.
    3. The current approach of fetching topics and iterating for bids may result in inefficient N+1 queries.
    4. There's a risk of repeating logic related to bidding across different parts of the application.
    5. UI elements and logic are intertwined within the controller, which is not ideal for MVC patterns.
    6. The views have repetitive non-zero checks for bid counts, which could be streamlined.
    7. CSS styles are hard-coded in views, which should be abstracted to CSS files.
    8. Missing error handling could cause unhandled exceptions for nonexistent bids or topics.
    9. Tests might not cover all scenarios, such as incorrect bid priorities or unrepresented teams.
    10. The UI lacks dynamic feedback mechanisms like AJAX updates for user interactions.

    Proposed Solution

    The design presented in this iteration of the project is very similar to the high-level design proposed last year in Fall 2023 Design. Since this pull request was not merged, we have included the proposed changes that are credible. Below is a comparable explanation of the previously offered remedy, as well as some new design decisions to improve upon the previous iteration of this issue.

    We've significantly improved the bidding system in Expertiza by enhancing the visibility and handling of bids for topics. Key improvements include detailed bidding data presentation, with distinct columns for each bid priority and clear team bid information. This offers users, both instructors and students, a transparent view into the bidding outcomes. Additionally, our refined logic more accurately calculates teams' preferred choice percentages, aiding better decision-making in topic assignments.

    Design

    Sequence Diagram for Bidding Process

    Current Flow

    • Go to the assignments section, we have created a dummy a assignment, "Test OODD", click edit icon next to it.

    • Now make sure the "has topics" checkbox is selected.

    • Now go to Topics section and scroll down to Bid Summary.

    • Here you will be able to view various stats of the bidding, like the percentage of teams that got their first choice of project, the number of teams that put the particular project as their first, second and third choice and the individual teams which bid on the particular project.

    Flowchart for Bidding Process

    Implementation Details

    Files Modified During the implementation

    • assignments_controller.rb
    • lottery_controller.rb
    • assignment.rb
    • bid.rb
    • team.rb
    • assignment_helper.rb
    • _topics.html.erb
    • bidding_details.html.erb
    • _bid_summary_partial.html.erb

    New functions that are implemented

    1. Assignment Controller

    File : ./app/controllers/assignments_controller.rb

    Functionality:

    • Added `bidding_details` method to `AssignmentController` for aggregating bid data per topic.
    • Implemented data retrieval for each topic's bids within an assignment using `@assignment.sign_up_topics`.
    • Compiled a list of teams assigned to topics, excluding those on the waitlist.
    • Introduced dynamic counting of bids per priority (1, 2, 3) for each topic and stored the results in `@count1`, `@count2`, and `@count3`.
    • Calculated the total number of teams and their respective percentages for obtaining their first, second, and third choice topics.
    • Created `bidding_details_for_topic` method to handle AJAX requests and render bid details for a specific topic.
    • Structured bid data retrieval to support interactive, on-the-fly updates in the user interface.

    2. Lottery Controller

    File : ./app/controllers/lottery_controller.rb

    Functionality:

    (1) Fetching Assignment and Topics:

    • The method retrieves an `Assignment` object based on the provided `id` parameter.
    • It then fetches all `SignUpTopic` objects associated with this assignment, storing them in the `@topics` instance variable.

    (2) Gathering Bids Data:

    • It initializes an empty hash `@bids_by_topic` to store bid information by topic.
    • Iterates over each topic and queries the `Bid` model to fetch all bids associated with that topic. Each bid's team and priority information are encapsulated in a hash and stored in the `@bids_by_topic`, keyed by topic ID.

    (3) Team Assignments Tracking:

    • Similarly, `@assigned_teams_by_topic` is prepared to hold information on teams assigned to each topic. This is populated by querying `SignedUpTeam` for non-waitlisted teams for each topic.

    (4) Dynamic Instance Variables for Priority Counts:

    • The code dynamically initializes and updates three instance variables: `@count1`, `@count2`, and `@count3` for each priority level (1, 2, 3). These variables are hashes that count the number of bids at each priority level for each topic.

    (5) Percentage Calculations:

    • After collecting bids and assigned teams, it calculates the total number of teams that made bids and computes the percentage of teams that received their first, second, and third choices. This is facilitated by helper methods `compute_priority_counts` and `compute_percentages`.

    (6) Overall Method Functionality:

    • The method effectively prepares a comprehensive data structure detailing the bids for each topic within the assignment. This includes the number of bids at each priority level and the percentages of teams that were able to secure their preferences. This data is essential for presenting a clear picture of the bidding results to the instructors or other stakeholders.

    (7) End Result:

    • The computed data is then used to render a view or to further business logic, providing insight into the distribution and success of bids across the different topics, thus aiding in intelligent assignment and team formation based on bidding data.

    3. Assignment Model

    File : ./app/models/assignment.rb

    Functionality:

    • ⁠Calculates the percentage of teams that have been awarded their first, second, and third choice topics based on bidding.
    • ⁠Utilizes a hash to keep count of the choices, initializing at zero for each choice level.
    • ⁠Iterates over each team to determine if they've been assigned a topic and subsequently increments the count of the choice they've made.
    • ⁠Counts the total number of teams to avoid division by zero errors when calculating percentages.
    • ⁠Transforms the counts into percentages by dividing by the total number of teams and multiplying by 100, rounding to two decimal places.
    • ⁠Provides the calculated percentages for use in views or other parts of the application.

    4. Bid Model

    File : ./app/models/bid.rb

    Functionality:

    • The method for merging bid data from different users was refined with clearer comments.
    • The method now organizes bidding information into a matrix structure, keyed by topic, simplifying the representation of bids for analysis.
    • A new method was introduced to calculate the percentages of teams receiving their preferred choices, with logic to prevent division by zero.
    • The data is then normalized to percentages, providing a concise and accurate calculation for bid analytics.

    5. Team Model

    File : ./app/models/team.rb

    Functionality:

    • Expanded the Team model with methods to fetch a team’s bid for a given topic.
    • Added functionality to retrieve the assigned sign-up topic for a team.
    • Refined the Team model's interface for interacting with associated bids and sign-up topics.

    6. Assignment Helper

    File : ./app/helpers/assignment_helper.rb

    Functionality:

    The ⁠ bid_intensity_class ⁠ method in the Assignment Helper serves the following functions:

    • Determines the CSS class to be applied based on the total number of bids for a topic.
    • If the total bids are between 0 and 5, it returns the class name 'bid-low-intensity'.
    • For total bids between 6 and 10, it returns 'bid-medium-intensity'.
    • If the number of bids exceeds 10, it yields 'bid-high-intensity'.
    • This method assists in visually differentiating the intensity of bidding on topics through color-coding or other styling cues in the user interface.

    7. Topics view

    File : ./app/views/assignments/edit/_topics.html.erb

    Functionality:

    • ⁠Introduced conditional checks for displaying specific sections in the topics form based on the assignment's properties like whether it allows suggestions, is intelligent, has a staggered deadline, etc.
    • ⁠Added a summary section to display aggregated bidding data if bidding is enabled.
    • ⁠Created a dynamic table that lists out the topic names, the count of first, second, and third priority bids, total bids, and names of bidding teams.
    • ⁠ ⁠Implemented a method to classify bid intensity into low, medium, and high based on the total number of bids.
    • ⁠Added modals to provide detailed bidding information for each topic, which will be populated via an AJAX call to a specified endpoint with the topic ID.
    • ⁠Set up a JavaScript function to handle click events on information buttons, triggering AJAX calls and displaying bid details in modals.


    8. Bidding Details view

    File : ./app/views/assignments/bidding_details.html.erb

    Functionality:

    • Displays the header "Bidding Details" along with the name of the current assignment.
    • Iterates over each topic that has received bids.
    • Retrieves and displays the name of each topic.
    • Creates a table structure with headers "Team Name" and "Bid Priority".
    • Loops through the bids associated with each topic.
    • For each bid, it displays the name of the team that placed the bid.
    • Also for each bid, it displays the priority level of the bid (e.g., 1st priority, 2nd priority).
    • Structures the data in a tabular format for clear visualization of teams and their bidding priorities per topic.



    9. Bid Summary view

    File : ./app/views/assignments/_bid_summary_partial.html.erb

    Functionality:

    • ⁠The snippet is part of a view template that generates a summary of bidding data for assignment topics.
    • ⁠It checks if there are any sign-up topics associated with the assignment.
    • ⁠For each topic, it lists out the total number of bids, along with a breakdown of bids by priority level: first, second, and third.
    • ⁠It also displays the names of teams that have placed bids on the topic.
    • ⁠The percentage of teams that got their first choice is calculated and displayed, color-coded to indicate the outcome:
      • Red for 0%, indicating no team got their first choice.
      • Green for 100%, indicating all teams got their first choice.
      • Orange for any percentage in between.
    • ⁠If no bids are present for a topic, it notes that.
    • ⁠If there are no topics created for the assignment, it informs the user accordingly.

    Accomplishment

    This project has added a "Bid Summary", which enables the instructor to see various stats of the bidding, like the percentage of teams that got their first choice of project, the number of teams that put the particular project as their first, second and third choice and the individual teams which bid on the particular project.

    Test Plan

    Manual Testing

    Follow these instructions to manually test the below functionality:

    • Navigate to the assignments page and click on the pencil icon next to the 'Test OODD' assignment.
    • Confirm that the 'Has Topics' checkbox is selected on the general assignment settings page.
    • Move to the 'Topics' tab and check the 'Enable bidding for topics' option.
    • Add a new topic for students to bid on by clicking the 'New Topic' button and entering relevant details.
    • Log in as a student and bid on the new topic, choosing the priority level for the bid.
    • Return to the 'Topics' tab as an instructor to view the updated bidding table with bids and priorities listed.
    • Confirm that the total number of bids and the number of #1, #2, and #3 bids are displayed correctly for each topic.
    • Check the background color coding (green, yellow, red) in the bidding table that reflects the intensity of bids for visual verification.

    RSpec Testing

    The assignment_controller_spec.rb has existing automated rspec tests in place. Furthermore following tests were added to the code to ensure the functionality is working as expected and thereby increasing code coverage:-

    -> assignment_controller_spec.rb

    describe '#bidding_details' do
        it 'assigns necessary variables and renders bidding_details template' do
          allow(Assignment).to receive(:find).with('1').and_return(assignment)
          allow(assignment).to receive(:sign_up_topics).and_return([double('SignUpTopic', id: 1)])
          allow(Bid).to receive(:where).with(topic_id: 1).and_return([])
          allow(assignment).to receive(:calculate_percentage_of_teams_getting_choices).and_return({})
          allow(assignment).to receive(:teams_bidding_for_each_topic).and_return({})
          allow(assignment).to receive(:assigned_teams_for_topics).and_return({})
          
          get :bidding_details, params: { id: 1 }
          
          expect(assigns(:assignment)).to eq(assignment)
          expect(assigns(:bids_by_topic)).to eq({ 1 => [] })
          expect(response).to render_template('bidding_details')
        end
      end
    
      describe '#bidding_details_for_topic' do
        it 'assigns necessary variables and renders bidding_details_for_topic template' do
          topic = double('SignUpTopic', id: 1)
          bids = [double('Bid')]
    
          allow(SignUpTopic).to receive(:includes).with(:bids).and_return(SignUpTopic)
          allow(SignUpTopic).to receive(:find).with(1).and_return(topic)
          allow(topic).to receive(:bids).and_return(bids)
    
          get :bidding_details_for_topic, params: { topic_id: 1 }, format: :js
          
          expect(assigns(:topic)).to eq(topic)
          expect(assigns(:bids)).to eq(bids)
          expect(response).to render_template('bidding_details_for_topic')
        end
      end
    
    


    Similarly, the file assignment_spec.rb have the automated rspec tests in them, Few more test case were added to verify the functionalities added.

    -> assignment_spec.rb

    describe '#calculate_percentage_of_teams_getting_choices' do
      it 'calculates the percentage of teams getting their choices' do
        # Mock necessary objects for the test
        assignment = build(:assignment)
        team1 = build(:team)
        team2 = build(:team)
        topic1 = build(:sign_up_topic, assignment_id: assignment.id)
        topic2 = build(:sign_up_topic, assignment_id: assignment.id)
        bid1 = build(:bid, team: team1, topic: topic1)
        bid2 = build(:bid, team: team1, topic: topic2)
        bid3 = build(:bid, team: team2, topic: topic2)
        allow(assignment).to receive(:sign_up_topics).and_return([topic1, topic2])
        allow(Team).to receive(:where).and_return([team1, team2])
        allow(team1).to receive(:bid_for_topic).with(topic1).and_return(bid1)
        allow(team1).to receive(:bid_for_topic).with(topic2).and_return(bid2)
        allow(team2).to receive(:bid_for_topic).with(topic2).and_return(bid3)
    
        # Perform the calculation
        percentages = assignment.calculate_percentage_of_teams_getting_choices
    
        # Perform your assertions here
        expect(percentages[1]).to eq(50.0)
        expect(percentages[2]).to eq(100.0)
      end
    end
    
    describe '#teams_bidding_for_each_topic' do
      it 'returns teams bidding for each topic' do
        # Mock necessary objects for the test
        assignment = build(:assignment)
        topic1 = build(:sign_up_topic, id: 1)
        topic2 = build(:sign_up_topic, id: 2)
        team1 = build(:team)
        team2 = build(:team)
        bid1 = build(:bid, team: team1, topic: topic1)
        bid2 = build(:bid, team: team1, topic: topic2)
        bid3 = build(:bid, team: team2, topic: topic2)
        allow(assignment).to receive_message_chain(:sign_up_topics, :includes).and_return([topic1, topic2])
        allow(topic1).to receive_message_chain(:bids, :map).and_return([['Team1', 1]])
        allow(topic2).to receive_message_chain(:bids, :map).and_return([['Team1', 1], ['Team2', 2]])
    
        # Call the method
        result = assignment.teams_bidding_for_each_topic
    
        # Perform assertions
        expect(result[1]).to eq([['Team1', 1]])
        expect(result[2]).to eq([['Team1', 1], ['Team2', 2]])
      end
    end
    
    describe '#bidding_info_by_topic' do
      it 'returns bidding information by topic' do
        # Mock necessary objects for the test
        assignment = build(:assignment)
        topic1 = build(:sign_up_topic, id: 1)
        topic2 = build(:sign_up_topic, id: 2)
        team1 = build(:team, name: 'Team1')
        team2 = build(:team, name: 'Team2')
        bid1 = build(:bid, team: team1, priority: 1)
        bid2 = build(:bid, team: team2, priority: 2)
        allow(assignment).to receive_message_chain(:sign_up_topics, :includes).and_return([topic1, topic2])
        allow(topic1).to receive_message_chain(:bids, :includes, :map).and_return([{ team_name: 'Team1', bid_priority: 1 }])
        allow(topic2).to receive_message_chain(:bids, :includes, :map).and_return([{ team_name: 'Team2', bid_priority: 2 }])
    
        # Call the method
        result = assignment.bidding_info_by_topic
    
        # Perform assertions
        expect(result[1]).to eq([{ team_name: 'Team1', bid_priority: 1 }])
        expect(result[2]).to eq([{ team_name: 'Team2', bid_priority: 2 }])
      end
    end
    
    describe '#assigned_teams_for_topics' do
      it 'returns assigned teams for each topic' do
        # Mock necessary objects for the test
        assignment = build(:assignment)
        topic1 = build(:sign_up_topic, id: 1)
        topic2 = build(:sign_up_topic, id: 2)
        team1 = build(:team, name: 'Team1')
        team2 = build(:team, name: 'Team2')
        allow(assignment).to receive_message_chain(:sign_up_topics, :includes).and_return([topic1, topic2])
        allow(topic1).to receive_message_chain(:assigned_teams, :map).and_return(['Team1'])
        allow(topic2).to receive_message_chain(:assigned_teams, :map).and_return(['Team2'])
    
        # Call the method
        result = assignment.assigned_teams_for_topics
    
        # Perform assertions
        expect(result[1]).to eq(['Team1'])
        expect(result[2]).to eq(['Team2'])
      end
    end
    
    

    Demo Video

    You can watch this demo videofor a detailed demonstration of the project.

    Team

    Mentor:

    • Anvitha Reddy Gutha (agutha@ncsu.edu)

    Members:

    • Shiva Vara Prasad Kandhagatla (skandha@ncsu.edu)
    • Sai Santhosh Garlapati (sgarlap@ncsu.edu)
    • Chinmay Walinjkar (cpwalinj@ncsu.edu)

    References