<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ravnee</id>
	<title>Expertiza_Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ravnee"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Ravnee"/>
	<updated>2026-06-06T22:56:16Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/final_design_doc_M1450_navr&amp;diff=91904</id>
		<title>CSC/ECE 517 Fall 2014/final design doc M1450 navr</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/final_design_doc_M1450_navr&amp;diff=91904"/>
		<updated>2014-11-12T01:11:26Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Proposed Test Cases */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== [http://www.rust-lang.org/ Rust]===&lt;br /&gt;
&lt;br /&gt;
Rust is a modern systems programming language focusing on safety and speed to build reliable and efficient systems &amp;lt;ref&amp;gt; http://doc.rust-lang.org/nightly/intro.html &amp;lt;/ref&amp;gt;. It accomplishes the goals of memory safe without using garbage collection and it supports concurrency and parallelism in building platforms. &lt;br /&gt;
&lt;br /&gt;
Rust’s lightweight task mechanism also promises to allow fine-grained isolation between browser components, such as tabs and extensions, without the need for expensive runtime protection schemes, like operating system process isolation. &amp;lt;ref&amp;gt; https://www.mozilla.org/en-US/research/projects/ &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://github.com/servo/servo/wiki/Design Servo] ===&lt;br /&gt;
&lt;br /&gt;
Mozilla Research team is currently working on an experimental project to develop a new Web browser engine &amp;quot;Servo&amp;quot;, that is capable of supporting a variety of current and next generation of hardware like mobile devices, multi-core processors and high-performance GPUs. Servo builds on top of Rust to provide a secure and reliable foundation. It is currently developed on 64 bit devices.&amp;lt;ref&amp;gt; https://www.mozilla.org/en-US/research/projects/ &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main objectives of this experimentation project is improving the layout to graphics rendering - to optimize for power efficiency and maximize parallelism. &amp;lt;ref&amp;gt; https://www.mozilla.org/en-US/research/projects/ &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Purpose ===&lt;br /&gt;
&lt;br /&gt;
The purpose of this project is to introduce the support related to sessionstorage and localstorage in Servo Broswer, for this we have to create Storage structure and allow web pages to store data in the Servo memory space.&lt;br /&gt;
&lt;br /&gt;
=== Background ===&lt;br /&gt;
&lt;br /&gt;
Persistent storage on the web is used by many services such as the popular Disqus commenting interface. Implementing this important specification in Servo will allow stateful web applications to run, and will help expose any architectural problems that Servo's radical design may cause.&lt;br /&gt;
&lt;br /&gt;
== Architecture ==&lt;br /&gt;
&lt;br /&gt;
[[File:task.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Architecture comprises of a Storage Task which will be responsible to hold all the data that the web page requests to save. This happens via Channels in Rust, which implements a Sender Receiver protocol, the task is runnning in the background and waits to receive the data sent from the web page.&lt;br /&gt;
&lt;br /&gt;
=== Architecture Explained ===&lt;br /&gt;
*Each box represents a Rust task.&lt;br /&gt;
*Blue boxes represent the primary tasks in the browser pipeline.&lt;br /&gt;
*Gray boxes represent tasks auxiliary to the browser pipeline.&lt;br /&gt;
*White boxes represent worker tasks. Each such box represents several tasks, the precise number of which will vary with the workload.&lt;br /&gt;
*Dashed lines indicate supervisor relationships.&lt;br /&gt;
*Solid lines indicate communication channels.&lt;br /&gt;
&lt;br /&gt;
== Requirement Analysis &amp;lt;ref&amp;gt;https://github.com/servo/servo/wiki/Storage-student-project&amp;lt;/ref&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
As part of our [http://github.com/servo/servo/wiki/Storage-student-project project], we have to implement the [http://html.spec.whatwg.org/multipage/webstorage.html#webstorage Web Storage] specification in Servo. Implementing this important specification in Servo will allow stateful web applications to run, and will help expose any architectural problems that Servo's radical design may cause. &amp;lt;ref&amp;gt; https://github.com/servo/servo/wiki/Storage-student-project&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Below is a high level overview of the various steps that need to be carried out to achieve this:&lt;br /&gt;
&lt;br /&gt;
* Create the Storage interface and its stub implementation.&lt;br /&gt;
* Create the WindowSessionStorage interface making it return a Storage instance.&lt;br /&gt;
* Create a Storage Task which will be used to contain all stored data.&lt;br /&gt;
* Define a message-passing interface for reading and writing stored data for a particular browser tab.&lt;br /&gt;
* Use the Storage task in the implementation of Storage.&lt;br /&gt;
* When the value of a stored data is changed, notify its respective browser tab.&lt;br /&gt;
* Pass as many tests as possible.&lt;br /&gt;
* Implement the WindowLocalStorage interface which behaves slightly different from the WindowSessionStorage interface.&lt;br /&gt;
&lt;br /&gt;
== Data Design ==&lt;br /&gt;
&lt;br /&gt;
===  Data Description ===&lt;br /&gt;
&lt;br /&gt;
''The following are the data structures that will be used.''&lt;br /&gt;
&lt;br /&gt;
'''Storage''' | TreeMap&amp;lt;String,String&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''UrlMap''' | TreeMap&amp;lt;String,TreeMap&amp;lt;String,String&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Component Design ==&lt;br /&gt;
[[File:servo.jpg]]&lt;br /&gt;
=== Task ===&lt;br /&gt;
Rust provides safe concurrent abstractions through a number of core library primitives. This guide will describe the concurrency model in Rust, how it relates to the Rust type system, and introduce the fundamental library abstractions for constructing concurrent programs.&lt;br /&gt;
&lt;br /&gt;
Tasks provide failure isolation and recovery. When a fatal error occurs in Rust code as a result of an explicit call to panic!(), an assertion failure, or another invalid operation, the runtime system destroys the entire task. Unlike in languages such as Java and C++, there is no way to catch an exception. Instead, tasks may monitor each other to see if they panic.&lt;br /&gt;
&lt;br /&gt;
Tasks use Rust's type system to provide strong memory safety guarantees. In particular, the type system guarantees that tasks cannot induce a data race from shared mutable state.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Generate some state locally&lt;br /&gt;
let child_task_number = generate_task_number();&lt;br /&gt;
&lt;br /&gt;
spawn(proc() {&lt;br /&gt;
    // Capture it in the remote task&lt;br /&gt;
    println!(&amp;quot;I am child number {}&amp;quot;, child_task_number);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Channel ===&lt;br /&gt;
Now that we have spawned a new task, it would be nice if we could communicate with it. For this, we use channels. A channel is simply a pair of endpoints: one for sending messages and another for receiving messages.&lt;br /&gt;
&lt;br /&gt;
The simplest way to create a channel is to use the channel function to create a (Sender, Receiver) pair. In Rust parlance, a sender is a sending endpoint of a channel, and a receiver is the receiving endpoint. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let (tx, rx): (Sender&amp;lt;int&amp;gt;, Receiver&amp;lt;int&amp;gt;) = channel();&lt;br /&gt;
&lt;br /&gt;
spawn(proc() {&lt;br /&gt;
    let result = some_expensive_computation();&lt;br /&gt;
    tx.send(result);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
some_other_expensive_computation();&lt;br /&gt;
let result = rx.recv();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Design patterns ==&lt;br /&gt;
&lt;br /&gt;
We will be using &amp;quot;Delegation Pattern&amp;quot; in our project. The Storage interface is used by web applications to access the Web Storage provided by the browser. However, the actual data is stored somewhere else(Database/FileSystem/Memory). So, it makes sense to create another class which will maintain the actual stored data. The Storage class can then delegate the task of storing/retrieving data to this class. We will create a class &amp;quot;WebStorageTask&amp;quot; for this purpose.&lt;br /&gt;
&lt;br /&gt;
== UML diagrams (Eg use case diagram, class diagrams) ==&lt;br /&gt;
&lt;br /&gt;
[[File:Flow_Chart_Storage.png]][[File:Use_Case_Storage.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Proposed Test Cases ==&lt;br /&gt;
&lt;br /&gt;
To test the session storage in servo, we will be implementing the storage tasks. Some of the test cases for reference are: &lt;br /&gt;
* Clear session storage&lt;br /&gt;
* Set items in sessions storage&lt;br /&gt;
* Get stored items from session storage&lt;br /&gt;
* Check the number of items storage in session storage&lt;br /&gt;
* On removing the item from storage, it should be inaccessible&lt;br /&gt;
* Check if out of range indexes give error&lt;br /&gt;
* Access for out of range arguments as keys should return null&lt;br /&gt;
* Get an error on exceeding the limit of session storage&lt;br /&gt;
&lt;br /&gt;
You can find the detailed list of test cases at [https://github.com/servo/web-platform-tests/tree/servo/webstorage Webstorage Tests]&lt;br /&gt;
&lt;br /&gt;
== Further Readings ==&lt;br /&gt;
&lt;br /&gt;
Learning Rust by Examples: http://rustbyexample.com/ &amp;lt;br/&amp;gt;&lt;br /&gt;
Javascript as Servo's Garbage Collector: http://blog.mozilla.org/research/2014/08/26/javascript-servos-only-garbage-collector/  &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90908</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90908"/>
		<updated>2014-10-29T22:25:43Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Project Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;TestingLinks&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza instance links&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | '''username= &amp;quot;user480&amp;quot;&amp;lt;br /&amp;gt;password= &amp;quot;password&amp;quot;'''&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note for testing :''' It is recommended that in order to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there are other existing users who have participated in the same assignment.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[#TestingLinks|'''Expertiza Test instances links''']]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%. Following is the overall improvement report by Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Optimized the SQL query in leaderboard_helper.rb to replace multiple database calls.&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| All the participants associated with computed assignment list are calculated in a single database call and cached in memory rather than calling repetitively within loop.&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Database calls to ''Assignments'' table was reduced as result of removing it from multiple loops. Supporting data structure and caching enabled to achieve this reduction.&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Upon careful code investigation, we felt there is no need of any database calls to assignment_questionnaires table. This contains mapping of assignment id and questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Leaderboard reads the scores from ''ScoreCache'' table, which has ''revieweeId'' and a response object_type (''ReviewResponseMap'', ''AuthorFeedbackResponseMap'', etc.). Refactored code reuses the association of ''response object_type'' to the ''questionnaire_type'' and reduces the usage to 0. this is the most significant reduction in database calls. &lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| ScoreCache table has a field - ''revieweeId'' which can be either ''participantId'' or ''teamId''. All repetitive database calls was reduced to a single call by combining target participantId and teamId as a list of ''revieweeId''.&lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Teams table was repetitively called within a loop to retrieve participation in a set of assignments. It was pulled out of the loop and modified to get the same result for all the teams for a larger set of assignments.&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Leaderboards table was called multiple times to retrieve the Label for scores of corresponding questionnaire type. e.g. ''&amp;quot;ReviewQuestionnaire&amp;quot; - &amp;quot;Submitted Work&amp;quot;''. It was reduced to fetch all such mapping and cached.&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
Based on use case and requirement, we can implement a metric to calculate final scores based on weights of an assignment or a questionnaire type. However, it solely depends on the the requirement whether such logic should be implemented in the Leaderboard model or the Score computation model. The team recommends that such manipulation and calculation of scores should not be part of Leaderboard model. Leaderboard model should focus on determining the eligible participants and compute the final leaderboard list.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90906</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90906"/>
		<updated>2014-10-29T22:25:12Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Code Optimization */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;TestingLinks&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza instance links&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | '''username= &amp;quot;user480&amp;quot;&amp;lt;br /&amp;gt;password= &amp;quot;password&amp;quot;'''&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note for testing :''' It is recommended that in order to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there are other existing users who have participated in the same assignment.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[#TestingLinks|'''Expertiza Test instances links''']]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%. Following is the overall improvement report by Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Optimized the SQL query in leaderboard_helper.rb to replace multiple database calls.&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| All the participants associated with computed assignment list are calculated in a single database call and cached in memory rather than calling repetitively within loop.&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Database calls to ''Assignments'' table was reduced as result of removing it from multiple loops. Supporting data structure and caching enabled to achieve this reduction.&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Upon careful code investigation, we felt there is no need of any database calls to assignment_questionnaires table. This contains mapping of assignment id and questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Leaderboard reads the scores from ''ScoreCache'' table, which has ''revieweeId'' and a response object_type (''ReviewResponseMap'', ''AuthorFeedbackResponseMap'', etc.). Refactored code reuses the association of ''response object_type'' to the ''questionnaire_type'' and reduces the usage to 0. this is the most significant reduction in database calls. &lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| ScoreCache table has a field - ''revieweeId'' which can be either ''participantId'' or ''teamId''. All repetitive database calls was reduced to a single call by combining target participantId and teamId as a list of ''revieweeId''.&lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Teams table was repetitively called within a loop to retrieve participation in a set of assignments. It was pulled out of the loop and modified to get the same result for all the teams for a larger set of assignments.&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Leaderboards table was called multiple times to retrieve the Label for scores of corresponding questionnaire type. e.g. ''&amp;quot;ReviewQuestionnaire&amp;quot; - &amp;quot;Submitted Work&amp;quot;''. It was reduced to fetch all such mapping and cached.&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
Based on use case and requirement, we can implement a metric to calculate final scores based on weights of an assignment or a questionnaire type. However, it solely depends on the the requirement whether such logic should be implemented in the Leaderboard model or the Score computation model. The team recommends that such manipulation and calculation of scores should not be part of Leaderboard model. Leaderboard model should focus on determining the eligible participants and compute the final leaderboard list.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90905</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90905"/>
		<updated>2014-10-29T22:24:46Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Changes in Model */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;TestingLinks&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza instance links&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | '''username= &amp;quot;user480&amp;quot;&amp;lt;br /&amp;gt;password= &amp;quot;password&amp;quot;'''&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note for testing :''' It is recommended that in order to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there are other existing users who have participated in the same assignment.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[#TestingLinks|'''Expertiza Test instances links''']]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%. Following is the overall improvement report by Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Optimized the SQL query in leaderboard_helper.rb to replace multiple database calls.&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| All the participants associated with computed assignment list are calculated in a single database call and cached in memory rather than calling repetitively within loop.&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Database calls to ''Assignments'' table was reduced as result of removing it from multiple loops. Supporting data structure and caching enabled to achieve this reduction.&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Upon careful code investigation, we felt there is no need of any database calls to assignment_questionnaires table. This contains mapping of assignment id and questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Leaderboard reads the scores from ''ScoreCache'' table, which has ''revieweeId'' and a response object_type (''ReviewResponseMap'', ''AuthorFeedbackResponseMap'', etc.). Refactored code reuses the association of ''response object_type'' to the ''questionnaire_type'' and reduces the usage to 0. this is the most significant reduction in database calls. &lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| ScoreCache table has a field - ''revieweeId'' which can be either ''participantId'' or ''teamId''. All repetitive database calls was reduced to a single call by combining target participantId and teamId as a list of ''revieweeId''.&lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Teams table was repetitively called within a loop to retrieve participation in a set of assignments. It was pulled out of the loop and modified to get the same result for all the teams for a larger set of assignments.&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Leaderboards table was called multiple times to retrieve the Label for scores of corresponding questionnaire type. e.g. ''&amp;quot;ReviewQuestionnaire&amp;quot; - &amp;quot;Submitted Work&amp;quot;''. It was reduced to fetch all such mapping and cached.&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
Based on use case and requirement, we can implement a metric to calculate final scores based on weights of an assignment or a questionnaire type. However, it solely depends on the the requirement whether such logic should be implemented in the Leaderboard model or the Score computation model. The team recommends that such manipulation and calculation of scores should not be part of Leaderboard model. Leaderboard model should focus on determining the eligible participants and compute the final leaderboard list.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90904</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90904"/>
		<updated>2014-10-29T22:24:05Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Existing Functionality */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;TestingLinks&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza instance links&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | '''username= &amp;quot;user480&amp;quot;&amp;lt;br /&amp;gt;password= &amp;quot;password&amp;quot;'''&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note for testing :''' It is recommended that in order to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there are other existing users who have participated in the same assignment.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[#TestingLinks|'''Expertiza Test instances links''']]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%. Following is the overall improvement report by Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Optimized the SQL query in leaderboard_helper.rb to replace multiple database calls.&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| All the participants associated with computed assignment list are calculated in a single database call and cached in memory rather than calling repetitively within loop.&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Database calls to ''Assignments'' table was reduced as result of removing it from multiple loops. Supporting data structure and caching enabled to achieve this reduction.&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Upon careful code investigation, we felt there is no need of any database calls to assignment_questionnaires table. This contains mapping of assignment id and questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Leaderboard reads the scores from ''ScoreCache'' table, which has ''revieweeId'' and a response object_type (''ReviewResponseMap'', ''AuthorFeedbackResponseMap'', etc.). Refactored code reuses the association of ''response object_type'' to the ''questionnaire_type'' and reduces the usage to 0. this is the most significant reduction in database calls. &lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| ScoreCache table has a field - ''revieweeId'' which can be either ''participantId'' or ''teamId''. All repetitive database calls was reduced to a single call by combining target participantId and teamId as a list of ''revieweeId''.&lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Teams table was repetitively called within a loop to retrieve participation in a set of assignments. It was pulled out of the loop and modified to get the same result for all the teams for a larger set of assignments.&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Leaderboards table was called multiple times to retrieve the Label for scores of corresponding questionnaire type. e.g. ''&amp;quot;ReviewQuestionnaire&amp;quot; - &amp;quot;Submitted Work&amp;quot;''. It was reduced to fetch all such mapping and cached.&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
Based on use case and requirement, we can implement a metric to calculate final scores based on weights of an assignment or a questionnaire type. However, it solely depends on the the requirement whether such logic should be implemented in the Leaderboard model or the Score computation model. The team recommends that such manipulation and calculation of scores should not be part of Leaderboard model. Leaderboard model should focus on determining the eligible participants and compute the final leaderboard list.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90902</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90902"/>
		<updated>2014-10-29T22:23:03Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Existing Functionality */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;TestingLinks&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza instance links&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | '''username= &amp;quot;user480&amp;quot;&amp;lt;br /&amp;gt;password= &amp;quot;password&amp;quot;'''&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code style=&amp;quot;background:F0F0FF&amp;quot;&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code style=&amp;quot;background:F0F0FF&amp;quot;&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code style=&amp;quot;background:F0F0FF&amp;quot;&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code style=&amp;quot;background:F0F0FF&amp;quot;&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note for testing :''' It is recommended that in order to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there are other existing users who have participated in the same assignment.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[#TestingLinks|'''Expertiza Test instances links''']]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%. Following is the overall improvement report by Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Optimized the SQL query in leaderboard_helper.rb to replace multiple database calls.&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| All the participants associated with computed assignment list are calculated in a single database call and cached in memory rather than calling repetitively within loop.&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Database calls to ''Assignments'' table was reduced as result of removing it from multiple loops. Supporting data structure and caching enabled to achieve this reduction.&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Upon careful code investigation, we felt there is no need of any database calls to assignment_questionnaires table. This contains mapping of assignment id and questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Leaderboard reads the scores from ''ScoreCache'' table, which has ''revieweeId'' and a response object_type (''ReviewResponseMap'', ''AuthorFeedbackResponseMap'', etc.). Refactored code reuses the association of ''response object_type'' to the ''questionnaire_type'' and reduces the usage to 0. this is the most significant reduction in database calls. &lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| ScoreCache table has a field - ''revieweeId'' which can be either ''participantId'' or ''teamId''. All repetitive database calls was reduced to a single call by combining target participantId and teamId as a list of ''revieweeId''.&lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Teams table was repetitively called within a loop to retrieve participation in a set of assignments. It was pulled out of the loop and modified to get the same result for all the teams for a larger set of assignments.&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Leaderboards table was called multiple times to retrieve the Label for scores of corresponding questionnaire type. e.g. ''&amp;quot;ReviewQuestionnaire&amp;quot; - &amp;quot;Submitted Work&amp;quot;''. It was reduced to fetch all such mapping and cached.&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
Based on use case and requirement, we can implement a metric to calculate final scores based on weights of an assignment or a questionnaire type. However, it solely depends on the the requirement whether such logic should be implemented in the Leaderboard model or the Score computation model. The team recommends that such manipulation and calculation of scores should not be part of Leaderboard model. Leaderboard model should focus on determining the eligible participants and compute the final leaderboard list.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90899</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90899"/>
		<updated>2014-10-29T22:20:57Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Existing Functionality */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;TestingLinks&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza instance links&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | '''username= &amp;quot;user480&amp;quot;&amp;lt;br /&amp;gt;password= &amp;quot;password&amp;quot;'''&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code F0F0FF&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code F0F0FF&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code F0F0FF&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code F0F0FF&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note for testing :''' It is recommended that in order to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there are other existing users who have participated in the same assignment.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[#TestingLinks|'''Expertiza Test instances links''']]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%. Following is the overall improvement report by Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Optimized the SQL query in leaderboard_helper.rb to replace multiple database calls.&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| All the participants associated with computed assignment list are calculated in a single database call and cached in memory rather than calling repetitively within loop.&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Database calls to ''Assignments'' table was reduced as result of removing it from multiple loops. Supporting data structure and caching enabled to achieve this reduction.&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Upon careful code investigation, we felt there is no need of any database calls to assignment_questionnaires table. This contains mapping of assignment id and questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Leaderboard reads the scores from ''ScoreCache'' table, which has ''revieweeId'' and a response object_type (''ReviewResponseMap'', ''AuthorFeedbackResponseMap'', etc.). Refactored code reuses the association of ''response object_type'' to the ''questionnaire_type'' and reduces the usage to 0. this is the most significant reduction in database calls. &lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| ScoreCache table has a field - ''revieweeId'' which can be either ''participantId'' or ''teamId''. All repetitive database calls was reduced to a single call by combining target participantId and teamId as a list of ''revieweeId''.&lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Teams table was repetitively called within a loop to retrieve participation in a set of assignments. It was pulled out of the loop and modified to get the same result for all the teams for a larger set of assignments.&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Leaderboards table was called multiple times to retrieve the Label for scores of corresponding questionnaire type. e.g. ''&amp;quot;ReviewQuestionnaire&amp;quot; - &amp;quot;Submitted Work&amp;quot;''. It was reduced to fetch all such mapping and cached.&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
Based on use case and requirement, we can implement a metric to calculate final scores based on weights of an assignment or a questionnaire type. However, it solely depends on the the requirement whether such logic should be implemented in the Leaderboard model or the Score computation model. The team recommends that such manipulation and calculation of scores should not be part of Leaderboard model. Leaderboard model should focus on determining the eligible participants and compute the final leaderboard list.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90897</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90897"/>
		<updated>2014-10-29T22:20:19Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Project Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;TestingLinks&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza instance links&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | '''username= &amp;quot;user480&amp;quot;&amp;lt;br /&amp;gt;password= &amp;quot;password&amp;quot;'''&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code style=&amp;quot;background:#F0F0FF&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note for testing :''' It is recommended that in order to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there are other existing users who have participated in the same assignment.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[#TestingLinks|'''Expertiza Test instances links''']]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%. Following is the overall improvement report by Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Optimized the SQL query in leaderboard_helper.rb to replace multiple database calls.&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| All the participants associated with computed assignment list are calculated in a single database call and cached in memory rather than calling repetitively within loop.&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Database calls to ''Assignments'' table was reduced as result of removing it from multiple loops. Supporting data structure and caching enabled to achieve this reduction.&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Upon careful code investigation, we felt there is no need of any database calls to assignment_questionnaires table. This contains mapping of assignment id and questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Leaderboard reads the scores from ''ScoreCache'' table, which has ''revieweeId'' and a response object_type (''ReviewResponseMap'', ''AuthorFeedbackResponseMap'', etc.). Refactored code reuses the association of ''response object_type'' to the ''questionnaire_type'' and reduces the usage to 0. this is the most significant reduction in database calls. &lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| ScoreCache table has a field - ''revieweeId'' which can be either ''participantId'' or ''teamId''. All repetitive database calls was reduced to a single call by combining target participantId and teamId as a list of ''revieweeId''.&lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Teams table was repetitively called within a loop to retrieve participation in a set of assignments. It was pulled out of the loop and modified to get the same result for all the teams for a larger set of assignments.&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Leaderboards table was called multiple times to retrieve the Label for scores of corresponding questionnaire type. e.g. ''&amp;quot;ReviewQuestionnaire&amp;quot; - &amp;quot;Submitted Work&amp;quot;''. It was reduced to fetch all such mapping and cached.&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
Based on use case and requirement, we can implement a metric to calculate final scores based on weights of an assignment or a questionnaire type. However, it solely depends on the the requirement whether such logic should be implemented in the Leaderboard model or the Score computation model. The team recommends that such manipulation and calculation of scores should not be part of Leaderboard model. Leaderboard model should focus on determining the eligible participants and compute the final leaderboard list.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90893</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90893"/>
		<updated>2014-10-29T22:15:40Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Project Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;TestingLinks&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza instance links&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | '''username= &amp;quot;user480&amp;quot;&amp;lt;br /&amp;gt;password= &amp;quot;password&amp;quot;'''&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code style=&amp;quot;background:#E6E6FA&amp;quot;&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code style=&amp;quot;background:#E6E6FA&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code style=&amp;quot;background:#E6E6FA&amp;quot;&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code style=&amp;quot;background:#E6E6FA&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note for testing :''' It is recommended that in order to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there are other existing users who have participated in the same assignment.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[#TestingLinks|'''Expertiza Test instances links''']]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%. Following is the overall improvement report by Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Optimized the SQL query in leaderboard_helper.rb to replace multiple database calls.&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| All the participants associated with computed assignment list are calculated in a single database call and cached in memory rather than calling repetitively within loop.&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Database calls to ''Assignments'' table was reduced as result of removing it from multiple loops. Supporting data structure and caching enabled to achieve this reduction.&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Upon careful code investigation, we felt there is no need of any database calls to assignment_questionnaires table. This contains mapping of assignment id and questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Leaderboard reads the scores from ''ScoreCache'' table, which has ''revieweeId'' and a response object_type (''ReviewResponseMap'', ''AuthorFeedbackResponseMap'', etc.). Refactored code reuses the association of ''response object_type'' to the ''questionnaire_type'' and reduces the usage to 0. this is the most significant reduction in database calls. &lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| ScoreCache table has a field - ''revieweeId'' which can be either ''participantId'' or ''teamId''. All repetitive database calls was reduced to a single call by combining target participantId and teamId as a list of ''revieweeId''.&lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Teams table was repetitively called within a loop to retrieve participation in a set of assignments. It was pulled out of the loop and modified to get the same result for all the teams for a larger set of assignments.&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Leaderboards table was called multiple times to retrieve the Label for scores of corresponding questionnaire type. e.g. ''&amp;quot;ReviewQuestionnaire&amp;quot; - &amp;quot;Submitted Work&amp;quot;''. It was reduced to fetch all such mapping and cached.&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
Based on use case and requirement, we can implement a metric to calculate final scores based on weights of an assignment or a questionnaire type. However, it solely depends on the the requirement whether such logic should be implemented in the Leaderboard model or the Score computation model. The team recommends that such manipulation and calculation of scores should not be part of Leaderboard model. Leaderboard model should focus on determining the eligible participants and compute the final leaderboard list.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90892</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90892"/>
		<updated>2014-10-29T22:14:37Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Project Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;TestingLinks&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza instance links&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | '''username= &amp;quot;user480&amp;quot;&amp;lt;br /&amp;gt;password= &amp;quot;password&amp;quot;'''&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code style=&amp;quot;background:#F0F8FF&amp;quot;&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code style=&amp;quot;background:#F0F8FF&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code style=&amp;quot;background:#F0F8FF&amp;quot;&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code style=&amp;quot;background:#F0F8FF&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note for testing :''' It is recommended that in order to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there are other existing users who have participated in the same assignment.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[#TestingLinks|'''Expertiza Test instances links''']]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%. Following is the overall improvement report by Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Optimized the SQL query in leaderboard_helper.rb to replace multiple database calls.&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| All the participants associated with computed assignment list are calculated in a single database call and cached in memory rather than calling repetitively within loop.&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Database calls to ''Assignments'' table was reduced as result of removing it from multiple loops. Supporting data structure and caching enabled to achieve this reduction.&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Upon careful code investigation, we felt there is no need of any database calls to assignment_questionnaires table. This contains mapping of assignment id and questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Leaderboard reads the scores from ''ScoreCache'' table, which has ''revieweeId'' and a response object_type (''ReviewResponseMap'', ''AuthorFeedbackResponseMap'', etc.). Refactored code reuses the association of ''response object_type'' to the ''questionnaire_type'' and reduces the usage to 0. this is the most significant reduction in database calls. &lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| ScoreCache table has a field - ''revieweeId'' which can be either ''participantId'' or ''teamId''. All repetitive database calls was reduced to a single call by combining target participantId and teamId as a list of ''revieweeId''.&lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Teams table was repetitively called within a loop to retrieve participation in a set of assignments. It was pulled out of the loop and modified to get the same result for all the teams for a larger set of assignments.&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Leaderboards table was called multiple times to retrieve the Label for scores of corresponding questionnaire type. e.g. ''&amp;quot;ReviewQuestionnaire&amp;quot; - &amp;quot;Submitted Work&amp;quot;''. It was reduced to fetch all such mapping and cached.&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
Based on use case and requirement, we can implement a metric to calculate final scores based on weights of an assignment or a questionnaire type. However, it solely depends on the the requirement whether such logic should be implemented in the Leaderboard model or the Score computation model. The team recommends that such manipulation and calculation of scores should not be part of Leaderboard model. Leaderboard model should focus on determining the eligible participants and compute the final leaderboard list.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90891</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90891"/>
		<updated>2014-10-29T22:14:23Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Project Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;TestingLinks&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza instance links&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | '''username= &amp;quot;user480&amp;quot;&amp;lt;br /&amp;gt;password= &amp;quot;password&amp;quot;'''&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code style=&amp;quot;background:#F0F8FF&amp;quot;&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code style=&amp;quot;background:#F0F8FF&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code style=&amp;quot;background:#F0F8FF&amp;quot;&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code style=background:#F0F8FF&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note for testing :''' It is recommended that in order to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there are other existing users who have participated in the same assignment.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[#TestingLinks|'''Expertiza Test instances links''']]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%. Following is the overall improvement report by Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Optimized the SQL query in leaderboard_helper.rb to replace multiple database calls.&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| All the participants associated with computed assignment list are calculated in a single database call and cached in memory rather than calling repetitively within loop.&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Database calls to ''Assignments'' table was reduced as result of removing it from multiple loops. Supporting data structure and caching enabled to achieve this reduction.&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Upon careful code investigation, we felt there is no need of any database calls to assignment_questionnaires table. This contains mapping of assignment id and questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Leaderboard reads the scores from ''ScoreCache'' table, which has ''revieweeId'' and a response object_type (''ReviewResponseMap'', ''AuthorFeedbackResponseMap'', etc.). Refactored code reuses the association of ''response object_type'' to the ''questionnaire_type'' and reduces the usage to 0. this is the most significant reduction in database calls. &lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| ScoreCache table has a field - ''revieweeId'' which can be either ''participantId'' or ''teamId''. All repetitive database calls was reduced to a single call by combining target participantId and teamId as a list of ''revieweeId''.&lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Teams table was repetitively called within a loop to retrieve participation in a set of assignments. It was pulled out of the loop and modified to get the same result for all the teams for a larger set of assignments.&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Leaderboards table was called multiple times to retrieve the Label for scores of corresponding questionnaire type. e.g. ''&amp;quot;ReviewQuestionnaire&amp;quot; - &amp;quot;Submitted Work&amp;quot;''. It was reduced to fetch all such mapping and cached.&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
Based on use case and requirement, we can implement a metric to calculate final scores based on weights of an assignment or a questionnaire type. However, it solely depends on the the requirement whether such logic should be implemented in the Leaderboard model or the Score computation model. The team recommends that such manipulation and calculation of scores should not be part of Leaderboard model. Leaderboard model should focus on determining the eligible participants and compute the final leaderboard list.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90890</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90890"/>
		<updated>2014-10-29T22:13:51Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Project Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;TestingLinks&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza instance links&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | '''username= &amp;quot;user480&amp;quot;&amp;lt;br /&amp;gt;password= &amp;quot;password&amp;quot;'''&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code style=&amp;quot;background:#F0F8FF&amp;quot;&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code &amp;quot;background:#F0F8FF&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code &amp;quot;background:#F0F8FF&amp;quot;&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code &amp;quot;background:#F0F8FF&amp;quot;&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note for testing :''' It is recommended that in order to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there are other existing users who have participated in the same assignment.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[#TestingLinks|'''Expertiza Test instances links''']]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%. Following is the overall improvement report by Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Optimized the SQL query in leaderboard_helper.rb to replace multiple database calls.&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| All the participants associated with computed assignment list are calculated in a single database call and cached in memory rather than calling repetitively within loop.&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Database calls to ''Assignments'' table was reduced as result of removing it from multiple loops. Supporting data structure and caching enabled to achieve this reduction.&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Upon careful code investigation, we felt there is no need of any database calls to assignment_questionnaires table. This contains mapping of assignment id and questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Leaderboard reads the scores from ''ScoreCache'' table, which has ''revieweeId'' and a response object_type (''ReviewResponseMap'', ''AuthorFeedbackResponseMap'', etc.). Refactored code reuses the association of ''response object_type'' to the ''questionnaire_type'' and reduces the usage to 0. this is the most significant reduction in database calls. &lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| ScoreCache table has a field - ''revieweeId'' which can be either ''participantId'' or ''teamId''. All repetitive database calls was reduced to a single call by combining target participantId and teamId as a list of ''revieweeId''.&lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Teams table was repetitively called within a loop to retrieve participation in a set of assignments. It was pulled out of the loop and modified to get the same result for all the teams for a larger set of assignments.&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Leaderboards table was called multiple times to retrieve the Label for scores of corresponding questionnaire type. e.g. ''&amp;quot;ReviewQuestionnaire&amp;quot; - &amp;quot;Submitted Work&amp;quot;''. It was reduced to fetch all such mapping and cached.&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
Based on use case and requirement, we can implement a metric to calculate final scores based on weights of an assignment or a questionnaire type. However, it solely depends on the the requirement whether such logic should be implemented in the Leaderboard model or the Score computation model. The team recommends that such manipulation and calculation of scores should not be part of Leaderboard model. Leaderboard model should focus on determining the eligible participants and compute the final leaderboard list.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90881</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90881"/>
		<updated>2014-10-29T22:03:46Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Changes in Model */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;TestingLinks&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza instance links&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | '''username= &amp;quot;user480&amp;quot;&amp;lt;br /&amp;gt;password= &amp;quot;password&amp;quot;'''&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note for testing :''' It is recommended that in order to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there are other existing users who have participated in the same assignment.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[#TestingLinks|'''Expertiza Test instances links''']]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%. Following is the overall improvement report by Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Optimized the SQL query in leaderboard_helper.rb to replace multiple database calls.&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| All the participants associated with computed Assignment list are calculated in a single database call and cached in memory rather than calling repetitively.&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Database calls to Assignments table was reduced as result of removing it from multiple loops. Supporting data structure and caching enabled to achieve this.&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Upon careful code investigation, we felt there is no need of any database calls to assignment_questionnaires table. This contains mapping of assignment id and questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Leaderboard reads the scores from ScoreCache, which has revieweeId and a response object_type (''ReviewResponseMap'', ''AuthorFeedbackResponseMap'', etc.). Refactored code reuses the association of response object_type to the questionnaire_type and reduces the usage to 0.&lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
Based on use case and requirement, we can implement a metric to calculate final scores based on weights of an assignment or a questionnaire type. However, it solely depends on the the requirement whether such logic should be implemented in the Leaderboard model or the Score computation model. The team recommends that such manipulation and calculation of scores should not be part of Leaderboard model. Leaderboard model should focus on determining the eligible participants and compute the final leaderboard list.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90878</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90878"/>
		<updated>2014-10-29T22:03:28Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Existing Functionality */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;TestingLinks&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza instance links&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | '''username= &amp;quot;user480&amp;quot;&amp;lt;br /&amp;gt;password= &amp;quot;password&amp;quot;'''&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:2%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note for testing :''' It is recommended that in order to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there are other existing users who have participated in the same assignment.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[#TestingLinks|'''Expertiza Test instances links''']]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%. Following is the overall improvement report by Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Optimized the SQL query in leaderboard_helper.rb to replace multiple database calls.&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| All the participants associated with computed Assignment list are calculated in a single database call and cached in memory rather than calling repetitively.&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Database calls to Assignments table was reduced as result of removing it from multiple loops. Supporting data structure and caching enabled to achieve this.&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Upon careful code investigation, we felt there is no need of any database calls to assignment_questionnaires table. This contains mapping of assignment id and questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Leaderboard reads the scores from ScoreCache, which has revieweeId and a response object_type (''ReviewResponseMap'', ''AuthorFeedbackResponseMap'', etc.). Refactored code reuses the association of response object_type to the questionnaire_type and reduces the usage to 0.&lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
Based on use case and requirement, we can implement a metric to calculate final scores based on weights of an assignment or a questionnaire type. However, it solely depends on the the requirement whether such logic should be implemented in the Leaderboard model or the Score computation model. The team recommends that such manipulation and calculation of scores should not be part of Leaderboard model. Leaderboard model should focus on determining the eligible participants and compute the final leaderboard list.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90849</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90849"/>
		<updated>2014-10-29T21:14:11Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;TestingLinks&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza Links&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | username= &amp;quot;user480&amp;quot; password= &amp;quot;password&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note for testing :''' It is recommended that in order to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there are other existing users who have participated in the same assignment.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[#TestingLinks|'''Testing Links''']]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%. Following is the overall improvement report by Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Optimized the SQL query in leaderboard_helper.rb to replace multiple database calls.&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| All the participants associated with computed Assignment list are calculated in a single database call and cached in memory rather than calling repetitively.&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Assignem&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
Based on use case and requirement, we can implement a metric to calculate final scores based on weights of an assignment or a questionnaire type. However, it solely depends on the the requirement whether such logic should be implemented in the Leaderboard model or the Score computation model. The team recommends that such manipulation and calculation of scores should not be part of Leaderboard model. Leaderboard model should focus on determining the eligible participants and compute the final leaderboard list.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90848</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90848"/>
		<updated>2014-10-29T21:13:36Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;TestingLinks&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza Link&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | username= &amp;quot;user480&amp;quot; password= &amp;quot;password&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note for testing :''' It is recommended that in order to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there are other existing users who have participated in the same assignment.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[#TestingLinks|'''Testing Links''']]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%. Following is the overall improvement report by Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Optimized the SQL query in leaderboard_helper.rb to replace multiple database calls.&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| All the participants associated with computed Assignment list are calculated in a single database call and cached in memory rather than calling repetitively.&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Assignem&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
Based on use case and requirement, we can implement a metric to calculate final scores based on weights of an assignment or a questionnaire type. However, it solely depends on the the requirement whether such logic should be implemented in the Leaderboard model or the Score computation model. The team recommends that such manipulation and calculation of scores should not be part of Leaderboard model. Leaderboard model should focus on determining the eligible participants and compute the final leaderboard list.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90845</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90845"/>
		<updated>2014-10-29T21:13:08Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;TestingLinks&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza Link&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | username= &amp;quot;user480&amp;quot; password= &amp;quot;password&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note for testing :''' It is recommended that in order to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there are other existing users who have participated in the same assignment.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[#TestingLinks|Testing Links]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%. Following is the overall improvement report by Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Optimized the SQL query in leaderboard_helper.rb to replace multiple database calls.&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| All the participants associated with computed Assignment list are calculated in a single database call and cached in memory rather than calling repetitively.&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Assignem&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
Based on use case and requirement, we can implement a metric to calculate final scores based on weights of an assignment or a questionnaire type. However, it solely depends on the the requirement whether such logic should be implemented in the Leaderboard model or the Score computation model. The team recommends that such manipulation and calculation of scores should not be part of Leaderboard model. Leaderboard model should focus on determining the eligible participants and compute the final leaderboard list.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90843</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90843"/>
		<updated>2014-10-29T21:11:42Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;TestingLinks&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza Link&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | username= &amp;quot;user480&amp;quot; password= &amp;quot;password&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[#TestingLinks|Testing Links]]&lt;br /&gt;
&lt;br /&gt;
'''Note for testing :''' It is recommended that in order to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there are other existing users who have participated in the same assignment.&amp;lt;br /&amp;gt;'''e.g. Username/Password: user480/password'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%. Following is the overall improvement report by Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Optimized the SQL query in leaderboard_helper.rb to replace multiple database calls.&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| All the participants associated with computed Assignment list are calculated in a single database call and cached in memory rather than calling repetitively.&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Assignem&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
Based on use case and requirement, we can implement a metric to calculate final scores based on weights of an assignment or a questionnaire type. However, it solely depends on the the requirement whether such logic should be implemented in the Leaderboard model or the Score computation model. The team recommends that such manipulation and calculation of scores should not be part of Leaderboard model. Leaderboard model should focus on determining the eligible participants and compute the final leaderboard list.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90841</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90841"/>
		<updated>2014-10-29T21:10:58Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;TestingLinks&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza Link&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | username= &amp;quot;user480&amp;quot; password= &amp;quot;password&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
[[#TestingLinks|Testing Links]]&lt;br /&gt;
'''Note for testing :''' It is recommended that in order to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there are other existing users who have participated in the same assignment.&amp;lt;br /&amp;gt;'''e.g. Username/Password: user480/password'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%. Following is the overall improvement report by Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Dummy&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| Dummy&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Dummy&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
Based on use case and requirement, we can implement a metric to calculate final scores based on weights of an assignment or a questionnaire type. However, it solely depends on the the requirement whether such logic should be implemented in the Leaderboard model or the Score computation model. The team recommends that such manipulation and calculation of scores should not be part of Leaderboard model. Leaderboard model should focus on determining the eligible participants and compute the final leaderboard list.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90838</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90838"/>
		<updated>2014-10-29T21:04:58Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;TestingLinks&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza Link&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | username= &amp;quot;user480&amp;quot; password= &amp;quot;password&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%. Following is the overall improvement report by Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Dummy&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| Dummy&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Dummy&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
Based on use case and requirement, we can implement a metric to calculate final scores based on weights of an assignment or a questionnaire type. However, it solely depends on the the requirement whether such logic should be implemented in the Leaderboard model or the Score computation model. The team recommends that such manipulation and calculation of scores should not be part of Leaderboard model. Leaderboard model should focus on determining the eligible participants and compute the final leaderboard list.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90837</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90837"/>
		<updated>2014-10-29T21:04:43Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;TestingLinks&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza Link&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | username= &amp;quot;user480&amp;quot; password= &amp;quot;password&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%. Following is the overall improvement report by Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Dummy&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| Dummy&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Dummy&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
Based on use case and requirement, we can implement a metric to calculate final scores based on weights of an assignment or a questionnaire type. However, it solely depends on the the requirement whether such logic should be implemented in the Leaderboard model or the Score computation model. The team recommends that such manipulation and calculation of scores should not be part of Leaderboard model. Leaderboard model should focus on determining the eligible participants and compute the final leaderboard list.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90829</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90829"/>
		<updated>2014-10-29T21:01:06Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza Link&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | username= &amp;quot;user480&amp;quot; password= &amp;quot;password&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%. Following is the overall improvement report by Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Dummy&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| Dummy&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Dummy&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method &amp;lt;code&amp;gt; getAssignmentMapping &amp;lt;/code&amp;gt;, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90814</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90814"/>
		<updated>2014-10-29T20:51:36Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza Link&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | username= &amp;quot;user480&amp;quot;, password= &amp;quot;password&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center]]&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%.&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Dummy&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| Dummy&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Dummy&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method &amp;lt;code&amp;gt; getAssignmentMapping &amp;lt;/code&amp;gt;, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90808</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90808"/>
		<updated>2014-10-29T20:50:37Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza Link&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code complexity of original leaderboard implementation&lt;br /&gt;
! Code complexity of refactored leaderboard implementation&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_complexity.png|center|frame]]&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
| [[File:Refactored_Leaderboard_stats.png|center|frame]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center]]&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%.&lt;br /&gt;
&lt;br /&gt;
== Database Optimization ==&lt;br /&gt;
We computed the number of data base &amp;quot;SELECT&amp;quot; call generated the database driver by filtering the messages from the rails server. In the original code there were 625 data base select access generated for the leaderboard view. In the new code the number of select calls dropped to 111.&lt;br /&gt;
Shown below is the number of select calls generated per table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Table Name&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
! Comment&lt;br /&gt;
|-&lt;br /&gt;
| roles&lt;br /&gt;
| 52&lt;br /&gt;
| 13&lt;br /&gt;
| Dummy&lt;br /&gt;
|-&lt;br /&gt;
| users&lt;br /&gt;
| 25&lt;br /&gt;
| 25&lt;br /&gt;
| No Change&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| 111&lt;br /&gt;
| 3&lt;br /&gt;
| Dummy&lt;br /&gt;
|-&lt;br /&gt;
| assignments&lt;br /&gt;
| 16&lt;br /&gt;
| 5&lt;br /&gt;
| Dummy&lt;br /&gt;
|-&lt;br /&gt;
| assignment_questionnaires&lt;br /&gt;
| 11&lt;br /&gt;
| 0&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| questionnaires&lt;br /&gt;
| 311&lt;br /&gt;
| 0&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| score_caches&lt;br /&gt;
| 22&lt;br /&gt;
| 1&lt;br /&gt;
| Optimized &lt;br /&gt;
|-&lt;br /&gt;
| teams&lt;br /&gt;
| 11&lt;br /&gt;
| 2&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| teams_users&lt;br /&gt;
| 52&lt;br /&gt;
| 52&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
| leaderboards&lt;br /&gt;
| 9&lt;br /&gt;
| 5&lt;br /&gt;
| Optimized&lt;br /&gt;
|-&lt;br /&gt;
| courses&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| No change&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method &amp;lt;code&amp;gt; getAssignmentMapping &amp;lt;/code&amp;gt;, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90777</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90777"/>
		<updated>2014-10-29T20:34:12Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Changes in Helper */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza Link&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4 database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced by a |single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center]]&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%.&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method &amp;lt;code&amp;gt; getAssignmentMapping &amp;lt;/code&amp;gt;, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90775</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90775"/>
		<updated>2014-10-29T20:32:30Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Existing Functionality */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza Link&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to reduction in overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center]]&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%.&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method &amp;lt;code&amp;gt; getAssignmentMapping &amp;lt;/code&amp;gt;, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90770</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90770"/>
		<updated>2014-10-29T20:27:54Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Project Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza Link&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex &amp;lt;code&amp;gt;(Complexity=142)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to enhancement of overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center]]&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%.&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method &amp;lt;code&amp;gt; getAssignmentMapping &amp;lt;/code&amp;gt;, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90768</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90768"/>
		<updated>2014-10-29T20:27:27Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Changes In Model */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza Link&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex (Complexity=142).&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to enhancement of overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes in Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center]]&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%.&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method &amp;lt;code&amp;gt; getAssignmentMapping &amp;lt;/code&amp;gt;, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90766</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90766"/>
		<updated>2014-10-29T20:27:13Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Changes In Helper (leaderboard_helper.rb) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza Link&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex (Complexity=142).&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to enhancement of overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes In Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes in Helper =&lt;br /&gt;
&lt;br /&gt;
Changes made in methods of Helper &amp;lt;code&amp;gt; leaderboard_helper.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center]]&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%.&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method &amp;lt;code&amp;gt; getAssignmentMapping &amp;lt;/code&amp;gt;, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90762</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90762"/>
		<updated>2014-10-29T20:23:59Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Changes In Model (leaderboard.rb) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza Link&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex (Complexity=142).&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to enhancement of overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes In Model =&lt;br /&gt;
&lt;br /&gt;
Changes made in the methods of model &amp;lt;code&amp;gt; '''leaderboard.rb''' &amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes In Helper (leaderboard_helper.rb) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center]]&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%.&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method &amp;lt;code&amp;gt; getAssignmentMapping &amp;lt;/code&amp;gt;, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90744</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90744"/>
		<updated>2014-10-29T20:16:51Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work and Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza Link&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex (Complexity=142).&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to enhancement of overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes In Model (leaderboard.rb) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes In Helper (leaderboard_helper.rb) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center]]&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%.&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method &amp;lt;code&amp;gt; getAssignmentMapping &amp;lt;/code&amp;gt;, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90743</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90743"/>
		<updated>2014-10-29T20:16:18Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire type ( &amp;lt;code&amp;gt; Reviwed by Author, Reviewed by Teammates, Submitted Work, Reviewer &amp;lt;/code&amp;gt;), in each course. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza Link&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex (Complexity=142).&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard.rb class gets all the assignments within all the courses taken by currently logged in user. It also fetches any independent assignments (not associated with any course), that the user has taken. Then, it fetches all the participants who have participated in the computed list of assignments and aggregates their scores based on the questionnaire type. Several questionnaire type is associated with a single assignment. e.g. Direwolf application has - ''Review Questionnaire'', ''Author Feedback Questionnaire'' and ''Teammate Review Questionnaire''.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to enhancement of overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes In Model (leaderboard.rb) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes In Helper (leaderboard_helper.rb) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the original instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center]]&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%.&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method &amp;lt;code&amp;gt; getAssignmentMapping &amp;lt;/code&amp;gt;, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90732</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90732"/>
		<updated>2014-10-29T20:02:50Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
'''Project name: [https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]'''&amp;lt;ref&amp;gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit E1467: Expertiza - Refactoring LeaderBoard model]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the ''&amp;quot;Leaderboard&amp;quot;'' functionality of the web application [https://github.com/expertiza/expertiza Expertiza]&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza]&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The leaderboard functionality is to show top 3 individual scorers in each questionnaire types, in each courses. The leaderboard also shows the current standing of the logged in user under personal achievements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable floatright&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | Expertiza Link&lt;br /&gt;
|-&lt;br /&gt;
| Refactored Instance&lt;br /&gt;
| http://152.1.13.181:3000&lt;br /&gt;
|-&lt;br /&gt;
| Original Instance&lt;br /&gt;
| http://152.1.13.181:3001&lt;br /&gt;
|}&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
'''Classes involved:''' ''leaderboard.rb'' and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex (Complexity=142).&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard class gets all the assignments within all the courses taken by currently logged in user. It&lt;br /&gt;
also fetches any independent assignments (not associated with any course), that the user has taken.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_controller.rb &amp;lt;/code&amp;gt; and associated views files. We have also refactored ambiguous variable and method names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and computation. We have refactored many files related to Leaderboard implementation leading to enhancement of overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes In Model (leaderboard.rb) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Separate db call for each user assignment.&lt;br /&gt;
| Single db call with an array of assignment ids.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code. Appends each entry to the end of list&lt;br /&gt;
| Used concat to clarify that we are adding the independent and other assignments in courses. &lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call unlike several within the loop in its prior implementation. We have also removed redundant code computation and made the logic easier to understand. The overall complexity of this method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing name and hard to follow logic.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was refactored on various aspects like reducing database calls drastically, removing redundant code computation, redundant data storage in complex group of hashes and series of conditional statements. We would like to mention that previously, the method had 10 database calls within loop and 1 outside loop. After refactoring, the new method has just 1 database call within loop and 3 outside loops. Also, the overall code complexity is reduced from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes In Helper (leaderboard_helper.rb) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the orignal instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. &amp;lt;b&amp;gt;We changed the order in which the output is displayed to make it more coherent.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_personal_achievement_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
The refactoring process included reducing the database calls, loops and redundant storage and computation in all classes associated with Leaderboard functionality. While refactoring, the team has ensured to improve the readability of the code too by renaming ambiguous method and variable names and adding relevant comments to explain the objective of a code construct.&lt;br /&gt;
&lt;br /&gt;
== Code Optimization ==&lt;br /&gt;
&lt;br /&gt;
In the project description code complexity has been highlighted for several methods. [https://codeclimate.com/ Code Climate]&amp;lt;ref&amp;gt;[https://codeclimate.com/ Code Climate]&amp;lt;/ref&amp;gt; has been used to measure the code complexity of the current repository of Expertiza. After refactoring, we used the same tool i.e. Code Climate to measure the code complexity. Following is the snapshot of code complexity of &amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt; from Code Climate.&lt;br /&gt;
&lt;br /&gt;
[[File:CodeClimate_codecomplexity.png|center]]&lt;br /&gt;
&lt;br /&gt;
The report shows that all the 3 methods to be refactored have improved code complexity by over 50%.&lt;br /&gt;
&lt;br /&gt;
== Performance Optimization ==&lt;br /&gt;
&lt;br /&gt;
Google Chrome extension [https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://chrome.google.com/webstore/detail/page-load-time/fploionmjgeclbkemipmkogoaohcdbig?hl=en Page Load Time]&amp;lt;/ref&amp;gt; gives time to load a page.&lt;br /&gt;
We tried this extension to measure performance change after refactoring. We noticed that the time to load page reduced by almost 15%.&lt;br /&gt;
&lt;br /&gt;
This table indicates time to load page in seconds&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Iteration&lt;br /&gt;
! Original Version&lt;br /&gt;
! Refactored Version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| 2.08&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| 2.02&lt;br /&gt;
| 1.66&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| 2.01&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.76&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| 1.93&lt;br /&gt;
| 1.72&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
| 1.97&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.74&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
| 1.99&lt;br /&gt;
| 1.71&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
| 2.12&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
| 2.00&lt;br /&gt;
| 1.75&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;Average&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;2.02&amp;lt;/b&amp;gt;&lt;br /&gt;
|&amp;lt;b&amp;gt;1.74&amp;lt;/b&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method &amp;lt;code&amp;gt; getAssignmentMapping &amp;lt;/code&amp;gt;, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90623</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90623"/>
		<updated>2014-10-29T18:26:31Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit#heading=h.p92p30rar40t Writeup Page]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;big&amp;gt;Expertiza - Refactoring LeaderBoard model&amp;lt;/big&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the &amp;quot;Leaderboard&amp;quot; functionality of the web application Expertiza. The Expertiza project is a system to create reusable learning objects through peer review. The classes involved gets all the assignments in the course and all the participants in a course or in an assignment. The responsibility of the leaderboard module is to generate the top 3 individuals which is to be displayed as the leaderboard for the class and a personal leaderboard view to see a personal aggregated score.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
Classes involved: leaderboard.rb and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (Method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex (Complexity=142).&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard class gets all the assignments within all the courses taken by currently logged in user. It&lt;br /&gt;
also fetches any independent assignments (not associated with any course), that the user has taken.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;. We have also refactored ambiguous variable and method&lt;br /&gt;
names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and&lt;br /&gt;
computation. &lt;br /&gt;
We have refactored many files related to Leaderboard implementation leading to&lt;br /&gt;
enhancement of overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes In Model (leaderboard.rb) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call&lt;br /&gt;
unlike several within the loop in its prior implementation. We have also removed redundantcode computation and made the logic easier to understand. The overall complexity of this&lt;br /&gt;
method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally&lt;br /&gt;
by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was&lt;br /&gt;
refactored on various aspects like reducing database calls drastically, removing redundant&lt;br /&gt;
code computation, redundant data storage in complex group of hashes and series of&lt;br /&gt;
conditional statements. We would like to mention that previously, the method had 10&lt;br /&gt;
database calls within loop and 1 outside loop. After refactoring, the new method has just 1&lt;br /&gt;
database call within loop and 3 outside loops. Also, the overall code complexity is reduced&lt;br /&gt;
from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes In Helper (leaderboard_helper.rb) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Refactored Instance : http://152.1.13.181:3000 &amp;lt;br/&amp;gt;&lt;br /&gt;
Original Instance : http://152.1.13.181:3001&lt;br /&gt;
&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the orignal instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same. We changed the order in which the output is displayed to make it more coherent.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method &amp;lt;code&amp;gt; getAssignmentMapping &amp;lt;/code&amp;gt;, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90612</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90612"/>
		<updated>2014-10-29T18:16:17Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit#heading=h.p92p30rar40t Writeup Page]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Expertiza - Refactoring LeaderBoard model'''&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the &amp;quot;Leaderboard&amp;quot; functionality of the web application Expertiza. The Expertiza project is a system to create reusable learning objects through peer review. The classes involved gets all the assignments in the course and all the participants in a course or in an assignment. The responsibility of the leaderboard module is to generate the top 3 individuals which is to be displayed as the leaderboard for the class and a personal leaderboard view to see a personal aggregated score.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
Classes involved: leaderboard.rb and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (Method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex (Complexity=142).&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard class gets all the assignments within all the courses taken by currently logged in user. It&lt;br /&gt;
also fetches any independent assignments (not associated with any course), that the user has taken.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;. We have also refactored ambiguous variable and method&lt;br /&gt;
names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and&lt;br /&gt;
computation. &lt;br /&gt;
We have refactored many files related to Leaderboard implementation leading to&lt;br /&gt;
enhancement of overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes In Model (leaderboard.rb) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call&lt;br /&gt;
unlike several within the loop in its prior implementation. We have also removed redundantcode computation and made the logic easier to understand. The overall complexity of this&lt;br /&gt;
method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally&lt;br /&gt;
by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was&lt;br /&gt;
refactored on various aspects like reducing database calls drastically, removing redundant&lt;br /&gt;
code computation, redundant data storage in complex group of hashes and series of&lt;br /&gt;
conditional statements. We would like to mention that previously, the method had 10&lt;br /&gt;
database calls within loop and 1 outside loop. After refactoring, the new method has just 1&lt;br /&gt;
database call within loop and 3 outside loops. Also, the overall code complexity is reduced&lt;br /&gt;
from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes In Helper (leaderboard_helper.rb) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the orignal instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same &amp;lt;b&amp;gt; except for order in which it is displayed.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of Original Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method &amp;lt;code&amp;gt; getAssignmentMapping &amp;lt;/code&amp;gt;, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
= References=&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90606</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90606"/>
		<updated>2014-10-29T18:12:59Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Future Work */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit#heading=h.p92p30rar40t Writeup Page]&lt;br /&gt;
Expertiza - Refactoring LeaderBoard model&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the &amp;quot;Leaderboard&amp;quot; functionality of the web application Expertiza&amp;lt;ref name=&amp;quot;expertiza&amp;gt;''Expertiza'' http://wikis.lib.ncsu.edu/index.php/Expertiza&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The classes involved gets all the assignments in the course and all the participants in a course or in an assignment. The responsibility of the leaderboard module is to generate the top 3 individuals which is to be displayed as the leaderboard for the class and a personal leaderboard view to see a personal aggregated score.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
Classes involved: leaderboard.rb and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (Method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex (Complexity=142).&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard class gets all the assignments within all the courses taken by currently logged in user. It&lt;br /&gt;
also fetches any independent assignments (not associated with any course), that the user has taken.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;. We have also refactored ambiguous variable and method&lt;br /&gt;
names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and&lt;br /&gt;
computation. &lt;br /&gt;
We have refactored many files related to Leaderboard implementation leading to&lt;br /&gt;
enhancement of overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes In Model (leaderboard.rb) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call&lt;br /&gt;
unlike several within the loop in its prior implementation. We have also removed redundantcode computation and made the logic easier to understand. The overall complexity of this&lt;br /&gt;
method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally&lt;br /&gt;
by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was&lt;br /&gt;
refactored on various aspects like reducing database calls drastically, removing redundant&lt;br /&gt;
code computation, redundant data storage in complex group of hashes and series of&lt;br /&gt;
conditional statements. We would like to mention that previously, the method had 10&lt;br /&gt;
database calls within loop and 1 outside loop. After refactoring, the new method has just 1&lt;br /&gt;
database call within loop and 3 outside loops. Also, the overall code complexity is reduced&lt;br /&gt;
from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes In Helper (leaderboard_helper.rb) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the non refactored instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same except for some cosmetic changes and order in which it is displayed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of non Refactored Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method &amp;lt;code&amp;gt; getAssignmentMapping &amp;lt;/code&amp;gt;, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
= References=&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90605</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90605"/>
		<updated>2014-10-29T18:12:05Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit#heading=h.p92p30rar40t Writeup Page]&lt;br /&gt;
Expertiza - Refactoring LeaderBoard model&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the &amp;quot;Leaderboard&amp;quot; functionality of the web application Expertiza&amp;lt;ref name=&amp;quot;expertiza&amp;gt;''Expertiza'' http://wikis.lib.ncsu.edu/index.php/Expertiza&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The classes involved gets all the assignments in the course and all the participants in a course or in an assignment. The responsibility of the leaderboard module is to generate the top 3 individuals which is to be displayed as the leaderboard for the class and a personal leaderboard view to see a personal aggregated score.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
Classes involved: leaderboard.rb and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (Method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex (Complexity=142).&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard class gets all the assignments within all the courses taken by currently logged in user. It&lt;br /&gt;
also fetches any independent assignments (not associated with any course), that the user has taken.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;. We have also refactored ambiguous variable and method&lt;br /&gt;
names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and&lt;br /&gt;
computation. &lt;br /&gt;
We have refactored many files related to Leaderboard implementation leading to&lt;br /&gt;
enhancement of overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes In Model (leaderboard.rb) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call&lt;br /&gt;
unlike several within the loop in its prior implementation. We have also removed redundantcode computation and made the logic easier to understand. The overall complexity of this&lt;br /&gt;
method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally&lt;br /&gt;
by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was&lt;br /&gt;
refactored on various aspects like reducing database calls drastically, removing redundant&lt;br /&gt;
code computation, redundant data storage in complex group of hashes and series of&lt;br /&gt;
conditional statements. We would like to mention that previously, the method had 10&lt;br /&gt;
database calls within loop and 1 outside loop. After refactoring, the new method has just 1&lt;br /&gt;
database call within loop and 3 outside loops. Also, the overall code complexity is reduced&lt;br /&gt;
from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes In Helper (leaderboard_helper.rb) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
On VCL session there are 2 instances running. On &amp;lt;code&amp;gt; port 3001 &amp;lt;/code&amp;gt; the non refactored instance is setup and on &amp;lt;code&amp;gt; port 3000 &amp;lt;/code&amp;gt; the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same except for some cosmetic changes and order in which it is displayed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of non Refactored Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method getAssignmentMapping, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
= References=&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90604</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90604"/>
		<updated>2014-10-29T18:10:35Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Changes In Helper (leaderboard_helper.rb) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit#heading=h.p92p30rar40t Writeup Page]&lt;br /&gt;
Expertiza - Refactoring LeaderBoard model&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the &amp;quot;Leaderboard&amp;quot; functionality of the web application Expertiza&amp;lt;ref name=&amp;quot;expertiza&amp;gt;''Expertiza'' http://wikis.lib.ncsu.edu/index.php/Expertiza&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The classes involved gets all the assignments in the course and all the participants in a course or in an assignment. The responsibility of the leaderboard module is to generate the top 3 individuals which is to be displayed as the leaderboard for the class and a personal leaderboard view to see a personal aggregated score.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
Classes involved: leaderboard.rb and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (Method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex (Complexity=142).&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard class gets all the assignments within all the courses taken by currently logged in user. It&lt;br /&gt;
also fetches any independent assignments (not associated with any course), that the user has taken.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;. We have also refactored ambiguous variable and method&lt;br /&gt;
names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and&lt;br /&gt;
computation. &lt;br /&gt;
We have refactored many files related to Leaderboard implementation leading to&lt;br /&gt;
enhancement of overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes In Model (leaderboard.rb) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call&lt;br /&gt;
unlike several within the loop in its prior implementation. We have also removed redundantcode computation and made the logic easier to understand. The overall complexity of this&lt;br /&gt;
method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally&lt;br /&gt;
by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was&lt;br /&gt;
refactored on various aspects like reducing database calls drastically, removing redundant&lt;br /&gt;
code computation, redundant data storage in complex group of hashes and series of&lt;br /&gt;
conditional statements. We would like to mention that previously, the method had 10&lt;br /&gt;
database calls within loop and 1 outside loop. After refactoring, the new method has just 1&lt;br /&gt;
database call within loop and 3 outside loops. Also, the overall code complexity is reduced&lt;br /&gt;
from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes In Helper (leaderboard_helper.rb) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; userIsInstructor &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; studentInWhichCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getTop3Leaderboards &amp;lt;/code&amp;gt;&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
On VCL session there are 2 instances running. On port 3001 the non refactored instance is setup and on port 3000 the refactored instance is setup.&lt;br /&gt;
In below images we have shown that the output after refactoring is same except for some cosmetic changes and order in which it is displayed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of non Refactored Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method getAssignmentMapping, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
= References=&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90602</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90602"/>
		<updated>2014-10-29T18:09:23Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Changes In Model (leaderboard.rb) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit#heading=h.p92p30rar40t Writeup Page]&lt;br /&gt;
Expertiza - Refactoring LeaderBoard model&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the &amp;quot;Leaderboard&amp;quot; functionality of the web application Expertiza&amp;lt;ref name=&amp;quot;expertiza&amp;gt;''Expertiza'' http://wikis.lib.ncsu.edu/index.php/Expertiza&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The classes involved gets all the assignments in the course and all the participants in a course or in an assignment. The responsibility of the leaderboard module is to generate the top 3 individuals which is to be displayed as the leaderboard for the class and a personal leaderboard view to see a personal aggregated score.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
Classes involved: leaderboard.rb and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (Method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex (Complexity=142).&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard class gets all the assignments within all the courses taken by currently logged in user. It&lt;br /&gt;
also fetches any independent assignments (not associated with any course), that the user has taken.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;. We have also refactored ambiguous variable and method&lt;br /&gt;
names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and&lt;br /&gt;
computation. &lt;br /&gt;
We have refactored many files related to Leaderboard implementation leading to&lt;br /&gt;
enhancement of overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes In Model (leaderboard.rb) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getIndependantAssignments &amp;lt;/code&amp;gt;&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInCourses &amp;lt;/code&amp;gt;&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; sortHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call&lt;br /&gt;
unlike several within the loop in its prior implementation. We have also removed redundantcode computation and made the logic easier to understand. The overall complexity of this&lt;br /&gt;
method is reduced from 72 to 35.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt;&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| The new method name is &amp;lt;code&amp;gt; addScoreToResultantHash &amp;lt;/code&amp;gt;. As mentioned earlier, this is called internally&lt;br /&gt;
by &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. The complexity of this method is reduced from 67 to 39 .&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is &amp;lt;code&amp;gt; getParticipantsScore &amp;lt;/code&amp;gt;. The method was&lt;br /&gt;
refactored on various aspects like reducing database calls drastically, removing redundant&lt;br /&gt;
code computation, redundant data storage in complex group of hashes and series of&lt;br /&gt;
conditional statements. We would like to mention that previously, the method had 10&lt;br /&gt;
database calls within loop and 1 outside loop. After refactoring, the new method has just 1&lt;br /&gt;
database call within loop and 3 outside loops. Also, the overall code complexity is reduced&lt;br /&gt;
from 142 to 64.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes In Helper (leaderboard_helper.rb) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| userIsInstructor &lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| studentInWhichCourses &lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| getTop3Leaderboards&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! View of Refactored Leaderboard&lt;br /&gt;
! View of non Refactored Leaderboard&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
| [[File:Non_Refactored_Leaderboard_file.jpg|frame|left| ]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method getAssignmentMapping, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
= References=&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90593</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90593"/>
		<updated>2014-10-29T17:46:29Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Expertiza - Refactoring LeaderBoard model */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit#heading=h.p92p30rar40t Writeup Page]&lt;br /&gt;
Expertiza - Refactoring LeaderBoard model&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the &amp;quot;Leaderboard&amp;quot; functionality of the web application Expertiza&amp;lt;ref name=&amp;quot;expertiza&amp;gt;''Expertiza'' http://wikis.lib.ncsu.edu/index.php/Expertiza&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The classes involved gets all the assignments in the course and all the participants in a course or in an assignment. The responsibility of the leaderboard module is to generate the top 3 individuals which is to be displayed as the leaderboard for the class and a personal leaderboard view to see a personal aggregated score.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Project Description=&lt;br /&gt;
Classes involved: leaderboard.rb and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (Method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex (Complexity=142).&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
=Existing Functionality=&lt;br /&gt;
Leaderboard class gets all the assignments within all the courses taken by currently logged in user. It&lt;br /&gt;
also fetches any independent assignments (not associated with any course), that the user has taken.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;. We have also refactored ambiguous variable and method&lt;br /&gt;
names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and&lt;br /&gt;
computation. &lt;br /&gt;
We have refactored many files related to Leaderboard implementation leading to&lt;br /&gt;
enhancement of overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
=Changes In Model (leaderboard.rb) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| getIndependantAssignments&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| getParticipantEntriesInCourses&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| sortHash&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| extractPersonalAchievements&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call&lt;br /&gt;
unlike several within the loop in its prior implementation. We have also removed redundantcode computation and made the logic easier to understand. The overall complexity of this&lt;br /&gt;
method is reduced from 72 to 35 *.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| addEntryToCSHash&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| The new method name is addScoreToResultantHash. As mentioned earlier, this is called internally&lt;br /&gt;
by getParticipantEntriesInAssignmentList. The complexity of this method is reduced from&lt;br /&gt;
67 to 39 *.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| getParticipantEntriesInAssignmentList&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is getParticipantsScore. The method was&lt;br /&gt;
refactored on various aspects like reducing database calls drastically, removing redundant&lt;br /&gt;
code computation, redundant data storage in complex group of hashes and series of&lt;br /&gt;
conditional statements. We would like to mention that previously, the method had 10&lt;br /&gt;
database calls within loop and 1 outside loop. After refactoring, the new method has just 1&lt;br /&gt;
database call within loop and 3 outside loops. Also, the overall code complexity is reduced&lt;br /&gt;
from 142 to 64 *.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Changes In Helper (leaderboard_helper.rb) =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| userIsInstructor &lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| studentInWhichCourses &lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| getTop3Leaderboards&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who&lt;br /&gt;
has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
[[File:Refactored_Leaderboard_file.jpg|frame|left| View of Refactored Leaderboard]]&lt;br /&gt;
[[File:Non_Refactored_Leaderboard_file.jpg|frame|right| View of non Refactored Leaderboard]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Optimization=&lt;br /&gt;
&lt;br /&gt;
=Future Work=&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method getAssignmentMapping, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
= References=&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90591</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90591"/>
		<updated>2014-10-29T17:42:36Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Existing Functionality */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit#heading=h.p92p30rar40t Writeup Page]&lt;br /&gt;
=Expertiza - Refactoring LeaderBoard model=&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the &amp;quot;Leaderboard&amp;quot; functionality of the web application Expertiza&amp;lt;ref name=&amp;quot;expertiza&amp;gt;''Expertiza'' http://wikis.lib.ncsu.edu/index.php/Expertiza&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The classes involved gets all the assignments in the course and all the participants in a course or in an assignment. The responsibility of the leaderboard module is to generate the top 3 individuals which is to be displayed as the leaderboard for the class and a personal leaderboard view to see a personal aggregated score.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Project Description==&lt;br /&gt;
Classes involved: leaderboard.rb and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (Method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex (Complexity=142).&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
==Existing Functionality==&lt;br /&gt;
Leaderboard class gets all the assignments within all the courses taken by currently logged in user. It&lt;br /&gt;
also fetches any independent assignments (not associated with any course), that the user has taken.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList(assignmentList) &amp;lt;/code&amp;gt;&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; extractPersonalAchievements(csHash, courseIdList, userId) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| &amp;lt;code&amp;gt; addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid) &amp;lt;/code&amp;gt;&lt;br /&gt;
| This method is called internally from &amp;lt;code&amp;gt; Leaderboard.getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt;. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
&amp;lt;code&amp;gt; Leaderboard.rb &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; Leaderboard_helper.rb &amp;lt;/code&amp;gt;. We have also refactored ambiguous variable and method&lt;br /&gt;
names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and&lt;br /&gt;
computation. &lt;br /&gt;
We have refactored many files related to Leaderboard implementation leading to&lt;br /&gt;
enhancement of overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
==Changes In Model (leaderboard.rb) ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| getIndependantAssignments&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| getParticipantEntriesInCourses&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| sortHash&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| extractPersonalAchievements&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call&lt;br /&gt;
unlike several within the loop in its prior implementation. We have also removed redundantcode computation and made the logic easier to understand. The overall complexity of this&lt;br /&gt;
method is reduced from 72 to 35 *.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| addEntryToCSHash&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| The new method name is addScoreToResultantHash. As mentioned earlier, this is called internally&lt;br /&gt;
by getParticipantEntriesInAssignmentList. The complexity of this method is reduced from&lt;br /&gt;
67 to 39 *.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| getParticipantEntriesInAssignmentList&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is getParticipantsScore. The method was&lt;br /&gt;
refactored on various aspects like reducing database calls drastically, removing redundant&lt;br /&gt;
code computation, redundant data storage in complex group of hashes and series of&lt;br /&gt;
conditional statements. We would like to mention that previously, the method had 10&lt;br /&gt;
database calls within loop and 1 outside loop. After refactoring, the new method has just 1&lt;br /&gt;
database call within loop and 3 outside loops. Also, the overall code complexity is reduced&lt;br /&gt;
from 142 to 64 *.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Changes In Helper (leaderboard_helper.rb) ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| userIsInstructor &lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| studentInWhichCourses &lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| getTop3Leaderboards&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who&lt;br /&gt;
has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
[[File:Refactored_Leaderboard_file.jpg|frame|left| View of Refactored Leaderboard]]&lt;br /&gt;
[[File:Non_Refactored_Leaderboard_file.jpg|frame|right| View of non Refactored Leaderboard]]&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;br /&gt;
&lt;br /&gt;
==Future Work==&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method getAssignmentMapping, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
== References==&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90589</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90589"/>
		<updated>2014-10-29T17:40:40Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Project Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit#heading=h.p92p30rar40t Writeup Page]&lt;br /&gt;
=Expertiza - Refactoring LeaderBoard model=&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the &amp;quot;Leaderboard&amp;quot; functionality of the web application Expertiza&amp;lt;ref name=&amp;quot;expertiza&amp;gt;''Expertiza'' http://wikis.lib.ncsu.edu/index.php/Expertiza&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The classes involved gets all the assignments in the course and all the participants in a course or in an assignment. The responsibility of the leaderboard module is to generate the top 3 individuals which is to be displayed as the leaderboard for the class and a personal leaderboard view to see a personal aggregated score.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Project Description==&lt;br /&gt;
Classes involved: leaderboard.rb and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (Method: &amp;lt;code&amp;gt; extractPersonalAchievements &amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor &amp;lt;code&amp;gt; getParticipantEntriesInAssignmentList &amp;lt;/code&amp;gt; method. Its very complex (Complexity=142).&lt;br /&gt;
&lt;br /&gt;
6. Refactor &amp;lt;code&amp;gt; addEntryToCSHash &amp;lt;/code&amp;gt; according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
==Existing Functionality==&lt;br /&gt;
Leaderboard class gets all the assignments within all the courses taken by currently logged in user. It&lt;br /&gt;
also fetches any independent assignments (not associated with any course), that the user has taken.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| ''getParticipantEntriesInAssignmentList(assignmentList)''&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| ''extractPersonalAchievements(csHash, courseIdList, userId)''&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| ''addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid)''&lt;br /&gt;
| This method is called internally from ''Leaderboard.getParticipantEntriesInAssignmentList''. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
Leaderboard.rb, Leaderboard_helper.rb. We have also refactored ambiguous variable and method&lt;br /&gt;
names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and&lt;br /&gt;
computation. &lt;br /&gt;
We have refactored many files related to Leaderboard implementation leading to&lt;br /&gt;
enhancement of overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
==Changes In Model (leaderboard.rb) ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| getIndependantAssignments&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| getParticipantEntriesInCourses&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| sortHash&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| extractPersonalAchievements&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call&lt;br /&gt;
unlike several within the loop in its prior implementation. We have also removed redundantcode computation and made the logic easier to understand. The overall complexity of this&lt;br /&gt;
method is reduced from 72 to 35 *.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| addEntryToCSHash&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| The new method name is addScoreToResultantHash. As mentioned earlier, this is called internally&lt;br /&gt;
by getParticipantEntriesInAssignmentList. The complexity of this method is reduced from&lt;br /&gt;
67 to 39 *.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| getParticipantEntriesInAssignmentList&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is getParticipantsScore. The method was&lt;br /&gt;
refactored on various aspects like reducing database calls drastically, removing redundant&lt;br /&gt;
code computation, redundant data storage in complex group of hashes and series of&lt;br /&gt;
conditional statements. We would like to mention that previously, the method had 10&lt;br /&gt;
database calls within loop and 1 outside loop. After refactoring, the new method has just 1&lt;br /&gt;
database call within loop and 3 outside loops. Also, the overall code complexity is reduced&lt;br /&gt;
from 142 to 64 *.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Changes In Helper (leaderboard_helper.rb) ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| userIsInstructor &lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| studentInWhichCourses &lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| getTop3Leaderboards&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who&lt;br /&gt;
has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
[[File:Refactored_Leaderboard_file.jpg|frame| View of Refactored Leaderboard]]&lt;br /&gt;
[[File:Non_Refactored_Leaderboard_file.jpg|frame| View of non Refactored Leaderboard]]&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;br /&gt;
&lt;br /&gt;
==Future Work==&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method getAssignmentMapping, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
== References==&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90581</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90581"/>
		<updated>2014-10-29T17:34:13Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Project Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit#heading=h.p92p30rar40t Writeup Page]&lt;br /&gt;
=Expertiza - Refactoring LeaderBoard model=&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the &amp;quot;Leaderboard&amp;quot; functionality of the web application Expertiza&amp;lt;ref name=&amp;quot;expertiza&amp;gt;''Expertiza'' http://wikis.lib.ncsu.edu/index.php/Expertiza&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The classes involved gets all the assignments in the course and all the participants in a course or in an assignment. The responsibility of the leaderboard module is to generate the top 3 individuals which is to be displayed as the leaderboard for the class and a personal leaderboard view to see a personal aggregated score.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Project Description==&lt;br /&gt;
Classes involved: leaderboard.rb and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (Method: &amp;lt;code&amp;gt;extractPersonalAchievements&amp;lt;/code&amp;gt;). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor ''addEntryToCSHash'' according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor ''getParticipantEntriesInAssignmentList'' method. Its very complex (Complexity=142).&lt;br /&gt;
&lt;br /&gt;
6. Refactor ''addEntryToCSHash'' according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
==Existing Functionality==&lt;br /&gt;
Leaderboard class gets all the assignments within all the courses taken by currently logged in user. It&lt;br /&gt;
also fetches any independent assignments (not associated with any course), that the user has taken.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| ''getParticipantEntriesInAssignmentList(assignmentList)''&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| ''extractPersonalAchievements(csHash, courseIdList, userId)''&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| ''addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid)''&lt;br /&gt;
| This method is called internally from ''Leaderboard.getParticipantEntriesInAssignmentList''. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
Leaderboard.rb, Leaderboard_helper.rb. We have also refactored ambiguous variable and method&lt;br /&gt;
names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and&lt;br /&gt;
computation. &lt;br /&gt;
We have refactored many files related to Leaderboard implementation leading to&lt;br /&gt;
enhancement of overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
==Changes In Model (leaderboard.rb) ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| getIndependantAssignments&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| getParticipantEntriesInCourses&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| sortHash&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| extractPersonalAchievements&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call&lt;br /&gt;
unlike several within the loop in its prior implementation. We have also removed redundantcode computation and made the logic easier to understand. The overall complexity of this&lt;br /&gt;
method is reduced from 72 to 35 *.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| addEntryToCSHash&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| The new method name is addScoreToResultantHash. As mentioned earlier, this is called internally&lt;br /&gt;
by getParticipantEntriesInAssignmentList. The complexity of this method is reduced from&lt;br /&gt;
67 to 39 *.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| getParticipantEntriesInAssignmentList&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is getParticipantsScore. The method was&lt;br /&gt;
refactored on various aspects like reducing database calls drastically, removing redundant&lt;br /&gt;
code computation, redundant data storage in complex group of hashes and series of&lt;br /&gt;
conditional statements. We would like to mention that previously, the method had 10&lt;br /&gt;
database calls within loop and 1 outside loop. After refactoring, the new method has just 1&lt;br /&gt;
database call within loop and 3 outside loops. Also, the overall code complexity is reduced&lt;br /&gt;
from 142 to 64 *.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Changes In Helper (leaderboard_helper.rb) ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| userIsInstructor &lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| studentInWhichCourses &lt;br /&gt;
| Rewrote to reduce the number of database calls. &lt;br /&gt;
| This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| getTop3Leaderboards&lt;br /&gt;
| Dead code&lt;br /&gt;
| Removed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who&lt;br /&gt;
has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
[[File:Refactored_Personal_Achievement_file.jpg|left|frame| View of Personal Achievement]]&lt;br /&gt;
[[File:Refactored_Leaderboard_file.jpg|right|frame| View of Refactored Leaderboard]]&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;br /&gt;
&lt;br /&gt;
==Future Work==&lt;br /&gt;
There was a requirement in the project, that we should come up with an efficient way to search for participants based on assignment ids. However, upon investigation, we found that scores stored in table ScoreCache, gives us revieweeId which is either participantId or teamId. Therefore, we have a method getAssignmentMapping, which creates a mapping of participant and team with corresponding assignment. This is very useful while computing leaderboard.&lt;br /&gt;
&lt;br /&gt;
== References==&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90556</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90556"/>
		<updated>2014-10-29T17:21:28Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Existing Functionality */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit#heading=h.p92p30rar40t Writeup Page]&lt;br /&gt;
=Expertiza - Refactoring LeaderBoard model=&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the &amp;quot;Leaderboard&amp;quot; functionality of the web application Expertiza&amp;lt;ref name=&amp;quot;expertiza&amp;gt;''Expertiza'' http://wikis.lib.ncsu.edu/index.php/Expertiza&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The classes involved gets all the assignments in the course and all the participants in a course or in an assignment. The responsibility of the leaderboard module is to generate the top 3 individuals which is to be displayed as the leaderboard for the class and a personal leaderboard view to see a personal aggregated score.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Project Description==&lt;br /&gt;
Classes involved: leaderboard.rb and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (Method: ''extractPersonalAchievements''). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor ''addEntryToCSHash'' according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor ''getParticipantEntriesInAssignmentList'' method. Its very complex (Complexity=142).&lt;br /&gt;
&lt;br /&gt;
6. Refactor ''addEntryToCSHash'' according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
==Existing Functionality==&lt;br /&gt;
Leaderboard class gets all the assignments within all the courses taken by currently logged in user. It&lt;br /&gt;
also fetches any independent assignments (not associated with any course), that the user has taken.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| ''getParticipantEntriesInAssignmentList(assignmentList)''&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| ''extractPersonalAchievements(csHash, courseIdList, userId)''&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| ''addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid)''&lt;br /&gt;
| This method is called internally from ''Leaderboard.getParticipantEntriesInAssignmentList''. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
Leaderboard.rb, Leaderboard_helper.rb. We have also refactored ambiguous variable and method&lt;br /&gt;
names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and&lt;br /&gt;
computation. &lt;br /&gt;
We have refactored many files related to Leaderboard implementation leading to&lt;br /&gt;
enhancement of overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
==Changes In Model (leaderboard.rb) ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| getIndependantAssignments&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| getParticipantEntriesInCourses&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| sortHash&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| extractPersonalAchievements&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call&lt;br /&gt;
unlike several within the loop in its prior implementation. We have also removed redundantcode computation and made the logic easier to understand. The overall complexity of this&lt;br /&gt;
method is reduced from 72 to 35 *.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| addEntryToCSHash&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| The new method name is addScoreToResultantHash. As mentioned earlier, this is called internally&lt;br /&gt;
by getParticipantEntriesInAssignmentList. The complexity of this method is reduced from&lt;br /&gt;
67 to 39 *.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| getParticipantEntriesInAssignmentList&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is getParticipantsScore. The method was&lt;br /&gt;
refactored on various aspects like reducing database calls drastically, removing redundant&lt;br /&gt;
code computation, redundant data storage in complex group of hashes and series of&lt;br /&gt;
conditional statements. We would like to mention that previously, the method had 10&lt;br /&gt;
database calls within loop and 1 outside loop. After refactoring, the new method has just 1&lt;br /&gt;
database call within loop and 3 outside loops. Also, the overall code complexity is reduced&lt;br /&gt;
from 142 to 64 *.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
○ There was a requirement in the project, that we should come up with an efficient way to&lt;br /&gt;
search for participants based on assignment ids. However, upon investigation, we found&lt;br /&gt;
that scores stored in table ScoreCache, gives us revieweeId which is either participantId or&lt;br /&gt;
teamId. Therefore, we have a method getAssignmentMapping, which creates a mapping of&lt;br /&gt;
participant and team with corresponding assignment. This is very useful while computing&lt;br /&gt;
leaderboard.&lt;br /&gt;
&lt;br /&gt;
2. Leaderboard_helper.rb&lt;br /&gt;
○ userIsInstructor : This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
○ studentInWhichCourses : This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
○ getTop3Leaderboards : This method is a dead code, not called from anywhere, therefore,&lt;br /&gt;
we have commented this for the moment.&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who&lt;br /&gt;
has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
[[File:Refactored_Leaderboard_file.jpg||frame|Build Status Page in CruiseControl &amp;lt;ref name=&amp;quot;cc&amp;quot;&amp;gt;&amp;lt;/ref&amp;gt;. View of Refactored Leaderboard]]&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90555</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90555"/>
		<updated>2014-10-29T17:20:31Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Project Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit#heading=h.p92p30rar40t Writeup Page]&lt;br /&gt;
=Expertiza - Refactoring LeaderBoard model=&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the &amp;quot;Leaderboard&amp;quot; functionality of the web application Expertiza&amp;lt;ref name=&amp;quot;expertiza&amp;gt;''Expertiza'' http://wikis.lib.ncsu.edu/index.php/Expertiza&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The classes involved gets all the assignments in the course and all the participants in a course or in an assignment. The responsibility of the leaderboard module is to generate the top 3 individuals which is to be displayed as the leaderboard for the class and a personal leaderboard view to see a personal aggregated score.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Project Description==&lt;br /&gt;
Classes involved: leaderboard.rb and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (Method: ''extractPersonalAchievements''). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor ''addEntryToCSHash'' according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor ''getParticipantEntriesInAssignmentList'' method. Its very complex (Complexity=142).&lt;br /&gt;
&lt;br /&gt;
6. Refactor ''addEntryToCSHash'' according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
==Existing Functionality==&lt;br /&gt;
Leaderboard class gets all the assignments within all the courses taken by currently logged in user. It&lt;br /&gt;
also fetches any independent assignments (not associated with any course), that the user has taken.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| getParticipantEntriesInAssignmentList(assignmentList)&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| extractPersonalAchievements(csHash, courseIdList, userId)&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid)&lt;br /&gt;
| This method is called internally from Leaderboard.getParticipantEntriesInAssignmentList. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
Leaderboard.rb, Leaderboard_helper.rb. We have also refactored ambiguous variable and method&lt;br /&gt;
names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and&lt;br /&gt;
computation. &lt;br /&gt;
We have refactored many files related to Leaderboard implementation leading to&lt;br /&gt;
enhancement of overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
==Changes In Model (leaderboard.rb) ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| getIndependantAssignments&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| getParticipantEntriesInCourses&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| sortHash&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| extractPersonalAchievements&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call&lt;br /&gt;
unlike several within the loop in its prior implementation. We have also removed redundantcode computation and made the logic easier to understand. The overall complexity of this&lt;br /&gt;
method is reduced from 72 to 35 *.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| addEntryToCSHash&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| The new method name is addScoreToResultantHash. As mentioned earlier, this is called internally&lt;br /&gt;
by getParticipantEntriesInAssignmentList. The complexity of this method is reduced from&lt;br /&gt;
67 to 39 *.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| getParticipantEntriesInAssignmentList&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is getParticipantsScore. The method was&lt;br /&gt;
refactored on various aspects like reducing database calls drastically, removing redundant&lt;br /&gt;
code computation, redundant data storage in complex group of hashes and series of&lt;br /&gt;
conditional statements. We would like to mention that previously, the method had 10&lt;br /&gt;
database calls within loop and 1 outside loop. After refactoring, the new method has just 1&lt;br /&gt;
database call within loop and 3 outside loops. Also, the overall code complexity is reduced&lt;br /&gt;
from 142 to 64 *.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
○ There was a requirement in the project, that we should come up with an efficient way to&lt;br /&gt;
search for participants based on assignment ids. However, upon investigation, we found&lt;br /&gt;
that scores stored in table ScoreCache, gives us revieweeId which is either participantId or&lt;br /&gt;
teamId. Therefore, we have a method getAssignmentMapping, which creates a mapping of&lt;br /&gt;
participant and team with corresponding assignment. This is very useful while computing&lt;br /&gt;
leaderboard.&lt;br /&gt;
&lt;br /&gt;
2. Leaderboard_helper.rb&lt;br /&gt;
○ userIsInstructor : This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
○ studentInWhichCourses : This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
○ getTop3Leaderboards : This method is a dead code, not called from anywhere, therefore,&lt;br /&gt;
we have commented this for the moment.&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who&lt;br /&gt;
has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
[[File:Refactored_Leaderboard_file.jpg||frame|Build Status Page in CruiseControl &amp;lt;ref name=&amp;quot;cc&amp;quot;&amp;gt;&amp;lt;/ref&amp;gt;. View of Refactored Leaderboard]]&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90551</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90551"/>
		<updated>2014-10-29T17:18:20Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* Existing Functionality */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit#heading=h.p92p30rar40t Writeup Page]&lt;br /&gt;
=Expertiza - Refactoring LeaderBoard model=&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the &amp;quot;Leaderboard&amp;quot; functionality of the web application Expertiza&amp;lt;ref name=&amp;quot;expertiza&amp;gt;''Expertiza'' http://wikis.lib.ncsu.edu/index.php/Expertiza&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The classes involved gets all the assignments in the course and all the participants in a course or in an assignment. The responsibility of the leaderboard module is to generate the top 3 individuals which is to be displayed as the leaderboard for the class and a personal leaderboard view to see a personal aggregated score.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Project Description==&lt;br /&gt;
Classes involved: leaderboard.rb and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (Method: extractPersonalAchievements). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor addEntryToCSHash according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor getParticipantEntriesInAssignmentList method. Its very complex (Complexity=142).&lt;br /&gt;
&lt;br /&gt;
6. Refactor addEntryToCSHash according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
==Existing Functionality==&lt;br /&gt;
Leaderboard class gets all the assignments within all the courses taken by currently logged in user. It&lt;br /&gt;
also fetches any independent assignments (not associated with any course), that the user has taken.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:3%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| getParticipantEntriesInAssignmentList(assignmentList)&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| extractPersonalAchievements(csHash, courseIdList, userId)&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the ranking of currently logged in user against total users associated with the same set of courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid)&lt;br /&gt;
| This method is called internally from Leaderboard.getParticipantEntriesInAssignmentList. This method aggregates score of a user grouped by course id, further grouped by questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
Leaderboard.rb, Leaderboard_helper.rb. We have also refactored ambiguous variable and method&lt;br /&gt;
names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and&lt;br /&gt;
computation. &lt;br /&gt;
We have refactored many files related to Leaderboard implementation leading to&lt;br /&gt;
enhancement of overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
==Changes==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| getIndependantAssignments&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| getParticipantEntriesInCourses&lt;br /&gt;
| Reduced the number of database calls within loop.&lt;br /&gt;
| Less complexity and runs faster.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| sortHash&lt;br /&gt;
| in place changes.&lt;br /&gt;
| Returns a new deep copy of the updated hash.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 4 '''''&lt;br /&gt;
| extractPersonalAchievements&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| This method is refactored to use only 1 database call&lt;br /&gt;
unlike several within the loop in its prior implementation. We have also removed redundantcode computation and made the logic easier to understand. The overall complexity of this&lt;br /&gt;
method is reduced from 72 to 35 *.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 5 '''''&lt;br /&gt;
| addEntryToCSHash&lt;br /&gt;
| Confusing code with extra data base calls.&lt;br /&gt;
| The new method name is addScoreToResultantHash. As mentioned earlier, this is called internally&lt;br /&gt;
by getParticipantEntriesInAssignmentList. The complexity of this method is reduced from&lt;br /&gt;
67 to 39 *.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 6 '''''&lt;br /&gt;
| getParticipantEntriesInAssignmentList&lt;br /&gt;
| This method was the most complex method in the class. &lt;br /&gt;
| The new refactored method name is getParticipantsScore. The method was&lt;br /&gt;
refactored on various aspects like reducing database calls drastically, removing redundant&lt;br /&gt;
code computation, redundant data storage in complex group of hashes and series of&lt;br /&gt;
conditional statements. We would like to mention that previously, the method had 10&lt;br /&gt;
database calls within loop and 1 outside loop. After refactoring, the new method has just 1&lt;br /&gt;
database call within loop and 3 outside loops. Also, the overall code complexity is reduced&lt;br /&gt;
from 142 to 64 *.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
○ There was a requirement in the project, that we should come up with an efficient way to&lt;br /&gt;
search for participants based on assignment ids. However, upon investigation, we found&lt;br /&gt;
that scores stored in table ScoreCache, gives us revieweeId which is either participantId or&lt;br /&gt;
teamId. Therefore, we have a method getAssignmentMapping, which creates a mapping of&lt;br /&gt;
participant and team with corresponding assignment. This is very useful while computing&lt;br /&gt;
leaderboard.&lt;br /&gt;
&lt;br /&gt;
2. Leaderboard_helper.rb&lt;br /&gt;
○ userIsInstructor : This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
○ studentInWhichCourses : This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
○ getTop3Leaderboards : This method is a dead code, not called from anywhere, therefore,&lt;br /&gt;
we have commented this for the moment.&lt;br /&gt;
&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who&lt;br /&gt;
has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
[[File:Refactored_Leaderboard_file.jpg||frame|Build Status Page in CruiseControl &amp;lt;ref name=&amp;quot;cc&amp;quot;&amp;gt;&amp;lt;/ref&amp;gt;. View of Refactored Leaderboard]]&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90540</id>
		<title>CSC/ECE 517 Fall 2014/OSS E1467 rsv</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/OSS_E1467_rsv&amp;diff=90540"/>
		<updated>2014-10-29T17:11:04Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/document/d/1FZCL9KWSdVNsX9BowuZ3gxbCOJoiWX-GVLctSZei3No/edit#heading=h.p92p30rar40t Writeup Page]&lt;br /&gt;
=Expertiza - Refactoring LeaderBoard model=&lt;br /&gt;
&lt;br /&gt;
Our project is to refactor the code in the &amp;quot;Leaderboard&amp;quot; functionality of the web application Expertiza&amp;lt;ref name=&amp;quot;expertiza&amp;gt;''Expertiza'' http://wikis.lib.ncsu.edu/index.php/Expertiza&amp;lt;/ref&amp;gt;. The Expertiza project is a system to create reusable learning objects through peer review. The classes involved gets all the assignments in the course and all the participants in a course or in an assignment. The responsibility of the leaderboard module is to generate the top 3 individuals which is to be displayed as the leaderboard for the class and a personal leaderboard view to see a personal aggregated score.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Project Description==&lt;br /&gt;
Classes involved: leaderboard.rb and associated other model and controllers classes. &lt;br /&gt;
&lt;br /&gt;
1. Come up with an efficient way to search for participants based on assignment ids.&lt;br /&gt;
&lt;br /&gt;
2. Refactor score hash for personal achievements. (Method: extractPersonalAchievements). Seperate out method which will rank individual personal achievements.&lt;br /&gt;
&lt;br /&gt;
3. Refactor addEntryToCSHash according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
4. Seperate out computation of CS entries(metric) and refactor it to be more modular and elegant. &lt;br /&gt;
&lt;br /&gt;
5. Refactor getParticipantEntriesInAssignmentList method. Its very complex (Complexity=142).&lt;br /&gt;
&lt;br /&gt;
6. Refactor addEntryToCSHash according to your new metric method.&lt;br /&gt;
&lt;br /&gt;
==Existing Functionality==&lt;br /&gt;
Leaderboard class gets all the assignments within all the courses taken by currently logged in user. It&lt;br /&gt;
also fetches any independent assignments (not associated with any course), that the user has taken.&lt;br /&gt;
&lt;br /&gt;
Leaderboard model has following 3 important methods:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:5%;&amp;quot;|Sr. No.&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Comment&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|''''' 1 '''''&lt;br /&gt;
| getParticipantEntriesInAssignmentList(assignmentList)&lt;br /&gt;
|This method is responsible for calculating the leaderboard of all the participants associated&lt;br /&gt;
with assignments in given assignment list.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 2 '''''&lt;br /&gt;
| extractPersonalAchievements(csHash, courseIdList, userId)&lt;br /&gt;
| This method is responsible for calculating personal aggregated score. It also calculates the&lt;br /&gt;
ranking of currently logged in user against total users associated with the same set of&lt;br /&gt;
courses as that of current user.&lt;br /&gt;
|-&lt;br /&gt;
|''''' 3 '''''&lt;br /&gt;
| addEntryToCSHash(qtypeHash, qtype, userid, csEntry, courseid)&lt;br /&gt;
| This method is called internally from Leaderboard.getParticipantEntriesInAssignmentList. This method aggregates score of a user grouped by course id, further grouped by&lt;br /&gt;
questionnaire type.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In the OSS project, we have refactored these methods along with other smaller methods in&lt;br /&gt;
Leaderboard.rb, Leaderboard_helper.rb. We have also refactored ambiguous variable and method&lt;br /&gt;
names.&lt;br /&gt;
&lt;br /&gt;
We have keenly focussed in reducing the database calls, loops and redundant storage and&lt;br /&gt;
computation. &lt;br /&gt;
We have refactored many files related to Leaderboard implementation leading to&lt;br /&gt;
enhancement of overall complexity of the feature.&lt;br /&gt;
&lt;br /&gt;
==Changes==&lt;br /&gt;
1. Leaderboard.rb&lt;br /&gt;
○ Methods like getIndependantAssignments and getParticipantEntriesInCourses are&lt;br /&gt;
refactored to reduce the database calls within loop. Database calls have huge impact on&lt;br /&gt;
overall complexity of the code and performance of the software.&lt;br /&gt;
○ sortHash : This method modified the input hash. We refactored it to not alter the input&lt;br /&gt;
hash object, but rather return a new deep copy of the updated hash object.&lt;br /&gt;
○ extractPersonalAchievements : This method is refactored to use only 1 database call&lt;br /&gt;
unlike several within the loop in its prior implementation. We have also removed redundantcode computation and made the logic easier to understand. The overall complexity of this&lt;br /&gt;
method is reduced from 72 to 35 *.&lt;br /&gt;
○ addEntryToCSHash : This method is refactored to reduce the redundant code. The new&lt;br /&gt;
method name is addScoreToResultantHash. As mentioned earlier, this is called internally&lt;br /&gt;
by getParticipantEntriesInAssignmentList. The complexity of this method is reduced from&lt;br /&gt;
67 to 39 *.&lt;br /&gt;
&lt;br /&gt;
○ getParticipantEntriesInAssignmentList : This method was the most complex method in&lt;br /&gt;
the class. The new refactored method name is getParticipantsScore. The method was&lt;br /&gt;
refactored on various aspects like reducing database calls drastically, removing redundant&lt;br /&gt;
code computation, redundant data storage in complex group of hashes and series of&lt;br /&gt;
conditional statements. We would like to mention that previously, the method had 10&lt;br /&gt;
database calls within loop and 1 outside loop. After refactoring, the new method has just 1&lt;br /&gt;
database call within loop and 3 outside loops. Also, the overall code complexity is reduced&lt;br /&gt;
from 142 to 64 *.&lt;br /&gt;
○ There was a requirement in the project, that we should come up with an efficient way to&lt;br /&gt;
search for participants based on assignment ids. However, upon investigation, we found&lt;br /&gt;
that scores stored in table ScoreCache, gives us revieweeId which is either participantId or&lt;br /&gt;
teamId. Therefore, we have a method getAssignmentMapping, which creates a mapping of&lt;br /&gt;
participant and team with corresponding assignment. This is very useful while computing&lt;br /&gt;
leaderboard.&lt;br /&gt;
2. Leaderboard_helper.rb&lt;br /&gt;
○ userIsInstructor : This method was refactored to reduce multiple database calls. 4&lt;br /&gt;
database calls was replaced by single call.&lt;br /&gt;
○ studentInWhichCourses : This method was refactored to reduce multiple database calls&lt;br /&gt;
and remove unnecessary loops. 1 database call outside and 1 within a loop was replaced&lt;br /&gt;
by a single call.&lt;br /&gt;
○ getTop3Leaderboards : This method is a dead code, not called from anywhere, therefore,&lt;br /&gt;
we have commented this for the moment.&lt;br /&gt;
There are several other changes in the views and controller which deal with renaming of the methods&lt;br /&gt;
and variables, adding proper comments etc and minor code refactoring. Please refer to our forked&lt;br /&gt;
github repository to view those changes.&lt;br /&gt;
Lastly, we would like to recommend the readers to test the leaderboard functionality by any user who&lt;br /&gt;
has participated in several assignments, some of them which is associated with any course and there&lt;br /&gt;
are other existing users who have participated in the same assignment. e.g. user480/password&lt;br /&gt;
* Code complexity measurement is according to Code Climate&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
==Optimization==&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/ch1a_1_rm&amp;diff=88421</id>
		<title>CSC/ECE 517 Fall 2014/ch1a 1 rm</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/ch1a_1_rm&amp;diff=88421"/>
		<updated>2014-09-25T21:05:58Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* History */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/document/d/1eq3XHiUUBIrEBx-R2Mgolaw7HttSgzPniwDLEF5oVk0/edit?pli=1 Writeup Page]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Play Framework'''&lt;br /&gt;
&lt;br /&gt;
Play is modern web framework that provides support for writing scalable applications in either Java or Scala. It is an open source web framework and follows model–view–controller [http://en.wikipedia.org/wiki/Model-view-controller MVC] architectural pattern. It mainly focuses on being stateless and non-blocking I/O which is one of the main drawbacks among its competitors like Tomcat, [http://en.wikipedia.org/wiki/Spring_Framework Spring MVC] etc. Unlike these, Play’s approach is not threaded, it is a framework that is based on event model. This support for a full HTTP asynchronous programming model, makes Play an ideal framework for writing highly-distributed systems while maintaining performance, reliability and developer productivity.&lt;br /&gt;
&lt;br /&gt;
Play is built on [http://en.wikipedia.org/wiki/Akka_(toolkit) Akka](Actor based model), providing predictable and minimal resource consumption for highly scalable applications. It used for handling highly concurrent systems and allows to develop applications in both Java and Scala.&amp;lt;ref&amp;gt; http://www.playframework.com &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Normal.png‎|right|]] &lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==History==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Play Framework development started back in 2007 at Zenexity but it’s first release as a open source framework was available not available until 2009.&lt;br /&gt;
In May 2008 the first published code for 1.0 appeared on Launchpad. This was followed by a full 1.0 release in October 2009.&lt;br /&gt;
&lt;br /&gt;
Play 1.1 &amp;lt;ref name=&amp;quot;history&amp;quot;&amp;gt;http://en.wikipedia.org/wiki/Play_framework#History&amp;lt;/ref&amp;gt; was released in November 2010 after a move from Launchpad to GitHub. It included a migration from Apache MINA to JBoss Netty, Scala support, native GlassFishcontainer, an asynchronous web services library, OAuth support, HTTPS support and other features.&lt;br /&gt;
&lt;br /&gt;
Play 1.2 &amp;lt;ref name=&amp;quot;history&amp;quot;/&amp;gt; was released in April 2011. It included dependency management with Apache Ivy, support for WebSocket, integrated database migration (reversion is not implemented yet), a switch to the H2 database and other features.&lt;br /&gt;
&lt;br /&gt;
Play 2.0 was released on March 13, 2012 in conjunction with Typesafe Stack 2.0.&lt;br /&gt;
&lt;br /&gt;
Play 2.1 &amp;lt;ref name=&amp;quot;history&amp;quot;/&amp;gt; was released on February 6, 2013, upgraded to Scala 2.10 and introduced, among other new features, modularisation, a new JSON API, filters and RequireJS support.&lt;br /&gt;
&lt;br /&gt;
Play 2.2 &amp;lt;ref name=&amp;quot;history&amp;quot;/&amp;gt; was released on September 20, 2013. Upgraded support for SBT to 0.13, better support for buffering, built in support for gzip and new stage and dist tasks with support for native packaging on several platforms such as OS X (DMG), Linux (RPM, DEB), and Windows (MSI) as well as zip files.&lt;br /&gt;
&lt;br /&gt;
Play 2.3&amp;lt;ref&amp;gt;https://www.playframework.com/documentation/2.3.x/Highlights23&amp;lt;/ref&amp;gt; has updated to include Activator, improved build environment(sbt), compatibilty with Java 8. This version of Play has been built on multiple version of Scala both 2.10 and 2.11. The WS client library has been refactored into its own library so that Play can have multiple WSClient objects, rather than only using the WS singleton. A method to use actors for handling websocket interactions has been incorporated for both Java and Scala. Anorm ( a simple data access layer that uses plain SQL to interact with the database and provides an API to parse and transform the resulting datasets) has been updated to include type safety, option parsing, error handling.&lt;br /&gt;
&lt;br /&gt;
==Development with Play== &lt;br /&gt;
&lt;br /&gt;
Let us see the features offered by Play from a developers perspective, who wants to develop a web application in Play framework.&lt;br /&gt;
===Installing Play===&lt;br /&gt;
To install Play framework, download the binaries from [https://www.playframework.com/download download page] and extract the contents to any folder. Add the extracted folder to path variable&amp;lt;ref&amp;gt;https://www.playframework.com/documentation/2.3.x/Installing &amp;lt;/ref&amp;gt; and verify whether you were able to execute the below command :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 activator ui&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This starts the play server and if everything goes well, you should see a default play application running at http: //127.0.0.1:8888/home .&lt;br /&gt;
&lt;br /&gt;
===Creating a new project===&lt;br /&gt;
&lt;br /&gt;
To create a new project just type the below command and Play will take care of creating directory structure for your app with a standard layout. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 activator new &amp;lt;app name&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you are wondering what folders were created and what they imply, here is a brief explanation to get you started :&lt;br /&gt;
&lt;br /&gt;
*app folder: It contains the main part of the application,i.e.,models, views, controllers. All the source code is present here.&lt;br /&gt;
&lt;br /&gt;
*conf folder: It will contain all the configuration files especially the application.conf, the routes file and the messages file used for [https://www.playframework.com/documentation/1.2/i18n Internationalization](a way of adopting your application to different languages for different regions). The main entry point of the application is conf/routes file, it will contain the list of URL’s that are accessible in a  application.&lt;br /&gt;
&lt;br /&gt;
*lib folder: It is used for extending libraries.&lt;br /&gt;
 &lt;br /&gt;
*public: It used for all static files like JavaScript files, style sheets and images directories, resources which are available publicly.&lt;br /&gt;
&lt;br /&gt;
*test folder: All the application tests are written in this folder, JUnit for functional testing and Selenium tests for Web application testing.&lt;br /&gt;
&lt;br /&gt;
There won’t be any predefined folder to store Java .class files, as Play doesn’t need one. It internally uses eclipse compiler and compiles Java classes on the fly. This gives the ability to reflect the changes made in Java files, without having to compile them again. Another advantage of having an inbuilt compiler is that Play will create a better error report by showing the point of failure &amp;lt;ref&amp;gt;http://stackoverflow.com/questions/11704951/play-framework-no-need-to-compile&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===How to run an application?===&lt;br /&gt;
&lt;br /&gt;
Navigate to the app directory and execute below command :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
activator run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Your application will be loaded and a web server is started at 9000 port. Application can be accessed at http://localhost:9000/ &lt;br /&gt;
&lt;br /&gt;
Similar to [http://rubyonrails.org/ Rails], Play also uses config/routes file to map the request URL to the respective controller method. A sample entry looks like this :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Get                      /                                     Users.index&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above line invokes index() method in Users controller when you access the application home page.&lt;br /&gt;
&lt;br /&gt;
You can either use a text editor to make code changes or even there is a support for IDEs like [https://netbeans.org/ Netbeans] and [https://www.eclipse.org/ Eclipse] in Play. If you want to set up a Java IDE, please check [https://www.playframework.com/documentation/1.1.1/ide this page]. &lt;br /&gt;
&lt;br /&gt;
===Database support===&lt;br /&gt;
&lt;br /&gt;
Play comes with an inbuilt Database called HSQLDB&amp;lt;ref&amp;gt;http://en.wikipedia.org/wiki/HSQLDB&amp;lt;/ref&amp;gt;, this is an in-memory database and if you want to use any other persisting databases like [http://www.oracle.com/us/products/database/overview/index.html Oracle], [http://www.postgresql.org/ Postgres] etc, you can add those configs in conf/application.conf file. Play will connect to the specified database while application startup.&lt;br /&gt;
 &lt;br /&gt;
Play uses 'Object Relational Mapper'  to persist the model objects to a persistent DB. JPA&amp;lt;ref&amp;gt;http://en.wikipedia.org/wiki/Java_Persistence_API&amp;lt;/ref&amp;gt; is a Java specification that defines a standard API for object relational mapping. As implementation of JPA, play uses the well-known Hibernate framework.&lt;br /&gt;
&lt;br /&gt;
===Testing===&lt;br /&gt;
&lt;br /&gt;
To run a test case, you need to start the application in a special ‘test’ mode. Stop the currently running application, open a command line and type:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 activator test&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The 'play test' command is almost the same than 'play run', except that it loads a test runner module that allows to run test suite directly from a browser. When you run a play application in test mode, play will automatically switch to the test framework id and load the application.conf file accordingly. Check this page for more information. Open a browser to the http://localhost:9000/@tests URL to see the test runner. &lt;br /&gt;
&lt;br /&gt;
Similar to Rails, one can use Fixtures to load the test data in test. These data files reside in appname/test/ folder.&lt;br /&gt;
&lt;br /&gt;
Play gives you a way to test directly the controller part of the application using [http://junit.org/ JUnit]. These are called 'Functional tests'. Basically a functional test calls the play ActionInvoker directly, simulating an HTTP request. So we give an HTTP method, an URI and HTTP parameters. Play then routes the request, invokes the corresponding action and sends you back the filled response. You can then analyze it to check that the response content is like you expected.&lt;br /&gt;
&lt;br /&gt;
Play provides an additional functionality for [http://www.seleniumhq.org/ Selenium] tests, which are specifically written for web based applications. The benefit of using Selenium is that it will test your application in your browser and not a built in simulator.&lt;br /&gt;
&lt;br /&gt;
===Play Templates===&lt;br /&gt;
&lt;br /&gt;
Play has an efficient templating system which allows to dynamically generate HTML, XML, JSON or any text based format document. The template engine uses Groovy as an expression language. A tag system allows you to create reusable functions. Templates are stored in the app/views directory.&lt;br /&gt;
&lt;br /&gt;
This template language is useful in various ways and you can read more about it [https://www.playframework.com/documentation/1.0/templates here]&lt;br /&gt;
&lt;br /&gt;
===Play Modules===&lt;br /&gt;
&lt;br /&gt;
A play application can be assembled from several application modules. This lets you reuse components across several applications or split a large application into several smaller ones. A module is just another play application; however some differences exist in the way resources are loaded for an application module :&lt;br /&gt;
A module does not have a conf/application.conf file.&lt;br /&gt;
A module can have a conf/routes file, but these routes will not be loaded automatically.&lt;br /&gt;
All files are first searched for in the main application path, then in all loaded modules.&lt;br /&gt;
Everything in a module is optional.&lt;br /&gt;
You can create a module with the play new command, just like you do for any other application.&lt;br /&gt;
&lt;br /&gt;
To load an external module&amp;lt;ref&amp;gt;https://www.playframework.com/modules&amp;lt;/ref&amp;gt;, just declare it in the application.conf file of main application. One of such useful modules in CRUD module. Using [http://en.wikipedia.org/wiki/Create,_read,_update_and_delete CRUD] you can easily configure your application to have an administration area where you can add/update/delete any model objects present in your application.&lt;br /&gt;
&lt;br /&gt;
Another such frequently used module is a code coverage module based on the [http://cobertura.github.io/cobertura/ Cobertura] tool.&lt;br /&gt;
&lt;br /&gt;
==Why Play?==&lt;br /&gt;
&lt;br /&gt;
Play is a lightweight framework that offers so many options for [http://en.wikipedia.org/wiki/Java_%28programming_language%29 Java] and [http://en.wikipedia.org/wiki/Scala_%28programming_language%29 Scala] developers, without compromising much on productivity. Here are some of the features describing why one should opt for Play:&lt;br /&gt;
&lt;br /&gt;
===Developer Friendly=== &lt;br /&gt;
*Change the code wherever like Java classes or Templates and just hit refresh to see your changes.&lt;br /&gt;
*Lot of support for testing tools.&lt;br /&gt;
&lt;br /&gt;
===Scalable and Efficient===&lt;br /&gt;
*Play is built on Akka, so it supports non-blocking  I/O&amp;lt;ref&amp;gt;http://www.playframework.com/documentation/2.0.4/ScalaAsync&amp;lt;/ref&amp;gt;. This means it's very easy and inexpensive to make remote calls in parallel, which is important for high performance apps in a service oriented architecture.&lt;br /&gt;
&lt;br /&gt;
===Good Support===&lt;br /&gt;
*Commercial support is provided by [http://zenexity.com/ Zenexity] and [http://typesafe.com/ Typesafe].&lt;br /&gt;
*Easy cloud hosting options like Stax cloud hosting platform and can be deployed virtually anywhere: inside Servlet containers, as standalone servers, in Google Application Engine etc.&lt;br /&gt;
&lt;br /&gt;
===Open source===&lt;br /&gt;
*Play is a open source project and this enables you to see what happens under the hood.&lt;br /&gt;
*Also there is vast support through plugins modules etc which can be reused in building your application.&lt;br /&gt;
&lt;br /&gt;
===Built for latest technologies===&lt;br /&gt;
*Play has extensive NoSql and BigData support.&lt;br /&gt;
*Built-in support for REST, JSON/XML handling, non-blocking I/O, WebSockets &amp;lt;ref&amp;gt;http://www.playframework.com/documentation/2.0.4/ScalaWebSockets&amp;lt;/ref&amp;gt;, asset compilation (CoffeeScript, less), ORM, NoSQL support, and many.&lt;br /&gt;
&lt;br /&gt;
===Notable uses of Play===&lt;br /&gt;
&lt;br /&gt;
LinkedIn is the one of the most popular companies that uses play in its production.&amp;lt;ref&amp;gt; https://engineering.linkedin.com/play/play-framework-linkedin&amp;lt;/ref&amp;gt;&lt;br /&gt;
Some of the other websites that use Play are [https://www.coursera.org/ Coursera], Mashape, [http://typesafe.com/ typesafe], [http://prenser.com/ Prenser], [http://subscribe.peachdish.com/ PeachDish]&amp;lt;ref&amp;gt;http://en.wikipedia.org/wiki/Play_framework#Usage&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Comparison with other frameworks==&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|+ Feature-based Comparison on Web Frameworks &amp;lt;ref&amp;gt;http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2014/ch1a_1c_yj#Feature-based_Comparison_on_Web_Frameworks&amp;lt;/ref&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Project'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Language'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Ajax'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''MVC framework'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''MVC push-pull'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Testing framework(s)'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''DB migration framework(s)'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Security framework(s)'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Template framework(s)'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Caching framework(s)'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Form validation framework(s)'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Scaffolding'''&lt;br /&gt;
|-&lt;br /&gt;
| Ruby on Rails||Ruby||[http://prototypejs.org/ Prototype], [http://script.aculo.us/ script.aculo.us], [http://jquery.com/? jQuery]||Yes (ActiveRecord, Action Pack)||Push||Unit Tests, Functional Tests and Integration Tests||Yes||Plug-in||Yes||Yes||Yes||Yes&lt;br /&gt;
|-&lt;br /&gt;
| CakePHP||PHP &amp;gt;= 5.2||[http://prototypejs.org/ Prototype], [http://script.aculo.us/ script.aculo.us], [http://jquery.com/? jQuery], [http://http://mootools.net/ MooTools]||Yes||Push||Unit tests, object mocking, fixtures, code coverage, memory analysis with SimpleTest and XDebug PHPUnit (cakephp 2.0)||Yes, [http://book.cakephp.org/2.0/en/console-and-shells/schema-management-and-migrations.html CakePHP Schema Shell] by default, and some others||[http://en.wikipedia.org/wiki/Access_control_list ACL-based]||Themes, layouts, views, elements||Memcache, Redis, XCache, APC, File||Validation, security||Yes&lt;br /&gt;
|-&lt;br /&gt;
| Django||Python||Yes||Yes||Push||unittest, test client, LiveServerTestCase||Provided by South(http://south.aeracode.org/), Django Evolution||[http://en.wikipedia.org/wiki/Access_control_list ACL-based]||Django Template Language||Cache Framework||Django Forms API||No, not by default&lt;br /&gt;
|-&lt;br /&gt;
| Play||Scala/Java||Yes||Yes||Push-pull||Unit test, Functional test, Selenium||Yes, similar to Ruby on Rails||via Core Security module||Yes||Yes||Server-side validation||Yes&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==External links==&lt;br /&gt;
*[http://www.playframework.com/documentation/2.1.0/Home Play 2.1 Documentation]&lt;br /&gt;
&lt;br /&gt;
*[https://groups.google.com/forum/#%21forum/play-framework Play Framework Google Group]&lt;br /&gt;
&lt;br /&gt;
*[http://engineering.linkedin.com/play/play-framework-async-io-without-thread-pool-and-callback-hell Play framework at LinkedIn]&lt;br /&gt;
&lt;br /&gt;
*[https://github.com/playframework/Play20/wiki/Modules Play framework at github]&lt;br /&gt;
&lt;br /&gt;
*[http://stackoverflow.com/tags/playframework Stackoverflow Page]&lt;br /&gt;
&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Play_framework Play framework Wiki Page]&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/ch1a_1_rm&amp;diff=88420</id>
		<title>CSC/ECE 517 Fall 2014/ch1a 1 rm</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/ch1a_1_rm&amp;diff=88420"/>
		<updated>2014-09-25T21:04:11Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: /* History */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/document/d/1eq3XHiUUBIrEBx-R2Mgolaw7HttSgzPniwDLEF5oVk0/edit?pli=1 Writeup Page]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Play Framework'''&lt;br /&gt;
&lt;br /&gt;
Play is modern web framework that provides support for writing scalable applications in either Java or Scala. It is an open source web framework and follows model–view–controller [http://en.wikipedia.org/wiki/Model-view-controller MVC] architectural pattern. It mainly focuses on being stateless and non-blocking I/O which is one of the main drawbacks among its competitors like Tomcat, [http://en.wikipedia.org/wiki/Spring_Framework Spring MVC] etc. Unlike these, Play’s approach is not threaded, it is a framework that is based on event model. This support for a full HTTP asynchronous programming model, makes Play an ideal framework for writing highly-distributed systems while maintaining performance, reliability and developer productivity.&lt;br /&gt;
&lt;br /&gt;
Play is built on [http://en.wikipedia.org/wiki/Akka_(toolkit) Akka](Actor based model), providing predictable and minimal resource consumption for highly scalable applications. It used for handling highly concurrent systems and allows to develop applications in both Java and Scala.&amp;lt;ref&amp;gt; http://www.playframework.com &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Normal.png‎|right|]] &lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==History==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Play Framework development started back in 2007 at Zenexity but it’s first release as a open source framework was available not available until 2009.&lt;br /&gt;
In May 2008 the first published code for 1.0 appeared on Launchpad. This was followed by a full 1.0 release in October 2009.&lt;br /&gt;
&lt;br /&gt;
Play 1.1 &amp;lt;ref name=&amp;quot;history&amp;quot;&amp;gt;http://en.wikipedia.org/wiki/Play_framework#History&amp;lt;/ref&amp;gt; was released in November 2010 after a move from Launchpad to GitHub. It included a migration from Apache MINA to JBoss Netty, Scala support, native GlassFishcontainer, an asynchronous web services library, OAuth support, HTTPS support and other features.&lt;br /&gt;
&lt;br /&gt;
Play 1.2 &amp;lt;ref name=&amp;quot;history&amp;quot;/&amp;gt; was released in April 2011. It included dependency management with Apache Ivy, support for WebSocket, integrated database migration (reversion is not implemented yet), a switch to the H2 database and other features.&lt;br /&gt;
&lt;br /&gt;
Play 2.0 &amp;lt;ref name=&amp;quot;history&amp;quot;/&amp;gt; was released on March 13, 2012 in conjunction with Typesafe Stack 2.0.&lt;br /&gt;
&lt;br /&gt;
Play 2.1 &amp;lt;ref name=&amp;quot;history&amp;quot;/&amp;gt; was released on February 6, 2013, upgraded to Scala 2.10 and introduced, among other new features, modularisation, a new JSON API, filters and RequireJS support.&lt;br /&gt;
&lt;br /&gt;
Play 2.2 &amp;lt;ref name=&amp;quot;history&amp;quot;/&amp;gt; was released on September 20, 2013. Upgraded support for SBT to 0.13, better support for buffering, built in support for gzip and new stage and dist tasks with support for native packaging on several platforms such as OS X (DMG), Linux (RPM, DEB), and Windows (MSI) as well as zip files.&lt;br /&gt;
&lt;br /&gt;
Play 2.3&amp;lt;ref&amp;gt;https://www.playframework.com/documentation/2.3.x/Highlights23&amp;lt;/ref&amp;gt; has updated to include Activator, improved build environment(sbt), compatibilty with Java 8. This version of Play has been built on multiple version of Scala both 2.10 and 2.11. The WS client library has been refactored into its own library so that Play can have multiple WSClient objects, rather than only using the WS singleton. A method to use actors for handling websocket interactions has been incorporated for both Java and Scala. Anorm ( a simple data access layer that uses plain SQL to interact with the database and provides an API to parse and transform the resulting datasets) has been updated to include type safety, option parsing, error handling.&lt;br /&gt;
&lt;br /&gt;
==Development with Play== &lt;br /&gt;
&lt;br /&gt;
Let us see the features offered by Play from a developers perspective, who wants to develop a web application in Play framework.&lt;br /&gt;
===Installing Play===&lt;br /&gt;
To install Play framework, download the binaries from [https://www.playframework.com/download download page] and extract the contents to any folder. Add the extracted folder to path variable&amp;lt;ref&amp;gt;https://www.playframework.com/documentation/2.3.x/Installing &amp;lt;/ref&amp;gt; and verify whether you were able to execute the below command :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 activator ui&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This starts the play server and if everything goes well, you should see a default play application running at http: //127.0.0.1:8888/home .&lt;br /&gt;
&lt;br /&gt;
===Creating a new project===&lt;br /&gt;
&lt;br /&gt;
To create a new project just type the below command and Play will take care of creating directory structure for your app with a standard layout. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 activator new &amp;lt;app name&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you are wondering what folders were created and what they imply, here is a brief explanation to get you started :&lt;br /&gt;
&lt;br /&gt;
*app folder: It contains the main part of the application,i.e.,models, views, controllers. All the source code is present here.&lt;br /&gt;
&lt;br /&gt;
*conf folder: It will contain all the configuration files especially the application.conf, the routes file and the messages file used for [https://www.playframework.com/documentation/1.2/i18n Internationalization](a way of adopting your application to different languages for different regions). The main entry point of the application is conf/routes file, it will contain the list of URL’s that are accessible in a  application.&lt;br /&gt;
&lt;br /&gt;
*lib folder: It is used for extending libraries.&lt;br /&gt;
 &lt;br /&gt;
*public: It used for all static files like JavaScript files, style sheets and images directories, resources which are available publicly.&lt;br /&gt;
&lt;br /&gt;
*test folder: All the application tests are written in this folder, JUnit for functional testing and Selenium tests for Web application testing.&lt;br /&gt;
&lt;br /&gt;
There won’t be any predefined folder to store Java .class files, as Play doesn’t need one. It internally uses eclipse compiler and compiles Java classes on the fly. This gives the ability to reflect the changes made in Java files, without having to compile them again. Another advantage of having an inbuilt compiler is that Play will create a better error report by showing the point of failure &amp;lt;ref&amp;gt;http://stackoverflow.com/questions/11704951/play-framework-no-need-to-compile&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===How to run an application?===&lt;br /&gt;
&lt;br /&gt;
Navigate to the app directory and execute below command :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
activator run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Your application will be loaded and a web server is started at 9000 port. Application can be accessed at http://localhost:9000/ &lt;br /&gt;
&lt;br /&gt;
Similar to [http://rubyonrails.org/ Rails], Play also uses config/routes file to map the request URL to the respective controller method. A sample entry looks like this :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Get                      /                                     Users.index&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above line invokes index() method in Users controller when you access the application home page.&lt;br /&gt;
&lt;br /&gt;
You can either use a text editor to make code changes or even there is a support for IDEs like [https://netbeans.org/ Netbeans] and [https://www.eclipse.org/ Eclipse] in Play. If you want to set up a Java IDE, please check [https://www.playframework.com/documentation/1.1.1/ide this page]. &lt;br /&gt;
&lt;br /&gt;
===Database support===&lt;br /&gt;
&lt;br /&gt;
Play comes with an inbuilt Database called HSQLDB&amp;lt;ref&amp;gt;http://en.wikipedia.org/wiki/HSQLDB&amp;lt;/ref&amp;gt;, this is an in-memory database and if you want to use any other persisting databases like [http://www.oracle.com/us/products/database/overview/index.html Oracle], [http://www.postgresql.org/ Postgres] etc, you can add those configs in conf/application.conf file. Play will connect to the specified database while application startup.&lt;br /&gt;
 &lt;br /&gt;
Play uses 'Object Relational Mapper'  to persist the model objects to a persistent DB. JPA&amp;lt;ref&amp;gt;http://en.wikipedia.org/wiki/Java_Persistence_API&amp;lt;/ref&amp;gt; is a Java specification that defines a standard API for object relational mapping. As implementation of JPA, play uses the well-known Hibernate framework.&lt;br /&gt;
&lt;br /&gt;
===Testing===&lt;br /&gt;
&lt;br /&gt;
To run a test case, you need to start the application in a special ‘test’ mode. Stop the currently running application, open a command line and type:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 activator test&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The 'play test' command is almost the same than 'play run', except that it loads a test runner module that allows to run test suite directly from a browser. When you run a play application in test mode, play will automatically switch to the test framework id and load the application.conf file accordingly. Check this page for more information. Open a browser to the http://localhost:9000/@tests URL to see the test runner. &lt;br /&gt;
&lt;br /&gt;
Similar to Rails, one can use Fixtures to load the test data in test. These data files reside in appname/test/ folder.&lt;br /&gt;
&lt;br /&gt;
Play gives you a way to test directly the controller part of the application using [http://junit.org/ JUnit]. These are called 'Functional tests'. Basically a functional test calls the play ActionInvoker directly, simulating an HTTP request. So we give an HTTP method, an URI and HTTP parameters. Play then routes the request, invokes the corresponding action and sends you back the filled response. You can then analyze it to check that the response content is like you expected.&lt;br /&gt;
&lt;br /&gt;
Play provides an additional functionality for [http://www.seleniumhq.org/ Selenium] tests, which are specifically written for web based applications. The benefit of using Selenium is that it will test your application in your browser and not a built in simulator.&lt;br /&gt;
&lt;br /&gt;
===Play Templates===&lt;br /&gt;
&lt;br /&gt;
Play has an efficient templating system which allows to dynamically generate HTML, XML, JSON or any text based format document. The template engine uses Groovy as an expression language. A tag system allows you to create reusable functions. Templates are stored in the app/views directory.&lt;br /&gt;
&lt;br /&gt;
This template language is useful in various ways and you can read more about it [https://www.playframework.com/documentation/1.0/templates here]&lt;br /&gt;
&lt;br /&gt;
===Play Modules===&lt;br /&gt;
&lt;br /&gt;
A play application can be assembled from several application modules. This lets you reuse components across several applications or split a large application into several smaller ones. A module is just another play application; however some differences exist in the way resources are loaded for an application module :&lt;br /&gt;
A module does not have a conf/application.conf file.&lt;br /&gt;
A module can have a conf/routes file, but these routes will not be loaded automatically.&lt;br /&gt;
All files are first searched for in the main application path, then in all loaded modules.&lt;br /&gt;
Everything in a module is optional.&lt;br /&gt;
You can create a module with the play new command, just like you do for any other application.&lt;br /&gt;
&lt;br /&gt;
To load an external module&amp;lt;ref&amp;gt;https://www.playframework.com/modules&amp;lt;/ref&amp;gt;, just declare it in the application.conf file of main application. One of such useful modules in CRUD module. Using [http://en.wikipedia.org/wiki/Create,_read,_update_and_delete CRUD] you can easily configure your application to have an administration area where you can add/update/delete any model objects present in your application.&lt;br /&gt;
&lt;br /&gt;
Another such frequently used module is a code coverage module based on the [http://cobertura.github.io/cobertura/ Cobertura] tool.&lt;br /&gt;
&lt;br /&gt;
==Why Play?==&lt;br /&gt;
&lt;br /&gt;
Play is a lightweight framework that offers so many options for [http://en.wikipedia.org/wiki/Java_%28programming_language%29 Java] and [http://en.wikipedia.org/wiki/Scala_%28programming_language%29 Scala] developers, without compromising much on productivity. Here are some of the features describing why one should opt for Play:&lt;br /&gt;
&lt;br /&gt;
===Developer Friendly=== &lt;br /&gt;
*Change the code wherever like Java classes or Templates and just hit refresh to see your changes.&lt;br /&gt;
*Lot of support for testing tools.&lt;br /&gt;
&lt;br /&gt;
===Scalable and Efficient===&lt;br /&gt;
*Play is built on Akka, so it supports non-blocking  I/O&amp;lt;ref&amp;gt;http://www.playframework.com/documentation/2.0.4/ScalaAsync&amp;lt;/ref&amp;gt;. This means it's very easy and inexpensive to make remote calls in parallel, which is important for high performance apps in a service oriented architecture.&lt;br /&gt;
&lt;br /&gt;
===Good Support===&lt;br /&gt;
*Commercial support is provided by [http://zenexity.com/ Zenexity] and [http://typesafe.com/ Typesafe].&lt;br /&gt;
*Easy cloud hosting options like Stax cloud hosting platform and can be deployed virtually anywhere: inside Servlet containers, as standalone servers, in Google Application Engine etc.&lt;br /&gt;
&lt;br /&gt;
===Open source===&lt;br /&gt;
*Play is a open source project and this enables you to see what happens under the hood.&lt;br /&gt;
*Also there is vast support through plugins modules etc which can be reused in building your application.&lt;br /&gt;
&lt;br /&gt;
===Built for latest technologies===&lt;br /&gt;
*Play has extensive NoSql and BigData support.&lt;br /&gt;
*Built-in support for REST, JSON/XML handling, non-blocking I/O, WebSockets &amp;lt;ref&amp;gt;http://www.playframework.com/documentation/2.0.4/ScalaWebSockets&amp;lt;/ref&amp;gt;, asset compilation (CoffeeScript, less), ORM, NoSQL support, and many.&lt;br /&gt;
&lt;br /&gt;
===Notable uses of Play===&lt;br /&gt;
&lt;br /&gt;
LinkedIn is the one of the most popular companies that uses play in its production.&amp;lt;ref&amp;gt; https://engineering.linkedin.com/play/play-framework-linkedin&amp;lt;/ref&amp;gt;&lt;br /&gt;
Some of the other websites that use Play are [https://www.coursera.org/ Coursera], Mashape, [http://typesafe.com/ typesafe], [http://prenser.com/ Prenser], [http://subscribe.peachdish.com/ PeachDish]&amp;lt;ref&amp;gt;http://en.wikipedia.org/wiki/Play_framework#Usage&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Comparison with other frameworks==&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|+ Feature-based Comparison on Web Frameworks &amp;lt;ref&amp;gt;http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2014/ch1a_1c_yj#Feature-based_Comparison_on_Web_Frameworks&amp;lt;/ref&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Project'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Language'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Ajax'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''MVC framework'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''MVC push-pull'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Testing framework(s)'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''DB migration framework(s)'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Security framework(s)'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Template framework(s)'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Caching framework(s)'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Form validation framework(s)'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Scaffolding'''&lt;br /&gt;
|-&lt;br /&gt;
| Ruby on Rails||Ruby||[http://prototypejs.org/ Prototype], [http://script.aculo.us/ script.aculo.us], [http://jquery.com/? jQuery]||Yes (ActiveRecord, Action Pack)||Push||Unit Tests, Functional Tests and Integration Tests||Yes||Plug-in||Yes||Yes||Yes||Yes&lt;br /&gt;
|-&lt;br /&gt;
| CakePHP||PHP &amp;gt;= 5.2||[http://prototypejs.org/ Prototype], [http://script.aculo.us/ script.aculo.us], [http://jquery.com/? jQuery], [http://http://mootools.net/ MooTools]||Yes||Push||Unit tests, object mocking, fixtures, code coverage, memory analysis with SimpleTest and XDebug PHPUnit (cakephp 2.0)||Yes, [http://book.cakephp.org/2.0/en/console-and-shells/schema-management-and-migrations.html CakePHP Schema Shell] by default, and some others||[http://en.wikipedia.org/wiki/Access_control_list ACL-based]||Themes, layouts, views, elements||Memcache, Redis, XCache, APC, File||Validation, security||Yes&lt;br /&gt;
|-&lt;br /&gt;
| Django||Python||Yes||Yes||Push||unittest, test client, LiveServerTestCase||Provided by South(http://south.aeracode.org/), Django Evolution||[http://en.wikipedia.org/wiki/Access_control_list ACL-based]||Django Template Language||Cache Framework||Django Forms API||No, not by default&lt;br /&gt;
|-&lt;br /&gt;
| Play||Scala/Java||Yes||Yes||Push-pull||Unit test, Functional test, Selenium||Yes, similar to Ruby on Rails||via Core Security module||Yes||Yes||Server-side validation||Yes&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==External links==&lt;br /&gt;
*[http://www.playframework.com/documentation/2.1.0/Home Play 2.1 Documentation]&lt;br /&gt;
&lt;br /&gt;
*[https://groups.google.com/forum/#%21forum/play-framework Play Framework Google Group]&lt;br /&gt;
&lt;br /&gt;
*[http://engineering.linkedin.com/play/play-framework-async-io-without-thread-pool-and-callback-hell Play framework at LinkedIn]&lt;br /&gt;
&lt;br /&gt;
*[https://github.com/playframework/Play20/wiki/Modules Play framework at github]&lt;br /&gt;
&lt;br /&gt;
*[http://stackoverflow.com/tags/playframework Stackoverflow Page]&lt;br /&gt;
&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Play_framework Play framework Wiki Page]&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/ch1a_1_rm&amp;diff=88418</id>
		<title>CSC/ECE 517 Fall 2014/ch1a 1 rm</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/ch1a_1_rm&amp;diff=88418"/>
		<updated>2014-09-25T21:03:02Z</updated>

		<summary type="html">&lt;p&gt;Ravnee: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/document/d/1eq3XHiUUBIrEBx-R2Mgolaw7HttSgzPniwDLEF5oVk0/edit?pli=1 Writeup Page]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Play Framework'''&lt;br /&gt;
&lt;br /&gt;
Play is modern web framework that provides support for writing scalable applications in either Java or Scala. It is an open source web framework and follows model–view–controller [http://en.wikipedia.org/wiki/Model-view-controller MVC] architectural pattern. It mainly focuses on being stateless and non-blocking I/O which is one of the main drawbacks among its competitors like Tomcat, [http://en.wikipedia.org/wiki/Spring_Framework Spring MVC] etc. Unlike these, Play’s approach is not threaded, it is a framework that is based on event model. This support for a full HTTP asynchronous programming model, makes Play an ideal framework for writing highly-distributed systems while maintaining performance, reliability and developer productivity.&lt;br /&gt;
&lt;br /&gt;
Play is built on [http://en.wikipedia.org/wiki/Akka_(toolkit) Akka](Actor based model), providing predictable and minimal resource consumption for highly scalable applications. It used for handling highly concurrent systems and allows to develop applications in both Java and Scala.&amp;lt;ref&amp;gt; http://www.playframework.com &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Normal.png‎|right|]] &lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==History==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Play Framework development started back in 2007 at Zenexity but it’s first release as a open source framework was available not available until 2009.&lt;br /&gt;
In May 2008 the first published code for 1.0 appeared on Launchpad. This was followed by a full 1.0 release in October 2009.&amp;lt;ref name=&amp;quot;history&amp;quot;&amp;gt;http://en.wikipedia.org/wiki/Play_framework#History&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Play 1.1 &amp;lt;ref name=&amp;quot;history&amp;quot;/&amp;gt;was released in November 2010 after a move from Launchpad to GitHub. It included a migration from Apache MINA to JBoss Netty, Scala support, native GlassFishcontainer, an asynchronous web services library, OAuth support, HTTPS support and other features.&lt;br /&gt;
&lt;br /&gt;
Play 1.2 &amp;lt;ref name=&amp;quot;history&amp;quot;/&amp;gt;was released in April 2011. It included dependency management with Apache Ivy, support for WebSocket, integrated database migration (reversion is not implemented yet), a switch to the H2 database and other features.&lt;br /&gt;
&lt;br /&gt;
Play 2.0 &amp;lt;ref name=&amp;quot;history&amp;quot;/&amp;gt;was released on March 13, 2012 in conjunction with Typesafe Stack 2.0.&lt;br /&gt;
&lt;br /&gt;
Play 2.1 &amp;lt;ref name=&amp;quot;history&amp;quot;/&amp;gt;was released on February 6, 2013, upgraded to Scala 2.10 and introduced, among other new features, modularisation, a new JSON API, filters and RequireJS support.&lt;br /&gt;
&lt;br /&gt;
Play 2.2 &amp;lt;ref name=&amp;quot;history&amp;quot;/&amp;gt;was released on September 20, 2013. Upgraded support for SBT to 0.13, better support for buffering, built in support for gzip and new stage and dist tasks with support for native packaging on several platforms such as OS X (DMG), Linux (RPM, DEB), and Windows (MSI) as well as zip files.&lt;br /&gt;
&lt;br /&gt;
Play 2.3&amp;lt;ref&amp;gt;https://www.playframework.com/documentation/2.3.x/Highlights23&amp;lt;/ref&amp;gt; has updated to include Activator, improved build environment(sbt), compatibilty with Java 8. This version of Play has been built on multiple version of Scala both 2.10 and 2.11. The WS client library has been refactored into its own library so that Play can have multiple WSClient objects, rather than only using the WS singleton. A method to use actors for handling websocket interactions has been incorporated for both Java and Scala. Anorm ( a simple data access layer that uses plain SQL to interact with the database and provides an API to parse and transform the resulting datasets) has been updated to include type safety, option parsing, error handling.&lt;br /&gt;
&lt;br /&gt;
==Development with Play== &lt;br /&gt;
&lt;br /&gt;
Let us see the features offered by Play from a developers perspective, who wants to develop a web application in Play framework.&lt;br /&gt;
===Installing Play===&lt;br /&gt;
To install Play framework, download the binaries from [https://www.playframework.com/download download page] and extract the contents to any folder. Add the extracted folder to path variable&amp;lt;ref&amp;gt;https://www.playframework.com/documentation/2.3.x/Installing &amp;lt;/ref&amp;gt; and verify whether you were able to execute the below command :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 activator ui&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This starts the play server and if everything goes well, you should see a default play application running at http: //127.0.0.1:8888/home .&lt;br /&gt;
&lt;br /&gt;
===Creating a new project===&lt;br /&gt;
&lt;br /&gt;
To create a new project just type the below command and Play will take care of creating directory structure for your app with a standard layout. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 activator new &amp;lt;app name&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you are wondering what folders were created and what they imply, here is a brief explanation to get you started :&lt;br /&gt;
&lt;br /&gt;
*app folder: It contains the main part of the application,i.e.,models, views, controllers. All the source code is present here.&lt;br /&gt;
&lt;br /&gt;
*conf folder: It will contain all the configuration files especially the application.conf, the routes file and the messages file used for [https://www.playframework.com/documentation/1.2/i18n Internationalization](a way of adopting your application to different languages for different regions). The main entry point of the application is conf/routes file, it will contain the list of URL’s that are accessible in a  application.&lt;br /&gt;
&lt;br /&gt;
*lib folder: It is used for extending libraries.&lt;br /&gt;
 &lt;br /&gt;
*public: It used for all static files like JavaScript files, style sheets and images directories, resources which are available publicly.&lt;br /&gt;
&lt;br /&gt;
*test folder: All the application tests are written in this folder, JUnit for functional testing and Selenium tests for Web application testing.&lt;br /&gt;
&lt;br /&gt;
There won’t be any predefined folder to store Java .class files, as Play doesn’t need one. It internally uses eclipse compiler and compiles Java classes on the fly. This gives the ability to reflect the changes made in Java files, without having to compile them again. Another advantage of having an inbuilt compiler is that Play will create a better error report by showing the point of failure &amp;lt;ref&amp;gt;http://stackoverflow.com/questions/11704951/play-framework-no-need-to-compile&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===How to run an application?===&lt;br /&gt;
&lt;br /&gt;
Navigate to the app directory and execute below command :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
activator run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Your application will be loaded and a web server is started at 9000 port. Application can be accessed at http://localhost:9000/ &lt;br /&gt;
&lt;br /&gt;
Similar to [http://rubyonrails.org/ Rails], Play also uses config/routes file to map the request URL to the respective controller method. A sample entry looks like this :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Get                      /                                     Users.index&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The above line invokes index() method in Users controller when you access the application home page.&lt;br /&gt;
&lt;br /&gt;
You can either use a text editor to make code changes or even there is a support for IDEs like [https://netbeans.org/ Netbeans] and [https://www.eclipse.org/ Eclipse] in Play. If you want to set up a Java IDE, please check [https://www.playframework.com/documentation/1.1.1/ide this page]. &lt;br /&gt;
&lt;br /&gt;
===Database support===&lt;br /&gt;
&lt;br /&gt;
Play comes with an inbuilt Database called HSQLDB&amp;lt;ref&amp;gt;http://en.wikipedia.org/wiki/HSQLDB&amp;lt;/ref&amp;gt;, this is an in-memory database and if you want to use any other persisting databases like [http://www.oracle.com/us/products/database/overview/index.html Oracle], [http://www.postgresql.org/ Postgres] etc, you can add those configs in conf/application.conf file. Play will connect to the specified database while application startup.&lt;br /&gt;
 &lt;br /&gt;
Play uses 'Object Relational Mapper'  to persist the model objects to a persistent DB. JPA&amp;lt;ref&amp;gt;http://en.wikipedia.org/wiki/Java_Persistence_API&amp;lt;/ref&amp;gt; is a Java specification that defines a standard API for object relational mapping. As implementation of JPA, play uses the well-known Hibernate framework.&lt;br /&gt;
&lt;br /&gt;
===Testing===&lt;br /&gt;
&lt;br /&gt;
To run a test case, you need to start the application in a special ‘test’ mode. Stop the currently running application, open a command line and type:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 activator test&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The 'play test' command is almost the same than 'play run', except that it loads a test runner module that allows to run test suite directly from a browser. When you run a play application in test mode, play will automatically switch to the test framework id and load the application.conf file accordingly. Check this page for more information. Open a browser to the http://localhost:9000/@tests URL to see the test runner. &lt;br /&gt;
&lt;br /&gt;
Similar to Rails, one can use Fixtures to load the test data in test. These data files reside in appname/test/ folder.&lt;br /&gt;
&lt;br /&gt;
Play gives you a way to test directly the controller part of the application using [http://junit.org/ JUnit]. These are called 'Functional tests'. Basically a functional test calls the play ActionInvoker directly, simulating an HTTP request. So we give an HTTP method, an URI and HTTP parameters. Play then routes the request, invokes the corresponding action and sends you back the filled response. You can then analyze it to check that the response content is like you expected.&lt;br /&gt;
&lt;br /&gt;
Play provides an additional functionality for [http://www.seleniumhq.org/ Selenium] tests, which are specifically written for web based applications. The benefit of using Selenium is that it will test your application in your browser and not a built in simulator.&lt;br /&gt;
&lt;br /&gt;
===Play Templates===&lt;br /&gt;
&lt;br /&gt;
Play has an efficient templating system which allows to dynamically generate HTML, XML, JSON or any text based format document. The template engine uses Groovy as an expression language. A tag system allows you to create reusable functions. Templates are stored in the app/views directory.&lt;br /&gt;
&lt;br /&gt;
This template language is useful in various ways and you can read more about it [https://www.playframework.com/documentation/1.0/templates here]&lt;br /&gt;
&lt;br /&gt;
===Play Modules===&lt;br /&gt;
&lt;br /&gt;
A play application can be assembled from several application modules. This lets you reuse components across several applications or split a large application into several smaller ones. A module is just another play application; however some differences exist in the way resources are loaded for an application module :&lt;br /&gt;
A module does not have a conf/application.conf file.&lt;br /&gt;
A module can have a conf/routes file, but these routes will not be loaded automatically.&lt;br /&gt;
All files are first searched for in the main application path, then in all loaded modules.&lt;br /&gt;
Everything in a module is optional.&lt;br /&gt;
You can create a module with the play new command, just like you do for any other application.&lt;br /&gt;
&lt;br /&gt;
To load an external module&amp;lt;ref&amp;gt;https://www.playframework.com/modules&amp;lt;/ref&amp;gt;, just declare it in the application.conf file of main application. One of such useful modules in CRUD module. Using [http://en.wikipedia.org/wiki/Create,_read,_update_and_delete CRUD] you can easily configure your application to have an administration area where you can add/update/delete any model objects present in your application.&lt;br /&gt;
&lt;br /&gt;
Another such frequently used module is a code coverage module based on the [http://cobertura.github.io/cobertura/ Cobertura] tool.&lt;br /&gt;
&lt;br /&gt;
==Why Play?==&lt;br /&gt;
&lt;br /&gt;
Play is a lightweight framework that offers so many options for [http://en.wikipedia.org/wiki/Java_%28programming_language%29 Java] and [http://en.wikipedia.org/wiki/Scala_%28programming_language%29 Scala] developers, without compromising much on productivity. Here are some of the features describing why one should opt for Play:&lt;br /&gt;
&lt;br /&gt;
===Developer Friendly=== &lt;br /&gt;
*Change the code wherever like Java classes or Templates and just hit refresh to see your changes.&lt;br /&gt;
*Lot of support for testing tools.&lt;br /&gt;
&lt;br /&gt;
===Scalable and Efficient===&lt;br /&gt;
*Play is built on Akka, so it supports non-blocking  I/O&amp;lt;ref&amp;gt;http://www.playframework.com/documentation/2.0.4/ScalaAsync&amp;lt;/ref&amp;gt;. This means it's very easy and inexpensive to make remote calls in parallel, which is important for high performance apps in a service oriented architecture.&lt;br /&gt;
&lt;br /&gt;
===Good Support===&lt;br /&gt;
*Commercial support is provided by [http://zenexity.com/ Zenexity] and [http://typesafe.com/ Typesafe].&lt;br /&gt;
*Easy cloud hosting options like Stax cloud hosting platform and can be deployed virtually anywhere: inside Servlet containers, as standalone servers, in Google Application Engine etc.&lt;br /&gt;
&lt;br /&gt;
===Open source===&lt;br /&gt;
*Play is a open source project and this enables you to see what happens under the hood.&lt;br /&gt;
*Also there is vast support through plugins modules etc which can be reused in building your application.&lt;br /&gt;
&lt;br /&gt;
===Built for latest technologies===&lt;br /&gt;
*Play has extensive NoSql and BigData support.&lt;br /&gt;
*Built-in support for REST, JSON/XML handling, non-blocking I/O, WebSockets &amp;lt;ref&amp;gt;http://www.playframework.com/documentation/2.0.4/ScalaWebSockets&amp;lt;/ref&amp;gt;, asset compilation (CoffeeScript, less), ORM, NoSQL support, and many.&lt;br /&gt;
&lt;br /&gt;
===Notable uses of Play===&lt;br /&gt;
&lt;br /&gt;
LinkedIn is the one of the most popular companies that uses play in its production.&amp;lt;ref&amp;gt; https://engineering.linkedin.com/play/play-framework-linkedin&amp;lt;/ref&amp;gt;&lt;br /&gt;
Some of the other websites that use Play are [https://www.coursera.org/ Coursera], Mashape, [http://typesafe.com/ typesafe], [http://prenser.com/ Prenser], [http://subscribe.peachdish.com/ PeachDish]&amp;lt;ref&amp;gt;http://en.wikipedia.org/wiki/Play_framework#Usage&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Comparison with other frameworks==&lt;br /&gt;
{| {{table}}&lt;br /&gt;
|+ Feature-based Comparison on Web Frameworks &amp;lt;ref&amp;gt;http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2014/ch1a_1c_yj#Feature-based_Comparison_on_Web_Frameworks&amp;lt;/ref&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Project'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Language'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Ajax'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''MVC framework'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''MVC push-pull'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Testing framework(s)'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''DB migration framework(s)'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Security framework(s)'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Template framework(s)'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Caching framework(s)'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Form validation framework(s)'''&lt;br /&gt;
| align=&amp;quot;center&amp;quot; style=&amp;quot;background:#f0f0f0;&amp;quot;|'''Scaffolding'''&lt;br /&gt;
|-&lt;br /&gt;
| Ruby on Rails||Ruby||[http://prototypejs.org/ Prototype], [http://script.aculo.us/ script.aculo.us], [http://jquery.com/? jQuery]||Yes (ActiveRecord, Action Pack)||Push||Unit Tests, Functional Tests and Integration Tests||Yes||Plug-in||Yes||Yes||Yes||Yes&lt;br /&gt;
|-&lt;br /&gt;
| CakePHP||PHP &amp;gt;= 5.2||[http://prototypejs.org/ Prototype], [http://script.aculo.us/ script.aculo.us], [http://jquery.com/? jQuery], [http://http://mootools.net/ MooTools]||Yes||Push||Unit tests, object mocking, fixtures, code coverage, memory analysis with SimpleTest and XDebug PHPUnit (cakephp 2.0)||Yes, [http://book.cakephp.org/2.0/en/console-and-shells/schema-management-and-migrations.html CakePHP Schema Shell] by default, and some others||[http://en.wikipedia.org/wiki/Access_control_list ACL-based]||Themes, layouts, views, elements||Memcache, Redis, XCache, APC, File||Validation, security||Yes&lt;br /&gt;
|-&lt;br /&gt;
| Django||Python||Yes||Yes||Push||unittest, test client, LiveServerTestCase||Provided by South(http://south.aeracode.org/), Django Evolution||[http://en.wikipedia.org/wiki/Access_control_list ACL-based]||Django Template Language||Cache Framework||Django Forms API||No, not by default&lt;br /&gt;
|-&lt;br /&gt;
| Play||Scala/Java||Yes||Yes||Push-pull||Unit test, Functional test, Selenium||Yes, similar to Ruby on Rails||via Core Security module||Yes||Yes||Server-side validation||Yes&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==External links==&lt;br /&gt;
*[http://www.playframework.com/documentation/2.1.0/Home Play 2.1 Documentation]&lt;br /&gt;
&lt;br /&gt;
*[https://groups.google.com/forum/#%21forum/play-framework Play Framework Google Group]&lt;br /&gt;
&lt;br /&gt;
*[http://engineering.linkedin.com/play/play-framework-async-io-without-thread-pool-and-callback-hell Play framework at LinkedIn]&lt;br /&gt;
&lt;br /&gt;
*[https://github.com/playframework/Play20/wiki/Modules Play framework at github]&lt;br /&gt;
&lt;br /&gt;
*[http://stackoverflow.com/tags/playframework Stackoverflow Page]&lt;br /&gt;
&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Play_framework Play framework Wiki Page]&lt;/div&gt;</summary>
		<author><name>Ravnee</name></author>
	</entry>
</feed>