<?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=Szhang29</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=Szhang29"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Szhang29"/>
	<updated>2026-06-04T07:08:36Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=97001</id>
		<title>CSC/ECE 517 Spring 2015 S1524 FSZZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=97001"/>
		<updated>2015-04-28T16:14:00Z</updated>

		<summary type="html">&lt;p&gt;Szhang29: /* Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1524. Refactor staggered-deadline assignments&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Overview'''==&lt;br /&gt;
===Introduction to Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza. Github]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Staggered Deadlines===&lt;br /&gt;
Staggered deadlines involve planning alternate submission dates for papers, projects, or exams when a student has conflicting due dates for these.  The key part of staggered deadlines is the planning. Staggered deadlines are always established well in advance of the scheduled due date. It is the advanced planning of these deadlines that makes them &amp;quot;staggered deadlines&amp;quot; rather than extensions&amp;lt;ref&amp;gt;[http://pages.vassar.edu/accessingvassar/2013/01/15/difficulties-with-staggered-deadlines/ Elmichaels. ''Difficulties with Staggered Deadlines''. Jan 15, 2013]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=='''Documentation'''==&lt;br /&gt;
'''Controller'''&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/5c7c8579b6fe44e19f96183af43fab26cd26d1d1/app/controllers/sign_up_sheet_controller.rb sign_up_sheet_controller.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/rails4/app/controllers/assignments_controller.rb assignments_controller.rb]&lt;br /&gt;
&lt;br /&gt;
'''Model'''&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/142a9134a18bd7cc552c6937fe5c93a1e0f4947d/app/models/assignment_form.rb assignment_form.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/72b61129c70a88d1c1ae814a53cb83b6a15a3fa8/app/models/assignment.rb assignment.rb]&lt;br /&gt;
&lt;br /&gt;
'''View'''&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/3443fe119ee4ae02c676131b07cd42c2771f88e5/app/views/sign_up_sheet/add_signup_topics_staggered.html.erb add_signup_topics_staggered.html.erb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/651176622bff84b09c7de9f745a246279501deb8/app/views/tree_display/actions/_assignments_actions.html.erb _assignments_actions.html.erb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/f2495041c0d66ee5d35c3da23d45e043072f7a1c/app/views/sign_up_sheet/_table_header.html.erb _table_header.html.erb]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
==='''Background'''===&lt;br /&gt;
In this semester's 517 class.  Wiki 1a and Wiki 1b are structured as separate assignments, with separate signup sheets, teams, and reviews.  But really, since only one of the two was done by any student, it would've been better to have a single assignment.  Still, some topics could be done soon after the course started, whereas others were better done after we had studied related topics in class.&lt;br /&gt;
&lt;br /&gt;
==='''Staggered-deadline Assignment'''===&lt;br /&gt;
This raises the idea of a ''staggered-deadline assignment'', where different topics have different submission and review deadlines, rather than all topics having the same deadline. &lt;br /&gt;
&lt;br /&gt;
==='''Benefit'''===&lt;br /&gt;
* '''Easy to manage.''' Because in the past, instructor has to build two separate assignments for Wiki 1a and 1b, now one assignment for Wiki is enough. &lt;br /&gt;
&lt;br /&gt;
* '''Increase flexibility.''' For instance, when an OSS team facing a much more difficult problem than other teams, instructor may postpone their deadline several days. It will make Expertiza more humanize.&lt;br /&gt;
&lt;br /&gt;
* '''Take time to do calibration.''' We find that two Wiki assignments started at Jan. 28th and ended at Feb. 25th, which takes too much time. And with staggered-deadline assignment, we can distribute less time on them. And we can take redundant time to do calibrating. Because we find that many students actually do not know how to evaluate other ones' work, even there are some rubrics offered. So we recommend to let students grade sample assignments first, then calibrate their grading behaviors. Although it will take some time, we consider it is important to help students distinguish good assignments from common ones.&lt;br /&gt;
&lt;br /&gt;
=='''Product Verion Functionality'''==&lt;br /&gt;
* In production version, instructor can set ''Submission deadline'', ''Review deadline'' and ''Metareview deadline'' for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments_M.png‎  |frame|center|Set different deadline for each topic]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Also, instructor can set the dependencies of different topics. And there is a dependency graph generated automatically.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments1_M.png‎  |frame|center|Dependency graph for all topics]]&lt;br /&gt;
&lt;br /&gt;
=='''Design Pattern'''==&lt;br /&gt;
* '''MVC'''&lt;br /&gt;
**Model–view–controller (MVC) is a software architectural pattern for implementing user interfaces. It divides a given software application into three interconnected parts, so as to separate internal representations of information from the ways that information is presented to or accepted from the user.&amp;lt;ref&amp;gt;[http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller. ''Model–view–controller''. Wikipedia]&amp;lt;/ref&amp;gt;&lt;br /&gt;
**We need to modify model, view and controller in order to fix this functionality.&lt;br /&gt;
&lt;br /&gt;
* '''Publish-subscribe'''&lt;br /&gt;
**In software architecture, publish–subscribe is a messaging pattern where senders of messages, called publishers, do not program the messages to be sent directly to specific receivers, called subscribers. Instead, published messages are characterized into classes, without knowledge of what, if any, subscribers there may be. Similarly, subscribers express interest in one or more classes, and only receive messages that are of interest, without knowledge of what, if any, publishers there are.&amp;lt;ref&amp;gt;[http://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern. ''Publish–subscribe pattern''. Wikipedia]&amp;lt;/ref&amp;gt;&lt;br /&gt;
** When instructor set an assignment as staggered-dealine assignment, in theory, all the students will know.&lt;br /&gt;
&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Create staggered-deadline assignment'''&lt;br /&gt;
** '''Actor:''' Instructor&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** Instructor logs in Expertiza.&lt;br /&gt;
*** Instructor creates a new staggered-deadline assignment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Peer review only'''&lt;br /&gt;
** '''Actor:''' Student finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Hand in assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
*** Write author feedback to reviewer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Peer review and still work on assignments'''&lt;br /&gt;
** '''Actor:''' Student not finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Work on assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:UseCaseDiagram1_M.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Error Message Present'''==&lt;br /&gt;
* First, login expertiza, in the &amp;quot;Manage Content&amp;quot; page, create a new assignment. Then, as shown below, choose the &amp;quot;pencil&amp;quot; icon to edit the assignment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment1.jpg |frame|center|Assignment panel 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Check&amp;quot;Has topics?&amp;quot; and &amp;quot;Staggered deadline assignment?&amp;quot; two checkbox, and create new topics in &amp;quot;Topics&amp;quot; panel, click &amp;quot;save&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment2.jpg |frame|center|Create Topics]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Back to the &amp;quot;Manage Content&amp;quot; page, choose the &amp;quot;Edit signup sheet&amp;quot; icon.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment3.jpg |frame|center|Assignment panel 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Error: can't write unknown attribute 't_id'.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment4.jpg |frame|center|Error]]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Analysis'''==&lt;br /&gt;
* After discussing with professor, the &amp;quot;sign up sheet&amp;quot; icon in assignment pop up panel should be moved. Because that icon has the same functionality as &amp;quot;topic&amp;quot; panel in assignment edit window. These work has already done by [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2015/oss_E1509_lds OSS1509]. So we have to move all the staggered-deadline realted code to the [https://github.com/expertiza/expertiza/blob/rails4/app/controllers/assignments_controller.rb assignments_controller.rb] and [https://github.com/expertiza/expertiza/blob/rails4/app/views/assignments/edit.html.erb assignments/edit.html.erb].&lt;br /&gt;
&lt;br /&gt;
* In &amp;quot;sign_up_sheet_controller&amp;quot;, there are several errors and confusions in function &amp;quot;add_sign_up_topic&amp;quot;. The function is used to display a page that lists all the available topics for a staggered-deadline assignment.&amp;lt;br&amp;gt; &lt;br /&gt;
See the function code below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_signup_topic&lt;br /&gt;
  load_add_signup_topics(params[:id])&lt;br /&gt;
&lt;br /&gt;
  @review_rounds = Assignment.find(params[:id]).get_review_rounds&lt;br /&gt;
  @topics = SignUpTopic.where(assignment_id: params[:id])&lt;br /&gt;
&lt;br /&gt;
  #Use this until you figure out how to initialize this array&lt;br /&gt;
  @duedates = SignUpTopic.find_by_sql(&amp;quot;SELECT s.id as topic_id FROM sign_up_topics s WHERE s.assignment_id = &amp;quot; + params[:id].to_s)&lt;br /&gt;
&lt;br /&gt;
  unless @topics.nil?&lt;br /&gt;
    i=0&lt;br /&gt;
    @topics.each { |topic|&lt;br /&gt;
&lt;br /&gt;
      @duedates[i]['t_id'] = topic.id&lt;br /&gt;
      @duedates[i]['topic_identifier'] = topic.topic_identifier&lt;br /&gt;
      @duedates[i]['topic_name'] = topic.topic_name&lt;br /&gt;
&lt;br /&gt;
      for j in 1..@review_rounds&lt;br /&gt;
        duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('submission').id).first&lt;br /&gt;
        duedate_rev = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('review').id).first&lt;br /&gt;
        if !duedate_subm.nil? &amp;amp;&amp;amp; !duedate_rev.nil?&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        else&lt;br /&gt;
          #the topic is new. so copy deadlines from assignment&lt;br /&gt;
          set_of_due_dates = DueDate.where(assignment_id: params[:id])&lt;br /&gt;
          set_of_due_dates.each { |due_date|&lt;br /&gt;
            create_topic_deadline(due_date, 0, topic.id)&lt;br /&gt;
          }&lt;br /&gt;
&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
      end&lt;br /&gt;
      duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('metareview').id).first&lt;br /&gt;
      @duedates[i]['submission_'+ (@review_rounds+1).to_s] = !(duedate_subm.nil?)?(DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)):nil&lt;br /&gt;
      i = i + 1&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The main confusions are:&lt;br /&gt;
* In line 8, the variable &amp;quot;duedates&amp;quot; are declared as type &amp;quot;SignUpTopic&amp;quot;. The naming is quite confusing.&lt;br /&gt;
* In line 14, the SignUpTopic class doesn't have a column &amp;quot;t_id&amp;quot;, it raises an error. We think it should be &amp;quot;topic_id&amp;quot;.&lt;br /&gt;
* From the code we can guess the variable &amp;quot;duedates&amp;quot; is used to store the deadline for each topic. The class &amp;quot;DueData&amp;quot; does exist, but it does not have column &amp;quot;topic_identifier&amp;quot; or &amp;quot;topic_name&amp;quot;. It only stores the deadline for a single assignment.&lt;br /&gt;
&lt;br /&gt;
=='''Puzzle'''==&lt;br /&gt;
* If there is more than one round, which means students can submit their assignments more than once, so the staggered-deadline should refer to which deadline?&lt;br /&gt;
'''[Professor]''' In a staggered-deadline assignment, there is one submission deadline and one review deadline per round.  These are always set on a per-topic basis.&lt;br /&gt;
If the view currently works (and I think it might), as soon as you make an assignment a staggered-deadline assignment, the Signup Sheet (Topics) page will have a link at the bottom to show deadlines for each topic.  Click it, and you will see a separate text box for each deadline for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* If staggered-deadline of one assignment is even later than the second-round review, is it means that that assignment do not need peer review and go directly into meta-review stage?&lt;br /&gt;
'''[Professor]''' No, there are also separate meta-review deadlines for a staggered-deadline assignment.&lt;br /&gt;
I think in the current implementation, only submission deadlines, review deadlines, and meta-review deadlines vary by topic.  In a more complete implementation, there would be a way for ANY deadline to vary by topic.  This would include signup deadlines, drop-topic deadlines, team-formation deadlines, and any other kind of deadline that is defined later.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* When to set staggered-deadline assignments? Create assignment or Before submission?&lt;br /&gt;
'''[Professor]''' Basically, the staggered-deadline is set at the same time when an assignment is created. But if one team cannot hand in their work with sufficient reasons, instructor may extend the deadline of their topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* What is the meaning of &amp;quot;dependencies&amp;quot; between topics?&lt;br /&gt;
'''[Professor]''' The ''dependencies'' of topics means one topic cannot start until another topic finishes. For instance, ''Ruby'' topic must be finished before ''Rails'' topic.&lt;br /&gt;
&lt;br /&gt;
=='''Workflow'''==&lt;br /&gt;
&lt;br /&gt;
==='''Set topics staggered deadline'''===&lt;br /&gt;
At very beginning, we find that the type of &amp;lt;code&amp;gt;due_date&amp;lt;/code&amp;gt; variable &amp;lt;code&amp;gt;SignUpTopics&amp;lt;/code&amp;gt;. However, we found that many attributes used not belonging to &amp;lt;code&amp;gt;SignUpTopics&amp;lt;/code&amp;gt; class. So we deceide to use has tables instead. In order to keep update the staggered deadline, we put this variable in session. We also comprehended the relationship of corresponding tables. The original due dates are stored in &amp;lt;code&amp;gt;due_date&amp;lt;/code&amp;gt; table. And staggered-deadlines are stored in &amp;lt;code&amp;gt;TopicDeadline&amp;lt;/code&amp;gt; table. This table also stores different deadline types.&lt;br /&gt;
&lt;br /&gt;
Below is &amp;lt;code&amp;gt;save_topic_deadlines&amp;lt;/code&amp;gt; method after refactoring.&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
  #session[:duedates] stores all original duedates info&lt;br /&gt;
  #due_dates stores staggered duedates&lt;br /&gt;
  due_dates = params[:due_date]&lt;br /&gt;
  topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
  review_rounds = Assignment.find(params[:assignment_id]).get_review_rounds&lt;br /&gt;
  # j represents the review rounds&lt;br /&gt;
  j = 0&lt;br /&gt;
  topics.each { |topic|&lt;br /&gt;
    for i in 1..review_rounds&lt;br /&gt;
      topic_deadline_type_subm = DeadlineType.find_by_name('submission').id&lt;br /&gt;
      topic_deadline_subm = TopicDeadline.where(topic_id: session[:duedates][j]['id'].to_i, deadline_type_id: topic_deadline_type_subm, round: i).first&lt;br /&gt;
      topic_deadline_subm.update_attributes({'due_at' =&amp;gt; due_dates[session[:duedates][j]['id'].to_s + '_submission_' + i.to_s + '_due_date']})&lt;br /&gt;
      flash[:error] = &amp;quot;Please enter a valid &amp;quot; + (i &amp;gt; 1 ? &amp;quot;Resubmission deadline &amp;quot; + (i-1).to_s : &amp;quot;Submission deadline&amp;quot;) if topic_deadline_subm.errors.length &amp;gt; 0&lt;br /&gt;
      topic_deadline_type_rev = DeadlineType.find_by_name('review').id&lt;br /&gt;
      topic_deadline_rev = TopicDeadline.where(topic_id: session[:duedates][j]['id'].to_i, deadline_type_id: topic_deadline_type_rev, round:i).first&lt;br /&gt;
      topic_deadline_rev.update_attributes({'due_at' =&amp;gt; due_dates[session[:duedates][j]['id'].to_s + '_review_' + i.to_s + '_due_date']})&lt;br /&gt;
      flash[:error] = &amp;quot;Please enter a valid Review deadline &amp;quot; + (i &amp;gt; 1 ? (i-1).to_s : &amp;quot;&amp;quot;) if topic_deadline_rev.errors.length &amp;gt; 0&lt;br /&gt;
    end&lt;br /&gt;
    topic_deadline_subm = TopicDeadline.where(topic_id: session[:duedates][j]['id'], deadline_type_id:  DeadlineType.find_by_name('metareview').id).first&lt;br /&gt;
    topic_deadline_subm.update_attributes({'due_at' =&amp;gt; due_dates[session[:duedates][j]['id'].to_s + '_submission_' + (review_rounds+1).to_s + '_due_date']})&lt;br /&gt;
    flash[:error] = &amp;quot;Please enter a valid Meta review deadline&amp;quot; if topic_deadline_subm.errors.length &amp;gt; 0&lt;br /&gt;
    j = j + 1&lt;br /&gt;
  }&lt;br /&gt;
  redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==='''Save topics dependency and show dependency graph'''===&lt;br /&gt;
In edit signup sheet for assignment, we want to save topic dependency and show the depandency graph, as show below:&lt;br /&gt;
[[File:save_denpendency.jpg |frame|center|Assignment panel 1]]&lt;br /&gt;
In order to show the dependency graph, we must first save topics dependency and save the topic dependency graph under &amp;lt;code&amp;gt; public/assets/staggered_deadline_assignment_graph &amp;lt;/code&amp;gt; path. We first add new method in 'due_date' model:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def self.assign_start_due_date(assignment_id, set_of_topics)&lt;br /&gt;
&lt;br /&gt;
    #Remember, in create_common_start_time_topics function we reversed the graph so reverse it back&lt;br /&gt;
    set_of_topics = set_of_topics.reverse&lt;br /&gt;
&lt;br /&gt;
    set_of_topics_due_dates = Array.new&lt;br /&gt;
    i=0&lt;br /&gt;
    days_between_submissions = Assignment.find(assignment_id)['days_between_submissions'].to_i&lt;br /&gt;
    set_of_topics.each { |set_of_topic|&lt;br /&gt;
      set_of_due_dates = nil&lt;br /&gt;
      if i==0&lt;br /&gt;
        #take the first set from the table which user stores&lt;br /&gt;
        set_of_due_dates = DueDate.where(assignment_id)&lt;br /&gt;
        offset = 0&lt;br /&gt;
      else&lt;br /&gt;
        set_of_due_dates = TopicDeadline.where(set_of_topics[i-1][0])&lt;br /&gt;
        set_of_due_dates.sort_by { |a, b| a.due_at &amp;lt;=&amp;gt; b.due_at }&lt;br /&gt;
        offset = days_between_submissions&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      set_of_topic.each { |topic_id|&lt;br /&gt;
        #if the due dates have already been created and the save dependency is being clicked,&lt;br /&gt;
        #then delete existing n create again&lt;br /&gt;
        prev_saved_due_dates = TopicDeadline.where(topic_id)&lt;br /&gt;
&lt;br /&gt;
        #Only if there is a dependency for the topic&lt;br /&gt;
        if !prev_saved_due_dates.nil?&lt;br /&gt;
          num_due_dates = prev_saved_due_dates.length&lt;br /&gt;
          #for each due date in the current topic he want to compare it to the previous due date&lt;br /&gt;
          for x in 0..num_due_dates - 1&lt;br /&gt;
            #we don't want the old date to move earlier in time so we save it as the new due date and destroy the old one  &lt;br /&gt;
            if DateTime.parse(set_of_due_dates[x].due_at.to_s) + offset.to_i &amp;lt; DateTime.parse(prev_saved_due_dates[x].due_at.to_s)&lt;br /&gt;
              set_of_due_dates[x] = prev_saved_due_dates[x]&lt;br /&gt;
              offset = 0&lt;br /&gt;
            end&lt;br /&gt;
            prev_saved_due_dates[x].destroy&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        set_of_due_dates.each { |due_date|&lt;br /&gt;
          create_topic_deadline(due_date, offset, topic_id)&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      i = i+1&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, change the &amp;lt;code&amp;gt;save_topic_dependencies&amp;lt;/code&amp;gt; method in &amp;lt;code&amp;gt; sign_up_sheet_controller.rb &amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - redirect_to_sign_up(params[:assignment_id])&lt;br /&gt;
  + redirect_to :action =&amp;gt; 'add_signup_topics_staggered', :id =&amp;gt; params[:assignment_id] &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since we use &amp;lt;code&amp;gt;RGL:Graph#write_to_graphic_file&amp;lt;/code&amp;gt; method to turn the dependency graph into &amp;lt;code&amp;gt;jpg&amp;lt;/code&amp;gt; file, we need to install graphviz in our gems. Otherwise, the RGL will uses &amp;lt;code&amp;gt;dot&amp;lt;/code&amp;gt; files as an intermediary format to produce image formats. If we download the &amp;lt;code&amp;gt;GraphViz&amp;lt;/code&amp;gt; packege, RGL will invoke it to produce a &amp;lt;code&amp;gt;jpg&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'graphviz' &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Then, after we click the &amp;lt;code&amp;gt;Save dependency&amp;lt;/code&amp;gt; button, and click &amp;lt;code&amp;gt;show dependency graph&amp;lt;/code&amp;gt; button, the dependency graph is shown below:&lt;br /&gt;
[[File:show_denpendency.jpg |frame|center|Assignment panel 2]]&lt;br /&gt;
&lt;br /&gt;
==='''Test'''===&lt;br /&gt;
Since we have done several modifications to the Expertiza program, some new tests are needed to test the features.&lt;br /&gt;
We use the stub to simulate an authorized login (as instructor).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ApplicationController.any_instance.stub(:current_role_name).and_return('Instructor')&lt;br /&gt;
ApplicationController.any_instance.stub(:undo_link).and_return(TRUE)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Each time the program executes the &amp;lt;code&amp;gt;current_role_name&amp;lt;/code&amp;gt; function, it gets &amp;quot;instructor&amp;quot;.&lt;br /&gt;
In the test, we mainly test two things: staggered assignments and their corresponding dependency graph.&lt;br /&gt;
* Test the staggered assignment&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should be able to create topic for assignment&amp;quot; do&lt;br /&gt;
  get :create, id: @assignment.id, topic: {topic_name: &amp;quot;New Topic&amp;quot;, max_choosers: 2, topic_identifier: &amp;quot;Ch1&amp;quot;, category: &amp;quot;Programming&amp;quot;}&lt;br /&gt;
  expect(response).should redirect_to(edit_assignment_path(@assignment.id) + &amp;quot;#tabs-5&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
it &amp;quot;should be able to edit topic&amp;quot; do&lt;br /&gt;
  get :edit, id: @topic.id&lt;br /&gt;
  expect(response).to be_success&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
it &amp;quot;should be able to delete topic&amp;quot; do&lt;br /&gt;
  delete :destroy, id: @topic.id, assignment_id: @assignment.id&lt;br /&gt;
  expect(response).should redirect_to edit_assignment_path(@assignment.id) + &amp;quot;#tabs-5&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Test the dependency graph.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should be able to generate topic dependency&amp;quot; do&lt;br /&gt;
    post :save_topic_dependencies, assignment_id: @assignment.id&lt;br /&gt;
    expect(File).to exist(&amp;quot;public/assets/staggered_deadline_assignment_graph/graph_#{@assignment.id}.jpg&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
it &amp;quot;should be able to detect cycles&amp;quot; do&lt;br /&gt;
  post :save_topic_dependencies, assignment_id: @assignment.id,&lt;br /&gt;
       ('topic_dependencies_' + @topic1.id.to_s)=&amp;gt;{&amp;quot;dependent_on&amp;quot;=&amp;gt;[@topic2.id.to_s]},&lt;br /&gt;
       ('topic_dependencies_' + @topic2.id.to_s)=&amp;gt;{&amp;quot;dependent_on&amp;quot;=&amp;gt;[@topic1.id.to_s]}&lt;br /&gt;
  expect(flash[:error]).to eq(&amp;quot;There may be one or more cycles in the dependencies. Please correct them&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Deploy on VCL'''===&lt;br /&gt;
&lt;br /&gt;
* Visit http://vcl.ncsu.edu/ &amp;gt; Make a Reservation&lt;br /&gt;
* Select Ruby on Rails / Expertiza from the &amp;quot;Please select the environment ...&amp;quot; dropdown, select a duration, and then click Create Reservation&lt;br /&gt;
* Once the reservation is available, click Connect&lt;br /&gt;
* Follow the instructions on the connect screen (connect via SSH and then VNC). Connecting to SSH starts up VNC, the graphical environment to which you will connect.&lt;br /&gt;
* When connecting for the first time, it will prompt you for a password to access your (VNC) desktop. You can use any password, and it will be saved for later sessions.&lt;br /&gt;
* Follow the instructions given to connect to VNC. It is recommended to use [https://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=1&amp;amp;cad=rja&amp;amp;uact=8&amp;amp;ved=0CB0QFjAA&amp;amp;url=https%3A%2F%2Fchrome.google.com%2Fwebstore%2Fdetail%2Fvnc%25C2%25AE-viewer-for-google-ch%2Fiabmpiboiopbgfabjmgeedhcmjenhbla&amp;amp;ei=LEY7Veq8C8GNNrvhgegI&amp;amp;usg=AFQjCNGxB1W4GwZrwQWHyBfik1cbjvXMkw VNC Viewer for Google Chrome].&lt;br /&gt;
* Once connected to VNC, you should see Rubymine running.&lt;br /&gt;
* Open a terminal (Applications &amp;gt; Accessories &amp;gt; Terminal), try hitting &amp;lt;ctrl&amp;gt;-C to kill pending task if your terminal does not work properly.&lt;br /&gt;
* Ensure you have at least 20M disk quota available: fs lq . You can allocate more space at https://sysnews.ncsu.edu/tools-bin/usmdb-quota&lt;br /&gt;
* Clone the git repository: git clone (expertiza repository URL)&lt;br /&gt;
* Change to the directory (cd expertiza). You may create a &amp;quot;database.yml&amp;quot; file based on &amp;quot;database.yml.example&amp;quot;.&lt;br /&gt;
* Use rvm use (ruby version) to switch to proper ruby version. Then run bundle install (you may need to downgrade the bundler to avoid bundle install failure) and rake db:migrate to set up development environment.&lt;br /&gt;
* Use &amp;quot;rails s -b 0.0.0.0&amp;quot; to start server which allows the access outside VCL by using url: VCL_ip:3000.&lt;br /&gt;
&lt;br /&gt;
=='''Related materials'''==&lt;br /&gt;
*An [http://research.csc.ncsu.edu/efg/expertiza/reports/Instructor_documentation.doc instructor manual], explaining how to create an deploy an assignment in Expertiza.&lt;br /&gt;
*An [http://research.csc.ncsu.edu/efg/expertiza/presentations/videos/instructor.swf instructor video], slightly dated, showing how to create and deploy an assignment&lt;br /&gt;
* A guide for [[Creating_Custom_Rubric]]&lt;br /&gt;
*For students, a [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_documentation.ppt Powerpoint] or [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_documentation.pdf PDF] presentation explaining how to submit and review an assignment with Expertiza.&lt;br /&gt;
*For students, a [http://research.csc.ncsu.edu/efg/expertiza/presentations/videos/student.swf video] showing how to use the system to submit and review an assignment.&lt;br /&gt;
*For students, a [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_wiki_documentation.ppt Powerpoint] or [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_wiki_documentation.pdf PDF] presentation explaining how to submit and review wiki pages with Expertiza.&lt;br /&gt;
*For students, a [http://courses.ncsu.edu/csc517/common/homework/topic-signup-team-formation.ppt Powerpoint] or [http://courses.ncsu.edu/csc517/common/homework/topic-signup-team-formation.pdf PDF] presentation explaining how to form teams and sign up for topics&amp;lt;ref&amp;gt;[http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza. Wolfwikis]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Szhang29</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=97000</id>
		<title>CSC/ECE 517 Spring 2015 S1524 FSZZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=97000"/>
		<updated>2015-04-28T16:11:25Z</updated>

		<summary type="html">&lt;p&gt;Szhang29: /* Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1524. Refactor staggered-deadline assignments&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Overview'''==&lt;br /&gt;
===Introduction to Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza. Github]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Staggered Deadlines===&lt;br /&gt;
Staggered deadlines involve planning alternate submission dates for papers, projects, or exams when a student has conflicting due dates for these.  The key part of staggered deadlines is the planning. Staggered deadlines are always established well in advance of the scheduled due date. It is the advanced planning of these deadlines that makes them &amp;quot;staggered deadlines&amp;quot; rather than extensions&amp;lt;ref&amp;gt;[http://pages.vassar.edu/accessingvassar/2013/01/15/difficulties-with-staggered-deadlines/ Elmichaels. ''Difficulties with Staggered Deadlines''. Jan 15, 2013]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=='''Documentation'''==&lt;br /&gt;
'''Controller'''&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/5c7c8579b6fe44e19f96183af43fab26cd26d1d1/app/controllers/sign_up_sheet_controller.rb sign_up_sheet_controller.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/rails4/app/controllers/assignments_controller.rb assignments_controller.rb]&lt;br /&gt;
&lt;br /&gt;
'''Model'''&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/142a9134a18bd7cc552c6937fe5c93a1e0f4947d/app/models/assignment_form.rb assignment_form.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/72b61129c70a88d1c1ae814a53cb83b6a15a3fa8/app/models/assignment.rb assignment.rb]&lt;br /&gt;
&lt;br /&gt;
'''View'''&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/3443fe119ee4ae02c676131b07cd42c2771f88e5/app/views/sign_up_sheet/add_signup_topics_staggered.html.erb add_signup_topics_staggered.html.erb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/651176622bff84b09c7de9f745a246279501deb8/app/views/tree_display/actions/_assignments_actions.html.erb _assignments_actions.html.erb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/f2495041c0d66ee5d35c3da23d45e043072f7a1c/app/views/sign_up_sheet/_table_header.html.erb _table_header.html.erb]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
==='''Background'''===&lt;br /&gt;
In this semester's 517 class.  Wiki 1a and Wiki 1b are structured as separate assignments, with separate signup sheets, teams, and reviews.  But really, since only one of the two was done by any student, it would've been better to have a single assignment.  Still, some topics could be done soon after the course started, whereas others were better done after we had studied related topics in class.&lt;br /&gt;
&lt;br /&gt;
==='''Staggered-deadline Assignment'''===&lt;br /&gt;
This raises the idea of a ''staggered-deadline assignment'', where different topics have different submission and review deadlines, rather than all topics having the same deadline. &lt;br /&gt;
&lt;br /&gt;
==='''Benefit'''===&lt;br /&gt;
* '''Easy to manage.''' Because in the past, instructor has to build two separate assignments for Wiki 1a and 1b, now one assignment for Wiki is enough. &lt;br /&gt;
&lt;br /&gt;
* '''Increase flexibility.''' For instance, when an OSS team facing a much more difficult problem than other teams, instructor may postpone their deadline several days. It will make Expertiza more humanize.&lt;br /&gt;
&lt;br /&gt;
* '''Take time to do calibration.''' We find that two Wiki assignments started at Jan. 28th and ended at Feb. 25th, which takes too much time. And with staggered-deadline assignment, we can distribute less time on them. And we can take redundant time to do calibrating. Because we find that many students actually do not know how to evaluate other ones' work, even there are some rubrics offered. So we recommend to let students grade sample assignments first, then calibrate their grading behaviors. Although it will take some time, we consider it is important to help students distinguish good assignments from common ones.&lt;br /&gt;
&lt;br /&gt;
=='''Product Verion Functionality'''==&lt;br /&gt;
* In production version, instructor can set ''Submission deadline'', ''Review deadline'' and ''Metareview deadline'' for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments_M.png‎  |frame|center|Set different deadline for each topic]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Also, instructor can set the dependencies of different topics. And there is a dependency graph generated automatically.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments1_M.png‎  |frame|center|Dependency graph for all topics]]&lt;br /&gt;
&lt;br /&gt;
=='''Design Pattern'''==&lt;br /&gt;
* '''MVC'''&lt;br /&gt;
**Model–view–controller (MVC) is a software architectural pattern for implementing user interfaces. It divides a given software application into three interconnected parts, so as to separate internal representations of information from the ways that information is presented to or accepted from the user.&amp;lt;ref&amp;gt;[http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller. ''Model–view–controller''. Wikipedia]&amp;lt;/ref&amp;gt;&lt;br /&gt;
**We need to modify model, view and controller in order to fix this functionality.&lt;br /&gt;
&lt;br /&gt;
* '''Publish-subscribe'''&lt;br /&gt;
**In software architecture, publish–subscribe is a messaging pattern where senders of messages, called publishers, do not program the messages to be sent directly to specific receivers, called subscribers. Instead, published messages are characterized into classes, without knowledge of what, if any, subscribers there may be. Similarly, subscribers express interest in one or more classes, and only receive messages that are of interest, without knowledge of what, if any, publishers there are.&amp;lt;ref&amp;gt;[http://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern. ''Publish–subscribe pattern''. Wikipedia]&amp;lt;/ref&amp;gt;&lt;br /&gt;
** When instructor set an assignment as staggered-dealine assignment, in theory, all the students will know.&lt;br /&gt;
&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Create staggered-deadline assignment'''&lt;br /&gt;
** '''Actor:''' Instructor&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** Instructor logs in Expertiza.&lt;br /&gt;
*** Instructor creates a new staggered-deadline assignment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Peer review only'''&lt;br /&gt;
** '''Actor:''' Student finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Hand in assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
*** Write author feedback to reviewer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Peer review and still work on assignments'''&lt;br /&gt;
** '''Actor:''' Student not finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Work on assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:UseCaseDiagram1_M.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Error Message Present'''==&lt;br /&gt;
* First, login expertiza, in the &amp;quot;Manage Content&amp;quot; page, create a new assignment. Then, as shown below, choose the &amp;quot;pencil&amp;quot; icon to edit the assignment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment1.jpg |frame|center|Assignment panel 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Check&amp;quot;Has topics?&amp;quot; and &amp;quot;Staggered deadline assignment?&amp;quot; two checkbox, and create new topics in &amp;quot;Topics&amp;quot; panel, click &amp;quot;save&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment2.jpg |frame|center|Create Topics]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Back to the &amp;quot;Manage Content&amp;quot; page, choose the &amp;quot;Edit signup sheet&amp;quot; icon.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment3.jpg |frame|center|Assignment panel 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Error: can't write unknown attribute 't_id'.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment4.jpg |frame|center|Error]]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Analysis'''==&lt;br /&gt;
* After discussing with professor, the &amp;quot;sign up sheet&amp;quot; icon in assignment pop up panel should be moved. Because that icon has the same functionality as &amp;quot;topic&amp;quot; panel in assignment edit window. These work has already done by [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2015/oss_E1509_lds OSS1509]. So we have to move all the staggered-deadline realted code to the [https://github.com/expertiza/expertiza/blob/rails4/app/controllers/assignments_controller.rb assignments_controller.rb] and [https://github.com/expertiza/expertiza/blob/rails4/app/views/assignments/edit.html.erb assignments/edit.html.erb].&lt;br /&gt;
&lt;br /&gt;
* In &amp;quot;sign_up_sheet_controller&amp;quot;, there are several errors and confusions in function &amp;quot;add_sign_up_topic&amp;quot;. The function is used to display a page that lists all the available topics for a staggered-deadline assignment.&amp;lt;br&amp;gt; &lt;br /&gt;
See the function code below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_signup_topic&lt;br /&gt;
  load_add_signup_topics(params[:id])&lt;br /&gt;
&lt;br /&gt;
  @review_rounds = Assignment.find(params[:id]).get_review_rounds&lt;br /&gt;
  @topics = SignUpTopic.where(assignment_id: params[:id])&lt;br /&gt;
&lt;br /&gt;
  #Use this until you figure out how to initialize this array&lt;br /&gt;
  @duedates = SignUpTopic.find_by_sql(&amp;quot;SELECT s.id as topic_id FROM sign_up_topics s WHERE s.assignment_id = &amp;quot; + params[:id].to_s)&lt;br /&gt;
&lt;br /&gt;
  unless @topics.nil?&lt;br /&gt;
    i=0&lt;br /&gt;
    @topics.each { |topic|&lt;br /&gt;
&lt;br /&gt;
      @duedates[i]['t_id'] = topic.id&lt;br /&gt;
      @duedates[i]['topic_identifier'] = topic.topic_identifier&lt;br /&gt;
      @duedates[i]['topic_name'] = topic.topic_name&lt;br /&gt;
&lt;br /&gt;
      for j in 1..@review_rounds&lt;br /&gt;
        duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('submission').id).first&lt;br /&gt;
        duedate_rev = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('review').id).first&lt;br /&gt;
        if !duedate_subm.nil? &amp;amp;&amp;amp; !duedate_rev.nil?&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        else&lt;br /&gt;
          #the topic is new. so copy deadlines from assignment&lt;br /&gt;
          set_of_due_dates = DueDate.where(assignment_id: params[:id])&lt;br /&gt;
          set_of_due_dates.each { |due_date|&lt;br /&gt;
            create_topic_deadline(due_date, 0, topic.id)&lt;br /&gt;
          }&lt;br /&gt;
&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
      end&lt;br /&gt;
      duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('metareview').id).first&lt;br /&gt;
      @duedates[i]['submission_'+ (@review_rounds+1).to_s] = !(duedate_subm.nil?)?(DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)):nil&lt;br /&gt;
      i = i + 1&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The main confusions are:&lt;br /&gt;
* In line 8, the variable &amp;quot;duedates&amp;quot; are declared as type &amp;quot;SignUpTopic&amp;quot;. The naming is quite confusing.&lt;br /&gt;
* In line 14, the SignUpTopic class doesn't have a column &amp;quot;t_id&amp;quot;, it raises an error. We think it should be &amp;quot;topic_id&amp;quot;.&lt;br /&gt;
* From the code we can guess the variable &amp;quot;duedates&amp;quot; is used to store the deadline for each topic. The class &amp;quot;DueData&amp;quot; does exist, but it does not have column &amp;quot;topic_identifier&amp;quot; or &amp;quot;topic_name&amp;quot;. It only stores the deadline for a single assignment.&lt;br /&gt;
&lt;br /&gt;
=='''Puzzle'''==&lt;br /&gt;
* If there is more than one round, which means students can submit their assignments more than once, so the staggered-deadline should refer to which deadline?&lt;br /&gt;
'''[Professor]''' In a staggered-deadline assignment, there is one submission deadline and one review deadline per round.  These are always set on a per-topic basis.&lt;br /&gt;
If the view currently works (and I think it might), as soon as you make an assignment a staggered-deadline assignment, the Signup Sheet (Topics) page will have a link at the bottom to show deadlines for each topic.  Click it, and you will see a separate text box for each deadline for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* If staggered-deadline of one assignment is even later than the second-round review, is it means that that assignment do not need peer review and go directly into meta-review stage?&lt;br /&gt;
'''[Professor]''' No, there are also separate meta-review deadlines for a staggered-deadline assignment.&lt;br /&gt;
I think in the current implementation, only submission deadlines, review deadlines, and meta-review deadlines vary by topic.  In a more complete implementation, there would be a way for ANY deadline to vary by topic.  This would include signup deadlines, drop-topic deadlines, team-formation deadlines, and any other kind of deadline that is defined later.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* When to set staggered-deadline assignments? Create assignment or Before submission?&lt;br /&gt;
'''[Professor]''' Basically, the staggered-deadline is set at the same time when an assignment is created. But if one team cannot hand in their work with sufficient reasons, instructor may extend the deadline of their topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* What is the meaning of &amp;quot;dependencies&amp;quot; between topics?&lt;br /&gt;
'''[Professor]''' The ''dependencies'' of topics means one topic cannot start until another topic finishes. For instance, ''Ruby'' topic must be finished before ''Rails'' topic.&lt;br /&gt;
&lt;br /&gt;
=='''Workflow'''==&lt;br /&gt;
&lt;br /&gt;
==='''Set topics staggered deadline'''===&lt;br /&gt;
At very beginning, we find that the type of &amp;lt;code&amp;gt;due_date&amp;lt;/code&amp;gt; variable &amp;lt;code&amp;gt;SignUpTopics&amp;lt;/code&amp;gt;. However, we found that many attributes used not belonging to &amp;lt;code&amp;gt;SignUpTopics&amp;lt;/code&amp;gt; class. So we deceide to use has tables instead. In order to keep update the staggered deadline, we put this variable in session. We also comprehended the relationship of corresponding tables. The original due dates are stored in &amp;lt;code&amp;gt;due_date&amp;lt;/code&amp;gt; table. And staggered-deadlines are stored in &amp;lt;code&amp;gt;TopicDeadline&amp;lt;/code&amp;gt; table. This table also stores different deadline types.&lt;br /&gt;
&lt;br /&gt;
Below is &amp;lt;code&amp;gt;save_topic_deadlines&amp;lt;/code&amp;gt; method after refactoring.&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
  #session[:duedates] stores all original duedates info&lt;br /&gt;
  #due_dates stores staggered duedates&lt;br /&gt;
  due_dates = params[:due_date]&lt;br /&gt;
  topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
  review_rounds = Assignment.find(params[:assignment_id]).get_review_rounds&lt;br /&gt;
  # j represents the review rounds&lt;br /&gt;
  j = 0&lt;br /&gt;
  topics.each { |topic|&lt;br /&gt;
    for i in 1..review_rounds&lt;br /&gt;
      topic_deadline_type_subm = DeadlineType.find_by_name('submission').id&lt;br /&gt;
      topic_deadline_subm = TopicDeadline.where(topic_id: session[:duedates][j]['id'].to_i, deadline_type_id: topic_deadline_type_subm, round: i).first&lt;br /&gt;
      topic_deadline_subm.update_attributes({'due_at' =&amp;gt; due_dates[session[:duedates][j]['id'].to_s + '_submission_' + i.to_s + '_due_date']})&lt;br /&gt;
      flash[:error] = &amp;quot;Please enter a valid &amp;quot; + (i &amp;gt; 1 ? &amp;quot;Resubmission deadline &amp;quot; + (i-1).to_s : &amp;quot;Submission deadline&amp;quot;) if topic_deadline_subm.errors.length &amp;gt; 0&lt;br /&gt;
      topic_deadline_type_rev = DeadlineType.find_by_name('review').id&lt;br /&gt;
      topic_deadline_rev = TopicDeadline.where(topic_id: session[:duedates][j]['id'].to_i, deadline_type_id: topic_deadline_type_rev, round:i).first&lt;br /&gt;
      topic_deadline_rev.update_attributes({'due_at' =&amp;gt; due_dates[session[:duedates][j]['id'].to_s + '_review_' + i.to_s + '_due_date']})&lt;br /&gt;
      flash[:error] = &amp;quot;Please enter a valid Review deadline &amp;quot; + (i &amp;gt; 1 ? (i-1).to_s : &amp;quot;&amp;quot;) if topic_deadline_rev.errors.length &amp;gt; 0&lt;br /&gt;
    end&lt;br /&gt;
    topic_deadline_subm = TopicDeadline.where(topic_id: session[:duedates][j]['id'], deadline_type_id:  DeadlineType.find_by_name('metareview').id).first&lt;br /&gt;
    topic_deadline_subm.update_attributes({'due_at' =&amp;gt; due_dates[session[:duedates][j]['id'].to_s + '_submission_' + (review_rounds+1).to_s + '_due_date']})&lt;br /&gt;
    flash[:error] = &amp;quot;Please enter a valid Meta review deadline&amp;quot; if topic_deadline_subm.errors.length &amp;gt; 0&lt;br /&gt;
    j = j + 1&lt;br /&gt;
  }&lt;br /&gt;
  redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==='''Save topics dependency and show dependency graph'''===&lt;br /&gt;
In edit signup sheet for assignment, we want to save topic dependency and show the depandency graph, as show below:&lt;br /&gt;
[[File:save_denpendency.jpg |frame|center|Assignment panel 1]]&lt;br /&gt;
In order to show the dependency graph, we must first save topics dependency and save the topic dependency graph under &amp;lt;code&amp;gt; public/assets/staggered_deadline_assignment_graph &amp;lt;/code&amp;gt; path. We first add new method in 'due_date' model:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def self.assign_start_due_date(assignment_id, set_of_topics)&lt;br /&gt;
&lt;br /&gt;
    #Remember, in create_common_start_time_topics function we reversed the graph so reverse it back&lt;br /&gt;
    set_of_topics = set_of_topics.reverse&lt;br /&gt;
&lt;br /&gt;
    set_of_topics_due_dates = Array.new&lt;br /&gt;
    i=0&lt;br /&gt;
    days_between_submissions = Assignment.find(assignment_id)['days_between_submissions'].to_i&lt;br /&gt;
    set_of_topics.each { |set_of_topic|&lt;br /&gt;
      set_of_due_dates = nil&lt;br /&gt;
      if i==0&lt;br /&gt;
        #take the first set from the table which user stores&lt;br /&gt;
        set_of_due_dates = DueDate.where(assignment_id)&lt;br /&gt;
        offset = 0&lt;br /&gt;
      else&lt;br /&gt;
        set_of_due_dates = TopicDeadline.where(set_of_topics[i-1][0])&lt;br /&gt;
        set_of_due_dates.sort_by { |a, b| a.due_at &amp;lt;=&amp;gt; b.due_at }&lt;br /&gt;
        offset = days_between_submissions&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      set_of_topic.each { |topic_id|&lt;br /&gt;
        #if the due dates have already been created and the save dependency is being clicked,&lt;br /&gt;
        #then delete existing n create again&lt;br /&gt;
        prev_saved_due_dates = TopicDeadline.where(topic_id)&lt;br /&gt;
&lt;br /&gt;
        #Only if there is a dependency for the topic&lt;br /&gt;
        if !prev_saved_due_dates.nil?&lt;br /&gt;
          num_due_dates = prev_saved_due_dates.length&lt;br /&gt;
          #for each due date in the current topic he want to compare it to the previous due date&lt;br /&gt;
          for x in 0..num_due_dates - 1&lt;br /&gt;
            #we don't want the old date to move earlier in time so we save it as the new due date and destroy the old one  &lt;br /&gt;
            if DateTime.parse(set_of_due_dates[x].due_at.to_s) + offset.to_i &amp;lt; DateTime.parse(prev_saved_due_dates[x].due_at.to_s)&lt;br /&gt;
              set_of_due_dates[x] = prev_saved_due_dates[x]&lt;br /&gt;
              offset = 0&lt;br /&gt;
            end&lt;br /&gt;
            prev_saved_due_dates[x].destroy&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        set_of_due_dates.each { |due_date|&lt;br /&gt;
          create_topic_deadline(due_date, offset, topic_id)&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      i = i+1&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, change the &amp;lt;code&amp;gt;save_topic_dependencies&amp;lt;/code&amp;gt; method in &amp;lt;code&amp;gt; sign_up_sheet_controller.rb &amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - redirect_to_sign_up(params[:assignment_id])&lt;br /&gt;
  + redirect_to :action =&amp;gt; 'add_signup_topics_staggered', :id =&amp;gt; params[:assignment_id] &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since we use &amp;lt;code&amp;gt;RGL:Graph#write_to_graphic_file&amp;lt;/code&amp;gt; method to turn the dependency graph into &amp;lt;code&amp;gt;jpg&amp;lt;/code&amp;gt; file, we need to install graphviz in our gems. Otherwise, the RGL will uses &amp;lt;code&amp;gt;dot&amp;lt;/code&amp;gt; files as an intermediary format to produce image formats. If we download the &amp;lt;code&amp;gt;GraphViz&amp;lt;/code&amp;gt; packege, RGL will invoke it to produce a &amp;lt;code&amp;gt;jpg&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'graphviz' &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Then, after we click the &amp;lt;code&amp;gt;Save dependency&amp;lt;/code&amp;gt; button, and click &amp;lt;code&amp;gt;show dependency graph&amp;lt;/code&amp;gt; button, the dependency graph is shown below:&lt;br /&gt;
[[File:show_denpendency.jpg |frame|center|Assignment panel 2]]&lt;br /&gt;
&lt;br /&gt;
==='''Test'''===&lt;br /&gt;
Since we have done several modifications to the Expertiza program, some new tests are needed to test the features.&lt;br /&gt;
* We use the stub to simulate an authorized login (as instructor).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ApplicationController.any_instance.stub(:current_role_name).and_return('Instructor')&lt;br /&gt;
ApplicationController.any_instance.stub(:undo_link).and_return(TRUE)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Each time the program executes the &amp;lt;code&amp;gt;current_role_name&amp;lt;/code&amp;gt; function, it gets &amp;quot;instructor&amp;quot;.&lt;br /&gt;
* Before testing the staggered assignment, we write some tests to make sure the &amp;lt;code&amp;gt;SignUpTopic&amp;lt;/code&amp;gt; class work properly.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should be able to edit topic&amp;quot; do&lt;br /&gt;
  get :edit, id: @topic.id&lt;br /&gt;
  expect(response).to be_success&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
it &amp;quot;should be able to delete topic&amp;quot; do&lt;br /&gt;
  delete :destroy, id: @topic.id, assignment_id: @assignment.id&lt;br /&gt;
  expect(response).should redirect_to edit_assignment_path(@assignment.id) + &amp;quot;#tabs-5&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Then test staggered assignment.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should be able to create topic for assignment&amp;quot; do&lt;br /&gt;
  get :create, id: @assignment.id, topic: {topic_name: &amp;quot;New Topic&amp;quot;, max_choosers: 2, topic_identifier: &amp;quot;Ch1&amp;quot;, category: &amp;quot;Programming&amp;quot;}&lt;br /&gt;
  expect(response).should redirect_to(edit_assignment_path(@assignment.id) + &amp;quot;#tabs-5&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Test the dependency graph.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should be able to generate topic dependency&amp;quot; do&lt;br /&gt;
    post :save_topic_dependencies, assignment_id: @assignment.id&lt;br /&gt;
    expect(File).to exist(&amp;quot;public/assets/staggered_deadline_assignment_graph/graph_#{@assignment.id}.jpg&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
it &amp;quot;should be able to detect cycles&amp;quot; do&lt;br /&gt;
  post :save_topic_dependencies, assignment_id: @assignment.id,&lt;br /&gt;
       ('topic_dependencies_' + @topic1.id.to_s)=&amp;gt;{&amp;quot;dependent_on&amp;quot;=&amp;gt;[@topic2.id.to_s]},&lt;br /&gt;
       ('topic_dependencies_' + @topic2.id.to_s)=&amp;gt;{&amp;quot;dependent_on&amp;quot;=&amp;gt;[@topic1.id.to_s]}&lt;br /&gt;
  expect(flash[:error]).to eq(&amp;quot;There may be one or more cycles in the dependencies. Please correct them&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Deploy on VCL'''===&lt;br /&gt;
&lt;br /&gt;
* Visit http://vcl.ncsu.edu/ &amp;gt; Make a Reservation&lt;br /&gt;
* Select Ruby on Rails / Expertiza from the &amp;quot;Please select the environment ...&amp;quot; dropdown, select a duration, and then click Create Reservation&lt;br /&gt;
* Once the reservation is available, click Connect&lt;br /&gt;
* Follow the instructions on the connect screen (connect via SSH and then VNC). Connecting to SSH starts up VNC, the graphical environment to which you will connect.&lt;br /&gt;
* When connecting for the first time, it will prompt you for a password to access your (VNC) desktop. You can use any password, and it will be saved for later sessions.&lt;br /&gt;
* Follow the instructions given to connect to VNC. It is recommended to use [https://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=1&amp;amp;cad=rja&amp;amp;uact=8&amp;amp;ved=0CB0QFjAA&amp;amp;url=https%3A%2F%2Fchrome.google.com%2Fwebstore%2Fdetail%2Fvnc%25C2%25AE-viewer-for-google-ch%2Fiabmpiboiopbgfabjmgeedhcmjenhbla&amp;amp;ei=LEY7Veq8C8GNNrvhgegI&amp;amp;usg=AFQjCNGxB1W4GwZrwQWHyBfik1cbjvXMkw VNC Viewer for Google Chrome].&lt;br /&gt;
* Once connected to VNC, you should see Rubymine running.&lt;br /&gt;
* Open a terminal (Applications &amp;gt; Accessories &amp;gt; Terminal), try hitting &amp;lt;ctrl&amp;gt;-C to kill pending task if your terminal does not work properly.&lt;br /&gt;
* Ensure you have at least 20M disk quota available: fs lq . You can allocate more space at https://sysnews.ncsu.edu/tools-bin/usmdb-quota&lt;br /&gt;
* Clone the git repository: git clone (expertiza repository URL)&lt;br /&gt;
* Change to the directory (cd expertiza). You may create a &amp;quot;database.yml&amp;quot; file based on &amp;quot;database.yml.example&amp;quot;.&lt;br /&gt;
* Use rvm use (ruby version) to switch to proper ruby version. Then run bundle install (you may need to downgrade the bundler to avoid bundle install failure) and rake db:migrate to set up development environment.&lt;br /&gt;
* Use &amp;quot;rails s -b 0.0.0.0&amp;quot; to start server which allows the access outside VCL by using url: VCL_ip:3000.&lt;br /&gt;
&lt;br /&gt;
=='''Related materials'''==&lt;br /&gt;
*An [http://research.csc.ncsu.edu/efg/expertiza/reports/Instructor_documentation.doc instructor manual], explaining how to create an deploy an assignment in Expertiza.&lt;br /&gt;
*An [http://research.csc.ncsu.edu/efg/expertiza/presentations/videos/instructor.swf instructor video], slightly dated, showing how to create and deploy an assignment&lt;br /&gt;
* A guide for [[Creating_Custom_Rubric]]&lt;br /&gt;
*For students, a [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_documentation.ppt Powerpoint] or [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_documentation.pdf PDF] presentation explaining how to submit and review an assignment with Expertiza.&lt;br /&gt;
*For students, a [http://research.csc.ncsu.edu/efg/expertiza/presentations/videos/student.swf video] showing how to use the system to submit and review an assignment.&lt;br /&gt;
*For students, a [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_wiki_documentation.ppt Powerpoint] or [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_wiki_documentation.pdf PDF] presentation explaining how to submit and review wiki pages with Expertiza.&lt;br /&gt;
*For students, a [http://courses.ncsu.edu/csc517/common/homework/topic-signup-team-formation.ppt Powerpoint] or [http://courses.ncsu.edu/csc517/common/homework/topic-signup-team-formation.pdf PDF] presentation explaining how to form teams and sign up for topics&amp;lt;ref&amp;gt;[http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza. Wolfwikis]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Szhang29</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96999</id>
		<title>CSC/ECE 517 Spring 2015 S1524 FSZZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96999"/>
		<updated>2015-04-28T05:34:55Z</updated>

		<summary type="html">&lt;p&gt;Szhang29: /* Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1524. Refactor staggered-deadline assignments&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Overview'''==&lt;br /&gt;
===Introduction to Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza. Github]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Staggered Deadlines===&lt;br /&gt;
Staggered deadlines involve planning alternate submission dates for papers, projects, or exams when a student has conflicting due dates for these.  The key part of staggered deadlines is the planning. Staggered deadlines are always established well in advance of the scheduled due date. It is the advanced planning of these deadlines that makes them &amp;quot;staggered deadlines&amp;quot; rather than extensions&amp;lt;ref&amp;gt;[http://pages.vassar.edu/accessingvassar/2013/01/15/difficulties-with-staggered-deadlines/ Elmichaels. ''Difficulties with Staggered Deadlines''. Jan 15, 2013]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=='''Documentation'''==&lt;br /&gt;
'''Controller'''&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/5c7c8579b6fe44e19f96183af43fab26cd26d1d1/app/controllers/sign_up_sheet_controller.rb sign_up_sheet_controller.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/rails4/app/controllers/assignments_controller.rb assignments_controller.rb]&lt;br /&gt;
&lt;br /&gt;
'''Model'''&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/142a9134a18bd7cc552c6937fe5c93a1e0f4947d/app/models/assignment_form.rb assignment_form.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/72b61129c70a88d1c1ae814a53cb83b6a15a3fa8/app/models/assignment.rb assignment.rb]&lt;br /&gt;
&lt;br /&gt;
'''View'''&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/3443fe119ee4ae02c676131b07cd42c2771f88e5/app/views/sign_up_sheet/add_signup_topics_staggered.html.erb add_signup_topics_staggered.html.erb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/651176622bff84b09c7de9f745a246279501deb8/app/views/tree_display/actions/_assignments_actions.html.erb _assignments_actions.html.erb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/f2495041c0d66ee5d35c3da23d45e043072f7a1c/app/views/sign_up_sheet/_table_header.html.erb _table_header.html.erb]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
==='''Background'''===&lt;br /&gt;
In this semester's 517 class.  Wiki 1a and Wiki 1b are structured as separate assignments, with separate signup sheets, teams, and reviews.  But really, since only one of the two was done by any student, it would've been better to have a single assignment.  Still, some topics could be done soon after the course started, whereas others were better done after we had studied related topics in class.&lt;br /&gt;
&lt;br /&gt;
==='''Staggered-deadline Assignment'''===&lt;br /&gt;
This raises the idea of a ''staggered-deadline assignment'', where different topics have different submission and review deadlines, rather than all topics having the same deadline. &lt;br /&gt;
&lt;br /&gt;
==='''Benefit'''===&lt;br /&gt;
* '''Easy to manage.''' Because in the past, instructor has to build two separate assignments for Wiki 1a and 1b, now one assignment for Wiki is enough. &lt;br /&gt;
&lt;br /&gt;
* '''Increase flexibility.''' For instance, when an OSS team facing a much more difficult problem than other teams, instructor may postpone their deadline several days. It will make Expertiza more humanize.&lt;br /&gt;
&lt;br /&gt;
* '''Take time to do calibration.''' We find that two Wiki assignments started at Jan. 28th and ended at Feb. 25th, which takes too much time. And with staggered-deadline assignment, we can distribute less time on them. And we can take redundant time to do calibrating. Because we find that many students actually do not know how to evaluate other ones' work, even there are some rubrics offered. So we recommend to let students grade sample assignments first, then calibrate their grading behaviors. Although it will take some time, we consider it is important to help students distinguish good assignments from common ones.&lt;br /&gt;
&lt;br /&gt;
=='''Product Verion Functionality'''==&lt;br /&gt;
* In production version, instructor can set ''Submission deadline'', ''Review deadline'' and ''Metareview deadline'' for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments_M.png‎  |frame|center|Set different deadline for each topic]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Also, instructor can set the dependencies of different topics. And there is a dependency graph generated automatically.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments1_M.png‎  |frame|center|Dependency graph for all topics]]&lt;br /&gt;
&lt;br /&gt;
=='''Design Pattern'''==&lt;br /&gt;
* '''MVC'''&lt;br /&gt;
**Model–view–controller (MVC) is a software architectural pattern for implementing user interfaces. It divides a given software application into three interconnected parts, so as to separate internal representations of information from the ways that information is presented to or accepted from the user.&amp;lt;ref&amp;gt;[http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller. ''Model–view–controller''. Wikipedia]&amp;lt;/ref&amp;gt;&lt;br /&gt;
**We need to modify model, view and controller in order to fix this functionality.&lt;br /&gt;
&lt;br /&gt;
* '''Publish-subscribe'''&lt;br /&gt;
**In software architecture, publish–subscribe is a messaging pattern where senders of messages, called publishers, do not program the messages to be sent directly to specific receivers, called subscribers. Instead, published messages are characterized into classes, without knowledge of what, if any, subscribers there may be. Similarly, subscribers express interest in one or more classes, and only receive messages that are of interest, without knowledge of what, if any, publishers there are.&amp;lt;ref&amp;gt;[http://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern. ''Publish–subscribe pattern''. Wikipedia]&amp;lt;/ref&amp;gt;&lt;br /&gt;
** When instructor set an assignment as staggered-dealine assignment, in theory, all the students will know.&lt;br /&gt;
&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Create staggered-deadline assignment'''&lt;br /&gt;
** '''Actor:''' Instructor&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** Instructor logs in Expertiza.&lt;br /&gt;
*** Instructor creates a new staggered-deadline assignment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Peer review only'''&lt;br /&gt;
** '''Actor:''' Student finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Hand in assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
*** Write author feedback to reviewer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Peer review and still work on assignments'''&lt;br /&gt;
** '''Actor:''' Student not finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Work on assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:UseCaseDiagram1_M.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Error Message Present'''==&lt;br /&gt;
* First, login expertiza, in the &amp;quot;Manage Content&amp;quot; page, create a new assignment. Then, as shown below, choose the &amp;quot;pencil&amp;quot; icon to edit the assignment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment1.jpg |frame|center|Assignment panel 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Check&amp;quot;Has topics?&amp;quot; and &amp;quot;Staggered deadline assignment?&amp;quot; two checkbox, and create new topics in &amp;quot;Topics&amp;quot; panel, click &amp;quot;save&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment2.jpg |frame|center|Create Topics]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Back to the &amp;quot;Manage Content&amp;quot; page, choose the &amp;quot;Edit signup sheet&amp;quot; icon.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment3.jpg |frame|center|Assignment panel 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Error: can't write unknown attribute 't_id'.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment4.jpg |frame|center|Error]]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Analysis'''==&lt;br /&gt;
* After discussing with professor, the &amp;quot;sign up sheet&amp;quot; icon in assignment pop up panel should be moved. Because that icon has the same functionality as &amp;quot;topic&amp;quot; panel in assignment edit window. These work has already done by [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2015/oss_E1509_lds OSS1509]. So we have to move all the staggered-deadline realted code to the [https://github.com/expertiza/expertiza/blob/rails4/app/controllers/assignments_controller.rb assignments_controller.rb] and [https://github.com/expertiza/expertiza/blob/rails4/app/views/assignments/edit.html.erb assignments/edit.html.erb].&lt;br /&gt;
&lt;br /&gt;
* In &amp;quot;sign_up_sheet_controller&amp;quot;, there are several errors and confusions in function &amp;quot;add_sign_up_topic&amp;quot;. The function is used to display a page that lists all the available topics for a staggered-deadline assignment.&amp;lt;br&amp;gt; &lt;br /&gt;
See the function code below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_signup_topic&lt;br /&gt;
  load_add_signup_topics(params[:id])&lt;br /&gt;
&lt;br /&gt;
  @review_rounds = Assignment.find(params[:id]).get_review_rounds&lt;br /&gt;
  @topics = SignUpTopic.where(assignment_id: params[:id])&lt;br /&gt;
&lt;br /&gt;
  #Use this until you figure out how to initialize this array&lt;br /&gt;
  @duedates = SignUpTopic.find_by_sql(&amp;quot;SELECT s.id as topic_id FROM sign_up_topics s WHERE s.assignment_id = &amp;quot; + params[:id].to_s)&lt;br /&gt;
&lt;br /&gt;
  unless @topics.nil?&lt;br /&gt;
    i=0&lt;br /&gt;
    @topics.each { |topic|&lt;br /&gt;
&lt;br /&gt;
      @duedates[i]['t_id'] = topic.id&lt;br /&gt;
      @duedates[i]['topic_identifier'] = topic.topic_identifier&lt;br /&gt;
      @duedates[i]['topic_name'] = topic.topic_name&lt;br /&gt;
&lt;br /&gt;
      for j in 1..@review_rounds&lt;br /&gt;
        duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('submission').id).first&lt;br /&gt;
        duedate_rev = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('review').id).first&lt;br /&gt;
        if !duedate_subm.nil? &amp;amp;&amp;amp; !duedate_rev.nil?&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        else&lt;br /&gt;
          #the topic is new. so copy deadlines from assignment&lt;br /&gt;
          set_of_due_dates = DueDate.where(assignment_id: params[:id])&lt;br /&gt;
          set_of_due_dates.each { |due_date|&lt;br /&gt;
            create_topic_deadline(due_date, 0, topic.id)&lt;br /&gt;
          }&lt;br /&gt;
&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
      end&lt;br /&gt;
      duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('metareview').id).first&lt;br /&gt;
      @duedates[i]['submission_'+ (@review_rounds+1).to_s] = !(duedate_subm.nil?)?(DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)):nil&lt;br /&gt;
      i = i + 1&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The main confusions are:&lt;br /&gt;
* In line 8, the variable &amp;quot;duedates&amp;quot; are declared as type &amp;quot;SignUpTopic&amp;quot;. The naming is quite confusing.&lt;br /&gt;
* In line 14, the SignUpTopic class doesn't have a column &amp;quot;t_id&amp;quot;, it raises an error. We think it should be &amp;quot;topic_id&amp;quot;.&lt;br /&gt;
* From the code we can guess the variable &amp;quot;duedates&amp;quot; is used to store the deadline for each topic. The class &amp;quot;DueData&amp;quot; does exist, but it does not have column &amp;quot;topic_identifier&amp;quot; or &amp;quot;topic_name&amp;quot;. It only stores the deadline for a single assignment.&lt;br /&gt;
&lt;br /&gt;
=='''Puzzle'''==&lt;br /&gt;
* If there is more than one round, which means students can submit their assignments more than once, so the staggered-deadline should refer to which deadline?&lt;br /&gt;
'''[Professor]''' In a staggered-deadline assignment, there is one submission deadline and one review deadline per round.  These are always set on a per-topic basis.&lt;br /&gt;
If the view currently works (and I think it might), as soon as you make an assignment a staggered-deadline assignment, the Signup Sheet (Topics) page will have a link at the bottom to show deadlines for each topic.  Click it, and you will see a separate text box for each deadline for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* If staggered-deadline of one assignment is even later than the second-round review, is it means that that assignment do not need peer review and go directly into meta-review stage?&lt;br /&gt;
'''[Professor]''' No, there are also separate meta-review deadlines for a staggered-deadline assignment.&lt;br /&gt;
I think in the current implementation, only submission deadlines, review deadlines, and meta-review deadlines vary by topic.  In a more complete implementation, there would be a way for ANY deadline to vary by topic.  This would include signup deadlines, drop-topic deadlines, team-formation deadlines, and any other kind of deadline that is defined later.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* When to set staggered-deadline assignments? Create assignment or Before submission?&lt;br /&gt;
'''[Professor]''' Basically, the staggered-deadline is set at the same time when an assignment is created. But if one team cannot hand in their work with sufficient reasons, instructor may extend the deadline of their topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* What is the meaning of &amp;quot;dependencies&amp;quot; between topics?&lt;br /&gt;
'''[Professor]''' The ''dependencies'' of topics means one topic cannot start until another topic finishes. For instance, ''Ruby'' topic must be finished before ''Rails'' topic.&lt;br /&gt;
&lt;br /&gt;
=='''Workflow'''==&lt;br /&gt;
&lt;br /&gt;
==='''Set topics staggered deadline'''===&lt;br /&gt;
At very beginning, we find that the type of &amp;lt;code&amp;gt;due_date&amp;lt;/code&amp;gt; variable &amp;lt;code&amp;gt;SignUpTopics&amp;lt;/code&amp;gt;. However, we found that many attributes used not belonging to &amp;lt;code&amp;gt;SignUpTopics&amp;lt;/code&amp;gt; class. So we deceide to use has tables instead. In order to keep update the staggered deadline, we put this variable in session. We also comprehended the relationship of corresponding tables. The original due dates are stored in &amp;lt;code&amp;gt;due_date&amp;lt;/code&amp;gt; table. And staggered-deadlines are stored in &amp;lt;code&amp;gt;TopicDeadline&amp;lt;/code&amp;gt; table. This table also stores different deadline types.&lt;br /&gt;
&lt;br /&gt;
Below is &amp;lt;code&amp;gt;save_topic_deadlines&amp;lt;/code&amp;gt; method after refactoring.&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
  #session[:duedates] stores all original duedates info&lt;br /&gt;
  #due_dates stores staggered duedates&lt;br /&gt;
  due_dates = params[:due_date]&lt;br /&gt;
  topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
  review_rounds = Assignment.find(params[:assignment_id]).get_review_rounds&lt;br /&gt;
  # j represents the review rounds&lt;br /&gt;
  j = 0&lt;br /&gt;
  topics.each { |topic|&lt;br /&gt;
    for i in 1..review_rounds&lt;br /&gt;
      topic_deadline_type_subm = DeadlineType.find_by_name('submission').id&lt;br /&gt;
      topic_deadline_subm = TopicDeadline.where(topic_id: session[:duedates][j]['id'].to_i, deadline_type_id: topic_deadline_type_subm, round: i).first&lt;br /&gt;
      topic_deadline_subm.update_attributes({'due_at' =&amp;gt; due_dates[session[:duedates][j]['id'].to_s + '_submission_' + i.to_s + '_due_date']})&lt;br /&gt;
      flash[:error] = &amp;quot;Please enter a valid &amp;quot; + (i &amp;gt; 1 ? &amp;quot;Resubmission deadline &amp;quot; + (i-1).to_s : &amp;quot;Submission deadline&amp;quot;) if topic_deadline_subm.errors.length &amp;gt; 0&lt;br /&gt;
      topic_deadline_type_rev = DeadlineType.find_by_name('review').id&lt;br /&gt;
      topic_deadline_rev = TopicDeadline.where(topic_id: session[:duedates][j]['id'].to_i, deadline_type_id: topic_deadline_type_rev, round:i).first&lt;br /&gt;
      topic_deadline_rev.update_attributes({'due_at' =&amp;gt; due_dates[session[:duedates][j]['id'].to_s + '_review_' + i.to_s + '_due_date']})&lt;br /&gt;
      flash[:error] = &amp;quot;Please enter a valid Review deadline &amp;quot; + (i &amp;gt; 1 ? (i-1).to_s : &amp;quot;&amp;quot;) if topic_deadline_rev.errors.length &amp;gt; 0&lt;br /&gt;
    end&lt;br /&gt;
    topic_deadline_subm = TopicDeadline.where(topic_id: session[:duedates][j]['id'], deadline_type_id:  DeadlineType.find_by_name('metareview').id).first&lt;br /&gt;
    topic_deadline_subm.update_attributes({'due_at' =&amp;gt; due_dates[session[:duedates][j]['id'].to_s + '_submission_' + (review_rounds+1).to_s + '_due_date']})&lt;br /&gt;
    flash[:error] = &amp;quot;Please enter a valid Meta review deadline&amp;quot; if topic_deadline_subm.errors.length &amp;gt; 0&lt;br /&gt;
    j = j + 1&lt;br /&gt;
  }&lt;br /&gt;
  redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==='''Save topics dependency and show dependency graph'''===&lt;br /&gt;
In edit signup sheet for assignment, we want to save topic dependency and show the depandency graph, as show below:&lt;br /&gt;
[[File:save_denpendency.jpg |frame|center|Assignment panel 1]]&lt;br /&gt;
In order to show the dependency graph, we must first save topics dependency and save the topic dependency graph under &amp;lt;code&amp;gt; public/assets/staggered_deadline_assignment_graph &amp;lt;/code&amp;gt; path. We first add new method in 'due_date' model:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def self.assign_start_due_date(assignment_id, set_of_topics)&lt;br /&gt;
&lt;br /&gt;
    #Remember, in create_common_start_time_topics function we reversed the graph so reverse it back&lt;br /&gt;
    set_of_topics = set_of_topics.reverse&lt;br /&gt;
&lt;br /&gt;
    set_of_topics_due_dates = Array.new&lt;br /&gt;
    i=0&lt;br /&gt;
    days_between_submissions = Assignment.find(assignment_id)['days_between_submissions'].to_i&lt;br /&gt;
    set_of_topics.each { |set_of_topic|&lt;br /&gt;
      set_of_due_dates = nil&lt;br /&gt;
      if i==0&lt;br /&gt;
        #take the first set from the table which user stores&lt;br /&gt;
        set_of_due_dates = DueDate.where(assignment_id)&lt;br /&gt;
        offset = 0&lt;br /&gt;
      else&lt;br /&gt;
        set_of_due_dates = TopicDeadline.where(set_of_topics[i-1][0])&lt;br /&gt;
        set_of_due_dates.sort_by { |a, b| a.due_at &amp;lt;=&amp;gt; b.due_at }&lt;br /&gt;
        offset = days_between_submissions&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      set_of_topic.each { |topic_id|&lt;br /&gt;
        #if the due dates have already been created and the save dependency is being clicked,&lt;br /&gt;
        #then delete existing n create again&lt;br /&gt;
        prev_saved_due_dates = TopicDeadline.where(topic_id)&lt;br /&gt;
&lt;br /&gt;
        #Only if there is a dependency for the topic&lt;br /&gt;
        if !prev_saved_due_dates.nil?&lt;br /&gt;
          num_due_dates = prev_saved_due_dates.length&lt;br /&gt;
          #for each due date in the current topic he want to compare it to the previous due date&lt;br /&gt;
          for x in 0..num_due_dates - 1&lt;br /&gt;
            #we don't want the old date to move earlier in time so we save it as the new due date and destroy the old one  &lt;br /&gt;
            if DateTime.parse(set_of_due_dates[x].due_at.to_s) + offset.to_i &amp;lt; DateTime.parse(prev_saved_due_dates[x].due_at.to_s)&lt;br /&gt;
              set_of_due_dates[x] = prev_saved_due_dates[x]&lt;br /&gt;
              offset = 0&lt;br /&gt;
            end&lt;br /&gt;
            prev_saved_due_dates[x].destroy&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        set_of_due_dates.each { |due_date|&lt;br /&gt;
          create_topic_deadline(due_date, offset, topic_id)&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      i = i+1&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, change the &amp;lt;code&amp;gt;save_topic_dependencies&amp;lt;/code&amp;gt; method in &amp;lt;code&amp;gt; sign_up_sheet_controller.rb &amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - redirect_to_sign_up(params[:assignment_id])&lt;br /&gt;
  + redirect_to :action =&amp;gt; 'add_signup_topics_staggered', :id =&amp;gt; params[:assignment_id] &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since we use &amp;lt;code&amp;gt;RGL:Graph#write_to_graphic_file&amp;lt;/code&amp;gt; method to turn the dependency graph into &amp;lt;code&amp;gt;jpg&amp;lt;/code&amp;gt; file, we need to install graphviz in our gems. Otherwise, the RGL will uses &amp;lt;code&amp;gt;dot&amp;lt;/code&amp;gt; files as an intermediary format to produce image formats. If we download the &amp;lt;code&amp;gt;GraphViz&amp;lt;/code&amp;gt; packege, RGL will invoke it to produce a &amp;lt;code&amp;gt;jpg&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'graphviz' &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Then, after we click the &amp;lt;code&amp;gt;Save dependency&amp;lt;/code&amp;gt; button, and click &amp;lt;code&amp;gt;show dependency graph&amp;lt;/code&amp;gt; button, the dependency graph is shown below:&lt;br /&gt;
[[File:show_denpendency.jpg |frame|center|Assignment panel 2]]&lt;br /&gt;
&lt;br /&gt;
==='''Test'''===&lt;br /&gt;
Since we have done several modifications to the Expertiza program, some new tests are needed to test the features.&lt;br /&gt;
* We use the stub to simulate an authorized login (as instructor).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ApplicationController.any_instance.stub(:current_role_name).and_return('Instructor')&lt;br /&gt;
ApplicationController.any_instance.stub(:undo_link).and_return(TRUE)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Each time the program executes the &amp;lt;code&amp;gt;current_role_name&amp;lt;/code&amp;gt; function, it gets &amp;quot;instructor&amp;quot;.&lt;br /&gt;
* Before testing the staggered assignment, we write some tests to make sure the &amp;lt;code&amp;gt;SignUpTopic&amp;lt;/code&amp;gt; class work properly.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should be able to create topic for assignment&amp;quot; do&lt;br /&gt;
    get :create, id: @assignment.id, topic: {topic_name: &amp;quot;New Topic&amp;quot;, max_choosers: 2, topic_identifier: &amp;quot;Ch1&amp;quot;, category: &amp;quot;Programming&amp;quot;}&lt;br /&gt;
    expect(response).should redirect_to(edit_assignment_path(@assignment.id) + &amp;quot;#tabs-5&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
it &amp;quot;should be able to edit topic&amp;quot; do&lt;br /&gt;
  get :edit, id: @topic.id&lt;br /&gt;
  expect(response).to be_success&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
it &amp;quot;should be able to delete topic&amp;quot; do&lt;br /&gt;
  delete :destroy, id: @topic.id, assignment_id: @assignment.id&lt;br /&gt;
  expect(response).should redirect_to edit_assignment_path(@assignment.id) + &amp;quot;#tabs-5&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Then test the dependency graph.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should be able to generate topic dependency&amp;quot; do&lt;br /&gt;
    post :save_topic_dependencies, assignment_id: @assignment.id&lt;br /&gt;
    expect(File).to exist(&amp;quot;public/assets/staggered_deadline_assignment_graph/graph_#{@assignment.id}.jpg&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
it &amp;quot;should be able to detect cycles&amp;quot; do&lt;br /&gt;
  post :save_topic_dependencies, assignment_id: @assignment.id,&lt;br /&gt;
       ('topic_dependencies_' + @topic1.id.to_s)=&amp;gt;{&amp;quot;dependent_on&amp;quot;=&amp;gt;[@topic2.id.to_s]},&lt;br /&gt;
       ('topic_dependencies_' + @topic2.id.to_s)=&amp;gt;{&amp;quot;dependent_on&amp;quot;=&amp;gt;[@topic1.id.to_s]}&lt;br /&gt;
  expect(flash[:error]).to eq(&amp;quot;There may be one or more cycles in the dependencies. Please correct them&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Deploy on VCL'''===&lt;br /&gt;
&lt;br /&gt;
* Visit http://vcl.ncsu.edu/ &amp;gt; Make a Reservation&lt;br /&gt;
* Select Ruby on Rails / Expertiza from the &amp;quot;Please select the environment ...&amp;quot; dropdown, select a duration, and then click Create Reservation&lt;br /&gt;
* Once the reservation is available, click Connect&lt;br /&gt;
* Follow the instructions on the connect screen (connect via SSH and then VNC). Connecting to SSH starts up VNC, the graphical environment to which you will connect.&lt;br /&gt;
* When connecting for the first time, it will prompt you for a password to access your (VNC) desktop. You can use any password, and it will be saved for later sessions.&lt;br /&gt;
* Follow the instructions given to connect to VNC. It is recommended to use [https://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=1&amp;amp;cad=rja&amp;amp;uact=8&amp;amp;ved=0CB0QFjAA&amp;amp;url=https%3A%2F%2Fchrome.google.com%2Fwebstore%2Fdetail%2Fvnc%25C2%25AE-viewer-for-google-ch%2Fiabmpiboiopbgfabjmgeedhcmjenhbla&amp;amp;ei=LEY7Veq8C8GNNrvhgegI&amp;amp;usg=AFQjCNGxB1W4GwZrwQWHyBfik1cbjvXMkw VNC Viewer for Google Chrome].&lt;br /&gt;
* Once connected to VNC, you should see Rubymine running.&lt;br /&gt;
* Open a terminal (Applications &amp;gt; Accessories &amp;gt; Terminal), try hitting &amp;lt;ctrl&amp;gt;-C to kill pending task if your terminal does not work properly.&lt;br /&gt;
* Ensure you have at least 20M disk quota available: fs lq . You can allocate more space at https://sysnews.ncsu.edu/tools-bin/usmdb-quota&lt;br /&gt;
* Clone the git repository: git clone (expertiza repository URL)&lt;br /&gt;
* Change to the directory (cd expertiza). You may create a &amp;quot;database.yml&amp;quot; file based on &amp;quot;database.yml.example&amp;quot;.&lt;br /&gt;
* Use rvm use (ruby version) to switch to proper ruby version. Then run bundle install (you may need to downgrade the bundler to avoid bundle install failure) and rake db:migrate to set up development environment.&lt;br /&gt;
* Use &amp;quot;rails s -b 0.0.0.0&amp;quot; to start server which allows the access outside VCL by using url: VCL_ip:3000.&lt;br /&gt;
&lt;br /&gt;
=='''Related materials'''==&lt;br /&gt;
*An [http://research.csc.ncsu.edu/efg/expertiza/reports/Instructor_documentation.doc instructor manual], explaining how to create an deploy an assignment in Expertiza.&lt;br /&gt;
*An [http://research.csc.ncsu.edu/efg/expertiza/presentations/videos/instructor.swf instructor video], slightly dated, showing how to create and deploy an assignment&lt;br /&gt;
* A guide for [[Creating_Custom_Rubric]]&lt;br /&gt;
*For students, a [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_documentation.ppt Powerpoint] or [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_documentation.pdf PDF] presentation explaining how to submit and review an assignment with Expertiza.&lt;br /&gt;
*For students, a [http://research.csc.ncsu.edu/efg/expertiza/presentations/videos/student.swf video] showing how to use the system to submit and review an assignment.&lt;br /&gt;
*For students, a [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_wiki_documentation.ppt Powerpoint] or [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_wiki_documentation.pdf PDF] presentation explaining how to submit and review wiki pages with Expertiza.&lt;br /&gt;
*For students, a [http://courses.ncsu.edu/csc517/common/homework/topic-signup-team-formation.ppt Powerpoint] or [http://courses.ncsu.edu/csc517/common/homework/topic-signup-team-formation.pdf PDF] presentation explaining how to form teams and sign up for topics&amp;lt;ref&amp;gt;[http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza. Wolfwikis]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Szhang29</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96998</id>
		<title>CSC/ECE 517 Spring 2015 S1524 FSZZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96998"/>
		<updated>2015-04-28T05:34:17Z</updated>

		<summary type="html">&lt;p&gt;Szhang29: /* Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1524. Refactor staggered-deadline assignments&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Overview'''==&lt;br /&gt;
===Introduction to Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza. Github]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Staggered Deadlines===&lt;br /&gt;
Staggered deadlines involve planning alternate submission dates for papers, projects, or exams when a student has conflicting due dates for these.  The key part of staggered deadlines is the planning. Staggered deadlines are always established well in advance of the scheduled due date. It is the advanced planning of these deadlines that makes them &amp;quot;staggered deadlines&amp;quot; rather than extensions&amp;lt;ref&amp;gt;[http://pages.vassar.edu/accessingvassar/2013/01/15/difficulties-with-staggered-deadlines/ Elmichaels. ''Difficulties with Staggered Deadlines''. Jan 15, 2013]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=='''Documentation'''==&lt;br /&gt;
'''Controller'''&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/5c7c8579b6fe44e19f96183af43fab26cd26d1d1/app/controllers/sign_up_sheet_controller.rb sign_up_sheet_controller.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/rails4/app/controllers/assignments_controller.rb assignments_controller.rb]&lt;br /&gt;
&lt;br /&gt;
'''Model'''&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/142a9134a18bd7cc552c6937fe5c93a1e0f4947d/app/models/assignment_form.rb assignment_form.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/72b61129c70a88d1c1ae814a53cb83b6a15a3fa8/app/models/assignment.rb assignment.rb]&lt;br /&gt;
&lt;br /&gt;
'''View'''&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/3443fe119ee4ae02c676131b07cd42c2771f88e5/app/views/sign_up_sheet/add_signup_topics_staggered.html.erb add_signup_topics_staggered.html.erb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/651176622bff84b09c7de9f745a246279501deb8/app/views/tree_display/actions/_assignments_actions.html.erb _assignments_actions.html.erb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/f2495041c0d66ee5d35c3da23d45e043072f7a1c/app/views/sign_up_sheet/_table_header.html.erb _table_header.html.erb]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
==='''Background'''===&lt;br /&gt;
In this semester's 517 class.  Wiki 1a and Wiki 1b are structured as separate assignments, with separate signup sheets, teams, and reviews.  But really, since only one of the two was done by any student, it would've been better to have a single assignment.  Still, some topics could be done soon after the course started, whereas others were better done after we had studied related topics in class.&lt;br /&gt;
&lt;br /&gt;
==='''Staggered-deadline Assignment'''===&lt;br /&gt;
This raises the idea of a ''staggered-deadline assignment'', where different topics have different submission and review deadlines, rather than all topics having the same deadline. &lt;br /&gt;
&lt;br /&gt;
==='''Benefit'''===&lt;br /&gt;
* '''Easy to manage.''' Because in the past, instructor has to build two separate assignments for Wiki 1a and 1b, now one assignment for Wiki is enough. &lt;br /&gt;
&lt;br /&gt;
* '''Increase flexibility.''' For instance, when an OSS team facing a much more difficult problem than other teams, instructor may postpone their deadline several days. It will make Expertiza more humanize.&lt;br /&gt;
&lt;br /&gt;
* '''Take time to do calibration.''' We find that two Wiki assignments started at Jan. 28th and ended at Feb. 25th, which takes too much time. And with staggered-deadline assignment, we can distribute less time on them. And we can take redundant time to do calibrating. Because we find that many students actually do not know how to evaluate other ones' work, even there are some rubrics offered. So we recommend to let students grade sample assignments first, then calibrate their grading behaviors. Although it will take some time, we consider it is important to help students distinguish good assignments from common ones.&lt;br /&gt;
&lt;br /&gt;
=='''Product Verion Functionality'''==&lt;br /&gt;
* In production version, instructor can set ''Submission deadline'', ''Review deadline'' and ''Metareview deadline'' for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments_M.png‎  |frame|center|Set different deadline for each topic]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Also, instructor can set the dependencies of different topics. And there is a dependency graph generated automatically.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments1_M.png‎  |frame|center|Dependency graph for all topics]]&lt;br /&gt;
&lt;br /&gt;
=='''Design Pattern'''==&lt;br /&gt;
* '''MVC'''&lt;br /&gt;
**Model–view–controller (MVC) is a software architectural pattern for implementing user interfaces. It divides a given software application into three interconnected parts, so as to separate internal representations of information from the ways that information is presented to or accepted from the user.&amp;lt;ref&amp;gt;[http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller. ''Model–view–controller''. Wikipedia]&amp;lt;/ref&amp;gt;&lt;br /&gt;
**We need to modify model, view and controller in order to fix this functionality.&lt;br /&gt;
&lt;br /&gt;
* '''Publish-subscribe'''&lt;br /&gt;
**In software architecture, publish–subscribe is a messaging pattern where senders of messages, called publishers, do not program the messages to be sent directly to specific receivers, called subscribers. Instead, published messages are characterized into classes, without knowledge of what, if any, subscribers there may be. Similarly, subscribers express interest in one or more classes, and only receive messages that are of interest, without knowledge of what, if any, publishers there are.&amp;lt;ref&amp;gt;[http://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern. ''Publish–subscribe pattern''. Wikipedia]&amp;lt;/ref&amp;gt;&lt;br /&gt;
** When instructor set an assignment as staggered-dealine assignment, in theory, all the students will know.&lt;br /&gt;
&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Create staggered-deadline assignment'''&lt;br /&gt;
** '''Actor:''' Instructor&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** Instructor logs in Expertiza.&lt;br /&gt;
*** Instructor creates a new staggered-deadline assignment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Peer review only'''&lt;br /&gt;
** '''Actor:''' Student finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Hand in assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
*** Write author feedback to reviewer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Peer review and still work on assignments'''&lt;br /&gt;
** '''Actor:''' Student not finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Work on assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:UseCaseDiagram1_M.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Error Message Present'''==&lt;br /&gt;
* First, login expertiza, in the &amp;quot;Manage Content&amp;quot; page, create a new assignment. Then, as shown below, choose the &amp;quot;pencil&amp;quot; icon to edit the assignment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment1.jpg |frame|center|Assignment panel 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Check&amp;quot;Has topics?&amp;quot; and &amp;quot;Staggered deadline assignment?&amp;quot; two checkbox, and create new topics in &amp;quot;Topics&amp;quot; panel, click &amp;quot;save&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment2.jpg |frame|center|Create Topics]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Back to the &amp;quot;Manage Content&amp;quot; page, choose the &amp;quot;Edit signup sheet&amp;quot; icon.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment3.jpg |frame|center|Assignment panel 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Error: can't write unknown attribute 't_id'.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment4.jpg |frame|center|Error]]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Analysis'''==&lt;br /&gt;
* After discussing with professor, the &amp;quot;sign up sheet&amp;quot; icon in assignment pop up panel should be moved. Because that icon has the same functionality as &amp;quot;topic&amp;quot; panel in assignment edit window. These work has already done by [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2015/oss_E1509_lds OSS1509]. So we have to move all the staggered-deadline realted code to the [https://github.com/expertiza/expertiza/blob/rails4/app/controllers/assignments_controller.rb assignments_controller.rb] and [https://github.com/expertiza/expertiza/blob/rails4/app/views/assignments/edit.html.erb assignments/edit.html.erb].&lt;br /&gt;
&lt;br /&gt;
* In &amp;quot;sign_up_sheet_controller&amp;quot;, there are several errors and confusions in function &amp;quot;add_sign_up_topic&amp;quot;. The function is used to display a page that lists all the available topics for a staggered-deadline assignment.&amp;lt;br&amp;gt; &lt;br /&gt;
See the function code below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_signup_topic&lt;br /&gt;
  load_add_signup_topics(params[:id])&lt;br /&gt;
&lt;br /&gt;
  @review_rounds = Assignment.find(params[:id]).get_review_rounds&lt;br /&gt;
  @topics = SignUpTopic.where(assignment_id: params[:id])&lt;br /&gt;
&lt;br /&gt;
  #Use this until you figure out how to initialize this array&lt;br /&gt;
  @duedates = SignUpTopic.find_by_sql(&amp;quot;SELECT s.id as topic_id FROM sign_up_topics s WHERE s.assignment_id = &amp;quot; + params[:id].to_s)&lt;br /&gt;
&lt;br /&gt;
  unless @topics.nil?&lt;br /&gt;
    i=0&lt;br /&gt;
    @topics.each { |topic|&lt;br /&gt;
&lt;br /&gt;
      @duedates[i]['t_id'] = topic.id&lt;br /&gt;
      @duedates[i]['topic_identifier'] = topic.topic_identifier&lt;br /&gt;
      @duedates[i]['topic_name'] = topic.topic_name&lt;br /&gt;
&lt;br /&gt;
      for j in 1..@review_rounds&lt;br /&gt;
        duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('submission').id).first&lt;br /&gt;
        duedate_rev = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('review').id).first&lt;br /&gt;
        if !duedate_subm.nil? &amp;amp;&amp;amp; !duedate_rev.nil?&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        else&lt;br /&gt;
          #the topic is new. so copy deadlines from assignment&lt;br /&gt;
          set_of_due_dates = DueDate.where(assignment_id: params[:id])&lt;br /&gt;
          set_of_due_dates.each { |due_date|&lt;br /&gt;
            create_topic_deadline(due_date, 0, topic.id)&lt;br /&gt;
          }&lt;br /&gt;
&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
      end&lt;br /&gt;
      duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('metareview').id).first&lt;br /&gt;
      @duedates[i]['submission_'+ (@review_rounds+1).to_s] = !(duedate_subm.nil?)?(DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)):nil&lt;br /&gt;
      i = i + 1&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The main confusions are:&lt;br /&gt;
* In line 8, the variable &amp;quot;duedates&amp;quot; are declared as type &amp;quot;SignUpTopic&amp;quot;. The naming is quite confusing.&lt;br /&gt;
* In line 14, the SignUpTopic class doesn't have a column &amp;quot;t_id&amp;quot;, it raises an error. We think it should be &amp;quot;topic_id&amp;quot;.&lt;br /&gt;
* From the code we can guess the variable &amp;quot;duedates&amp;quot; is used to store the deadline for each topic. The class &amp;quot;DueData&amp;quot; does exist, but it does not have column &amp;quot;topic_identifier&amp;quot; or &amp;quot;topic_name&amp;quot;. It only stores the deadline for a single assignment.&lt;br /&gt;
&lt;br /&gt;
=='''Puzzle'''==&lt;br /&gt;
* If there is more than one round, which means students can submit their assignments more than once, so the staggered-deadline should refer to which deadline?&lt;br /&gt;
'''[Professor]''' In a staggered-deadline assignment, there is one submission deadline and one review deadline per round.  These are always set on a per-topic basis.&lt;br /&gt;
If the view currently works (and I think it might), as soon as you make an assignment a staggered-deadline assignment, the Signup Sheet (Topics) page will have a link at the bottom to show deadlines for each topic.  Click it, and you will see a separate text box for each deadline for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* If staggered-deadline of one assignment is even later than the second-round review, is it means that that assignment do not need peer review and go directly into meta-review stage?&lt;br /&gt;
'''[Professor]''' No, there are also separate meta-review deadlines for a staggered-deadline assignment.&lt;br /&gt;
I think in the current implementation, only submission deadlines, review deadlines, and meta-review deadlines vary by topic.  In a more complete implementation, there would be a way for ANY deadline to vary by topic.  This would include signup deadlines, drop-topic deadlines, team-formation deadlines, and any other kind of deadline that is defined later.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* When to set staggered-deadline assignments? Create assignment or Before submission?&lt;br /&gt;
'''[Professor]''' Basically, the staggered-deadline is set at the same time when an assignment is created. But if one team cannot hand in their work with sufficient reasons, instructor may extend the deadline of their topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* What is the meaning of &amp;quot;dependencies&amp;quot; between topics?&lt;br /&gt;
'''[Professor]''' The ''dependencies'' of topics means one topic cannot start until another topic finishes. For instance, ''Ruby'' topic must be finished before ''Rails'' topic.&lt;br /&gt;
&lt;br /&gt;
=='''Workflow'''==&lt;br /&gt;
&lt;br /&gt;
==='''Set topics staggered deadline'''===&lt;br /&gt;
At very beginning, we find that the type of &amp;lt;code&amp;gt;due_date&amp;lt;/code&amp;gt; variable &amp;lt;code&amp;gt;SignUpTopics&amp;lt;/code&amp;gt;. However, we found that many attributes used not belonging to &amp;lt;code&amp;gt;SignUpTopics&amp;lt;/code&amp;gt; class. So we deceide to use has tables instead. In order to keep update the staggered deadline, we put this variable in session. We also comprehended the relationship of corresponding tables. The original due dates are stored in &amp;lt;code&amp;gt;due_date&amp;lt;/code&amp;gt; table. And staggered-deadlines are stored in &amp;lt;code&amp;gt;TopicDeadline&amp;lt;/code&amp;gt; table. This table also stores different deadline types.&lt;br /&gt;
&lt;br /&gt;
Below is &amp;lt;code&amp;gt;save_topic_deadlines&amp;lt;/code&amp;gt; method after refactoring.&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
  #session[:duedates] stores all original duedates info&lt;br /&gt;
  #due_dates stores staggered duedates&lt;br /&gt;
  due_dates = params[:due_date]&lt;br /&gt;
  topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
  review_rounds = Assignment.find(params[:assignment_id]).get_review_rounds&lt;br /&gt;
  # j represents the review rounds&lt;br /&gt;
  j = 0&lt;br /&gt;
  topics.each { |topic|&lt;br /&gt;
    for i in 1..review_rounds&lt;br /&gt;
      topic_deadline_type_subm = DeadlineType.find_by_name('submission').id&lt;br /&gt;
      topic_deadline_subm = TopicDeadline.where(topic_id: session[:duedates][j]['id'].to_i, deadline_type_id: topic_deadline_type_subm, round: i).first&lt;br /&gt;
      topic_deadline_subm.update_attributes({'due_at' =&amp;gt; due_dates[session[:duedates][j]['id'].to_s + '_submission_' + i.to_s + '_due_date']})&lt;br /&gt;
      flash[:error] = &amp;quot;Please enter a valid &amp;quot; + (i &amp;gt; 1 ? &amp;quot;Resubmission deadline &amp;quot; + (i-1).to_s : &amp;quot;Submission deadline&amp;quot;) if topic_deadline_subm.errors.length &amp;gt; 0&lt;br /&gt;
      topic_deadline_type_rev = DeadlineType.find_by_name('review').id&lt;br /&gt;
      topic_deadline_rev = TopicDeadline.where(topic_id: session[:duedates][j]['id'].to_i, deadline_type_id: topic_deadline_type_rev, round:i).first&lt;br /&gt;
      topic_deadline_rev.update_attributes({'due_at' =&amp;gt; due_dates[session[:duedates][j]['id'].to_s + '_review_' + i.to_s + '_due_date']})&lt;br /&gt;
      flash[:error] = &amp;quot;Please enter a valid Review deadline &amp;quot; + (i &amp;gt; 1 ? (i-1).to_s : &amp;quot;&amp;quot;) if topic_deadline_rev.errors.length &amp;gt; 0&lt;br /&gt;
    end&lt;br /&gt;
    topic_deadline_subm = TopicDeadline.where(topic_id: session[:duedates][j]['id'], deadline_type_id:  DeadlineType.find_by_name('metareview').id).first&lt;br /&gt;
    topic_deadline_subm.update_attributes({'due_at' =&amp;gt; due_dates[session[:duedates][j]['id'].to_s + '_submission_' + (review_rounds+1).to_s + '_due_date']})&lt;br /&gt;
    flash[:error] = &amp;quot;Please enter a valid Meta review deadline&amp;quot; if topic_deadline_subm.errors.length &amp;gt; 0&lt;br /&gt;
    j = j + 1&lt;br /&gt;
  }&lt;br /&gt;
  redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==='''Save topics dependency and show dependency graph'''===&lt;br /&gt;
In edit signup sheet for assignment, we want to save topic dependency and show the depandency graph, as show below:&lt;br /&gt;
[[File:save_denpendency.jpg |frame|center|Assignment panel 1]]&lt;br /&gt;
In order to show the dependency graph, we must first save topics dependency and save the topic dependency graph under &amp;lt;code&amp;gt; public/assets/staggered_deadline_assignment_graph &amp;lt;/code&amp;gt; path. We first add new method in 'due_date' model:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def self.assign_start_due_date(assignment_id, set_of_topics)&lt;br /&gt;
&lt;br /&gt;
    #Remember, in create_common_start_time_topics function we reversed the graph so reverse it back&lt;br /&gt;
    set_of_topics = set_of_topics.reverse&lt;br /&gt;
&lt;br /&gt;
    set_of_topics_due_dates = Array.new&lt;br /&gt;
    i=0&lt;br /&gt;
    days_between_submissions = Assignment.find(assignment_id)['days_between_submissions'].to_i&lt;br /&gt;
    set_of_topics.each { |set_of_topic|&lt;br /&gt;
      set_of_due_dates = nil&lt;br /&gt;
      if i==0&lt;br /&gt;
        #take the first set from the table which user stores&lt;br /&gt;
        set_of_due_dates = DueDate.where(assignment_id)&lt;br /&gt;
        offset = 0&lt;br /&gt;
      else&lt;br /&gt;
        set_of_due_dates = TopicDeadline.where(set_of_topics[i-1][0])&lt;br /&gt;
        set_of_due_dates.sort_by { |a, b| a.due_at &amp;lt;=&amp;gt; b.due_at }&lt;br /&gt;
        offset = days_between_submissions&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      set_of_topic.each { |topic_id|&lt;br /&gt;
        #if the due dates have already been created and the save dependency is being clicked,&lt;br /&gt;
        #then delete existing n create again&lt;br /&gt;
        prev_saved_due_dates = TopicDeadline.where(topic_id)&lt;br /&gt;
&lt;br /&gt;
        #Only if there is a dependency for the topic&lt;br /&gt;
        if !prev_saved_due_dates.nil?&lt;br /&gt;
          num_due_dates = prev_saved_due_dates.length&lt;br /&gt;
          #for each due date in the current topic he want to compare it to the previous due date&lt;br /&gt;
          for x in 0..num_due_dates - 1&lt;br /&gt;
            #we don't want the old date to move earlier in time so we save it as the new due date and destroy the old one  &lt;br /&gt;
            if DateTime.parse(set_of_due_dates[x].due_at.to_s) + offset.to_i &amp;lt; DateTime.parse(prev_saved_due_dates[x].due_at.to_s)&lt;br /&gt;
              set_of_due_dates[x] = prev_saved_due_dates[x]&lt;br /&gt;
              offset = 0&lt;br /&gt;
            end&lt;br /&gt;
            prev_saved_due_dates[x].destroy&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        set_of_due_dates.each { |due_date|&lt;br /&gt;
          create_topic_deadline(due_date, offset, topic_id)&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      i = i+1&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, change the &amp;lt;code&amp;gt;save_topic_dependencies&amp;lt;/code&amp;gt; method in &amp;lt;code&amp;gt; sign_up_sheet_controller.rb &amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - redirect_to_sign_up(params[:assignment_id])&lt;br /&gt;
  + redirect_to :action =&amp;gt; 'add_signup_topics_staggered', :id =&amp;gt; params[:assignment_id] &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since we use &amp;lt;code&amp;gt;RGL:Graph#write_to_graphic_file&amp;lt;/code&amp;gt; method to turn the dependency graph into &amp;lt;code&amp;gt;jpg&amp;lt;/code&amp;gt; file, we need to install graphviz in our gems. Otherwise, the RGL will uses &amp;lt;code&amp;gt;dot&amp;lt;/code&amp;gt; files as an intermediary format to produce image formats. If we download the &amp;lt;code&amp;gt;GraphViz&amp;lt;/code&amp;gt; packege, RGL will invoke it to produce a &amp;lt;code&amp;gt;jpg&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'graphviz' &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Then, after we click the &amp;lt;code&amp;gt;Save dependency&amp;lt;/code&amp;gt; button, and click &amp;lt;code&amp;gt;show dependency graph&amp;lt;/code&amp;gt; button, the dependency graph is shown below:&lt;br /&gt;
[[File:show_denpendency.jpg |frame|center|Assignment panel 2]]&lt;br /&gt;
&lt;br /&gt;
==='''Test'''===&lt;br /&gt;
Since we have done several modifications to the Expertiza program, some new tests are needed to test the features.&lt;br /&gt;
* We use the stub to simulate an authorized login (as instructor).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ApplicationController.any_instance.stub(:current_role_name).and_return('Instructor')&lt;br /&gt;
ApplicationController.any_instance.stub(:undo_link).and_return(TRUE)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Each time the program executes the &amp;lt;code&amp;gt;current_role_name&amp;lt;/code&amp;gt; function, it gets &amp;quot;instructor&amp;quot;.&lt;br /&gt;
* Before testing the staggered assignment, we write some tests to make sure the &amp;lt;code&amp;gt;Topic&amp;lt;/code&amp;gt; work properly.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should be able to create topic for assignment&amp;quot; do&lt;br /&gt;
    get :create, id: @assignment.id, topic: {topic_name: &amp;quot;New Topic&amp;quot;, max_choosers: 2, topic_identifier: &amp;quot;Ch1&amp;quot;, category: &amp;quot;Programming&amp;quot;}&lt;br /&gt;
    expect(response).should redirect_to(edit_assignment_path(@assignment.id) + &amp;quot;#tabs-5&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
it &amp;quot;should be able to edit topic&amp;quot; do&lt;br /&gt;
  get :edit, id: @topic.id&lt;br /&gt;
  expect(response).to be_success&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
it &amp;quot;should be able to delete topic&amp;quot; do&lt;br /&gt;
  delete :destroy, id: @topic.id, assignment_id: @assignment.id&lt;br /&gt;
  expect(response).should redirect_to edit_assignment_path(@assignment.id) + &amp;quot;#tabs-5&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Then test the dependency graph&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should be able to generate topic dependency&amp;quot; do&lt;br /&gt;
    post :save_topic_dependencies, assignment_id: @assignment.id&lt;br /&gt;
    expect(File).to exist(&amp;quot;public/assets/staggered_deadline_assignment_graph/graph_#{@assignment.id}.jpg&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
it &amp;quot;should be able to detect cycles&amp;quot; do&lt;br /&gt;
  post :save_topic_dependencies, assignment_id: @assignment.id,&lt;br /&gt;
       ('topic_dependencies_' + @topic1.id.to_s)=&amp;gt;{&amp;quot;dependent_on&amp;quot;=&amp;gt;[@topic2.id.to_s]},&lt;br /&gt;
       ('topic_dependencies_' + @topic2.id.to_s)=&amp;gt;{&amp;quot;dependent_on&amp;quot;=&amp;gt;[@topic1.id.to_s]}&lt;br /&gt;
  expect(flash[:error]).to eq(&amp;quot;There may be one or more cycles in the dependencies. Please correct them&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Deploy on VCL'''===&lt;br /&gt;
&lt;br /&gt;
* Visit http://vcl.ncsu.edu/ &amp;gt; Make a Reservation&lt;br /&gt;
* Select Ruby on Rails / Expertiza from the &amp;quot;Please select the environment ...&amp;quot; dropdown, select a duration, and then click Create Reservation&lt;br /&gt;
* Once the reservation is available, click Connect&lt;br /&gt;
* Follow the instructions on the connect screen (connect via SSH and then VNC). Connecting to SSH starts up VNC, the graphical environment to which you will connect.&lt;br /&gt;
* When connecting for the first time, it will prompt you for a password to access your (VNC) desktop. You can use any password, and it will be saved for later sessions.&lt;br /&gt;
* Follow the instructions given to connect to VNC. It is recommended to use [https://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=1&amp;amp;cad=rja&amp;amp;uact=8&amp;amp;ved=0CB0QFjAA&amp;amp;url=https%3A%2F%2Fchrome.google.com%2Fwebstore%2Fdetail%2Fvnc%25C2%25AE-viewer-for-google-ch%2Fiabmpiboiopbgfabjmgeedhcmjenhbla&amp;amp;ei=LEY7Veq8C8GNNrvhgegI&amp;amp;usg=AFQjCNGxB1W4GwZrwQWHyBfik1cbjvXMkw VNC Viewer for Google Chrome].&lt;br /&gt;
* Once connected to VNC, you should see Rubymine running.&lt;br /&gt;
* Open a terminal (Applications &amp;gt; Accessories &amp;gt; Terminal), try hitting &amp;lt;ctrl&amp;gt;-C to kill pending task if your terminal does not work properly.&lt;br /&gt;
* Ensure you have at least 20M disk quota available: fs lq . You can allocate more space at https://sysnews.ncsu.edu/tools-bin/usmdb-quota&lt;br /&gt;
* Clone the git repository: git clone (expertiza repository URL)&lt;br /&gt;
* Change to the directory (cd expertiza). You may create a &amp;quot;database.yml&amp;quot; file based on &amp;quot;database.yml.example&amp;quot;.&lt;br /&gt;
* Use rvm use (ruby version) to switch to proper ruby version. Then run bundle install (you may need to downgrade the bundler to avoid bundle install failure) and rake db:migrate to set up development environment.&lt;br /&gt;
* Use &amp;quot;rails s -b 0.0.0.0&amp;quot; to start server which allows the access outside VCL by using url: VCL_ip:3000.&lt;br /&gt;
&lt;br /&gt;
=='''Related materials'''==&lt;br /&gt;
*An [http://research.csc.ncsu.edu/efg/expertiza/reports/Instructor_documentation.doc instructor manual], explaining how to create an deploy an assignment in Expertiza.&lt;br /&gt;
*An [http://research.csc.ncsu.edu/efg/expertiza/presentations/videos/instructor.swf instructor video], slightly dated, showing how to create and deploy an assignment&lt;br /&gt;
* A guide for [[Creating_Custom_Rubric]]&lt;br /&gt;
*For students, a [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_documentation.ppt Powerpoint] or [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_documentation.pdf PDF] presentation explaining how to submit and review an assignment with Expertiza.&lt;br /&gt;
*For students, a [http://research.csc.ncsu.edu/efg/expertiza/presentations/videos/student.swf video] showing how to use the system to submit and review an assignment.&lt;br /&gt;
*For students, a [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_wiki_documentation.ppt Powerpoint] or [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_wiki_documentation.pdf PDF] presentation explaining how to submit and review wiki pages with Expertiza.&lt;br /&gt;
*For students, a [http://courses.ncsu.edu/csc517/common/homework/topic-signup-team-formation.ppt Powerpoint] or [http://courses.ncsu.edu/csc517/common/homework/topic-signup-team-formation.pdf PDF] presentation explaining how to form teams and sign up for topics&amp;lt;ref&amp;gt;[http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza. Wolfwikis]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Szhang29</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96997</id>
		<title>CSC/ECE 517 Spring 2015 S1524 FSZZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96997"/>
		<updated>2015-04-27T23:11:34Z</updated>

		<summary type="html">&lt;p&gt;Szhang29: /* Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1524. Refactor staggered-deadline assignments&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Overview'''==&lt;br /&gt;
===Introduction to Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza. Github]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Staggered Deadlines===&lt;br /&gt;
Staggered deadlines involve planning alternate submission dates for papers, projects, or exams when a student has conflicting due dates for these.  The key part of staggered deadlines is the planning. Staggered deadlines are always established well in advance of the scheduled due date. It is the advanced planning of these deadlines that makes them &amp;quot;staggered deadlines&amp;quot; rather than extensions&amp;lt;ref&amp;gt;[http://pages.vassar.edu/accessingvassar/2013/01/15/difficulties-with-staggered-deadlines/ Elmichaels. ''Difficulties with Staggered Deadlines''. Jan 15, 2013]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=='''Documentation'''==&lt;br /&gt;
'''Controller'''&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/5c7c8579b6fe44e19f96183af43fab26cd26d1d1/app/controllers/sign_up_sheet_controller.rb sign_up_sheet_controller.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/rails4/app/controllers/assignments_controller.rb assignments_controller.rb]&lt;br /&gt;
&lt;br /&gt;
'''Model'''&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/142a9134a18bd7cc552c6937fe5c93a1e0f4947d/app/models/assignment_form.rb assignment_form.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/72b61129c70a88d1c1ae814a53cb83b6a15a3fa8/app/models/assignment.rb assignment.rb]&lt;br /&gt;
&lt;br /&gt;
'''View'''&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/3443fe119ee4ae02c676131b07cd42c2771f88e5/app/views/sign_up_sheet/add_signup_topics_staggered.html.erb add_signup_topics_staggered.html.erb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/651176622bff84b09c7de9f745a246279501deb8/app/views/tree_display/actions/_assignments_actions.html.erb _assignments_actions.html.erb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/f2495041c0d66ee5d35c3da23d45e043072f7a1c/app/views/sign_up_sheet/_table_header.html.erb _table_header.html.erb]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
==='''Background'''===&lt;br /&gt;
In this semester's 517 class.  Wiki 1a and Wiki 1b are structured as separate assignments, with separate signup sheets, teams, and reviews.  But really, since only one of the two was done by any student, it would've been better to have a single assignment.  Still, some topics could be done soon after the course started, whereas others were better done after we had studied related topics in class.&lt;br /&gt;
&lt;br /&gt;
==='''Staggered-deadline Assignment'''===&lt;br /&gt;
This raises the idea of a ''staggered-deadline assignment'', where different topics have different submission and review deadlines, rather than all topics having the same deadline. &lt;br /&gt;
&lt;br /&gt;
==='''Benefit'''===&lt;br /&gt;
* '''Easy to manage.''' Because in the past, instructor has to build two separate assignments for Wiki 1a and 1b, now one assignment for Wiki is enough. &lt;br /&gt;
&lt;br /&gt;
* '''Increase flexibility.''' For instance, when an OSS team facing a much more difficult problem than other teams, instructor may postpone their deadline several days. It will make Expertiza more humanize.&lt;br /&gt;
&lt;br /&gt;
* '''Take time to do calibration.''' We find that two Wiki assignments started at Jan. 28th and ended at Feb. 25th, which takes too much time. And with staggered-deadline assignment, we can distribute less time on them. And we can take redundant time to do calibrating. Because we find that many students actually do not know how to evaluate other ones' work, even there are some rubrics offered. So we recommend to let students grade sample assignments first, then calibrate their grading behaviors. Although it will take some time, we consider it is important to help students distinguish good assignments from common ones.&lt;br /&gt;
&lt;br /&gt;
=='''Product Verion Functionality'''==&lt;br /&gt;
* In production version, instructor can set ''Submission deadline'', ''Review deadline'' and ''Metareview deadline'' for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments_M.png‎  |frame|center|Set different deadline for each topic]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Also, instructor can set the dependencies of different topics. And there is a dependency graph generated automatically.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments1_M.png‎  |frame|center|Dependency graph for all topics]]&lt;br /&gt;
&lt;br /&gt;
=='''Design Pattern'''==&lt;br /&gt;
* '''MVC'''&lt;br /&gt;
**Model–view–controller (MVC) is a software architectural pattern for implementing user interfaces. It divides a given software application into three interconnected parts, so as to separate internal representations of information from the ways that information is presented to or accepted from the user.&amp;lt;ref&amp;gt;[http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller. ''Model–view–controller''. Wikipedia]&amp;lt;/ref&amp;gt;&lt;br /&gt;
**We need to modify model, view and controller in order to fix this functionality.&lt;br /&gt;
&lt;br /&gt;
* '''Publish-subscribe'''&lt;br /&gt;
**In software architecture, publish–subscribe is a messaging pattern where senders of messages, called publishers, do not program the messages to be sent directly to specific receivers, called subscribers. Instead, published messages are characterized into classes, without knowledge of what, if any, subscribers there may be. Similarly, subscribers express interest in one or more classes, and only receive messages that are of interest, without knowledge of what, if any, publishers there are.&amp;lt;ref&amp;gt;[http://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern. ''Publish–subscribe pattern''. Wikipedia]&amp;lt;/ref&amp;gt;&lt;br /&gt;
** When instructor set an assignment as staggered-dealine assignment, in theory, all the students will know.&lt;br /&gt;
&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Create staggered-deadline assignment'''&lt;br /&gt;
** '''Actor:''' Instructor&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** Instructor logs in Expertiza.&lt;br /&gt;
*** Instructor creates a new staggered-deadline assignment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Peer review only'''&lt;br /&gt;
** '''Actor:''' Student finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Hand in assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
*** Write author feedback to reviewer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Peer review and still work on assignments'''&lt;br /&gt;
** '''Actor:''' Student not finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Work on assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:UseCaseDiagram1_M.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Error Message Present'''==&lt;br /&gt;
* First, login expertiza, in the &amp;quot;Manage Content&amp;quot; page, create a new assignment. Then, as shown below, choose the &amp;quot;pencil&amp;quot; icon to edit the assignment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment1.jpg |frame|center|Assignment panel 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Check&amp;quot;Has topics?&amp;quot; and &amp;quot;Staggered deadline assignment?&amp;quot; two checkbox, and create new topics in &amp;quot;Topics&amp;quot; panel, click &amp;quot;save&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment2.jpg |frame|center|Create Topics]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Back to the &amp;quot;Manage Content&amp;quot; page, choose the &amp;quot;Edit signup sheet&amp;quot; icon.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment3.jpg |frame|center|Assignment panel 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Error: can't write unknown attribute 't_id'.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment4.jpg |frame|center|Error]]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Analysis'''==&lt;br /&gt;
* After discussing with professor, the &amp;quot;sign up sheet&amp;quot; icon in assignment pop up panel should be moved. Because that icon has the same functionality as &amp;quot;topic&amp;quot; panel in assignment edit window. These work has already done by [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2015/oss_E1509_lds OSS1509]. So we have to move all the staggered-deadline realted code to the [https://github.com/expertiza/expertiza/blob/rails4/app/controllers/assignments_controller.rb assignments_controller.rb] and [https://github.com/expertiza/expertiza/blob/rails4/app/views/assignments/edit.html.erb assignments/edit.html.erb].&lt;br /&gt;
&lt;br /&gt;
* In &amp;quot;sign_up_sheet_controller&amp;quot;, there are several errors and confusions in function &amp;quot;add_sign_up_topic&amp;quot;. The function is used to display a page that lists all the available topics for a staggered-deadline assignment.&amp;lt;br&amp;gt; &lt;br /&gt;
See the function code below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_signup_topic&lt;br /&gt;
  load_add_signup_topics(params[:id])&lt;br /&gt;
&lt;br /&gt;
  @review_rounds = Assignment.find(params[:id]).get_review_rounds&lt;br /&gt;
  @topics = SignUpTopic.where(assignment_id: params[:id])&lt;br /&gt;
&lt;br /&gt;
  #Use this until you figure out how to initialize this array&lt;br /&gt;
  @duedates = SignUpTopic.find_by_sql(&amp;quot;SELECT s.id as topic_id FROM sign_up_topics s WHERE s.assignment_id = &amp;quot; + params[:id].to_s)&lt;br /&gt;
&lt;br /&gt;
  unless @topics.nil?&lt;br /&gt;
    i=0&lt;br /&gt;
    @topics.each { |topic|&lt;br /&gt;
&lt;br /&gt;
      @duedates[i]['t_id'] = topic.id&lt;br /&gt;
      @duedates[i]['topic_identifier'] = topic.topic_identifier&lt;br /&gt;
      @duedates[i]['topic_name'] = topic.topic_name&lt;br /&gt;
&lt;br /&gt;
      for j in 1..@review_rounds&lt;br /&gt;
        duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('submission').id).first&lt;br /&gt;
        duedate_rev = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('review').id).first&lt;br /&gt;
        if !duedate_subm.nil? &amp;amp;&amp;amp; !duedate_rev.nil?&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        else&lt;br /&gt;
          #the topic is new. so copy deadlines from assignment&lt;br /&gt;
          set_of_due_dates = DueDate.where(assignment_id: params[:id])&lt;br /&gt;
          set_of_due_dates.each { |due_date|&lt;br /&gt;
            create_topic_deadline(due_date, 0, topic.id)&lt;br /&gt;
          }&lt;br /&gt;
&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
      end&lt;br /&gt;
      duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('metareview').id).first&lt;br /&gt;
      @duedates[i]['submission_'+ (@review_rounds+1).to_s] = !(duedate_subm.nil?)?(DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)):nil&lt;br /&gt;
      i = i + 1&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The main confusions are:&lt;br /&gt;
* In line 8, the variable &amp;quot;duedates&amp;quot; are declared as type &amp;quot;SignUpTopic&amp;quot;. The naming is quite confusing.&lt;br /&gt;
* In line 14, the SignUpTopic class doesn't have a column &amp;quot;t_id&amp;quot;, it raises an error. We think it should be &amp;quot;topic_id&amp;quot;.&lt;br /&gt;
* From the code we can guess the variable &amp;quot;duedates&amp;quot; is used to store the deadline for each topic. The class &amp;quot;DueData&amp;quot; does exist, but it does not have column &amp;quot;topic_identifier&amp;quot; or &amp;quot;topic_name&amp;quot;. It only stores the deadline for a single assignment.&lt;br /&gt;
&lt;br /&gt;
=='''Puzzle'''==&lt;br /&gt;
* If there is more than one round, which means students can submit their assignments more than once, so the staggered-deadline should refer to which deadline?&lt;br /&gt;
'''[Professor]''' In a staggered-deadline assignment, there is one submission deadline and one review deadline per round.  These are always set on a per-topic basis.&lt;br /&gt;
If the view currently works (and I think it might), as soon as you make an assignment a staggered-deadline assignment, the Signup Sheet (Topics) page will have a link at the bottom to show deadlines for each topic.  Click it, and you will see a separate text box for each deadline for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* If staggered-deadline of one assignment is even later than the second-round review, is it means that that assignment do not need peer review and go directly into meta-review stage?&lt;br /&gt;
'''[Professor]''' No, there are also separate meta-review deadlines for a staggered-deadline assignment.&lt;br /&gt;
I think in the current implementation, only submission deadlines, review deadlines, and meta-review deadlines vary by topic.  In a more complete implementation, there would be a way for ANY deadline to vary by topic.  This would include signup deadlines, drop-topic deadlines, team-formation deadlines, and any other kind of deadline that is defined later.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* When to set staggered-deadline assignments? Create assignment or Before submission?&lt;br /&gt;
'''[Professor]''' Basically, the staggered-deadline is set at the same time when an assignment is created. But if one team cannot hand in their work with sufficient reasons, instructor may extend the deadline of their topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* What is the meaning of &amp;quot;dependencies&amp;quot; between topics?&lt;br /&gt;
'''[Professor]''' The ''dependencies'' of topics means one topic cannot start until another topic finishes. For instance, ''Ruby'' topic must be finished before ''Rails'' topic.&lt;br /&gt;
&lt;br /&gt;
=='''Workflow'''==&lt;br /&gt;
&lt;br /&gt;
==='''Set topics staggered deadline'''===&lt;br /&gt;
At very beginning, we find that the type of &amp;lt;code&amp;gt;due_date&amp;lt;/code&amp;gt; variable &amp;lt;code&amp;gt;SignUpTopics&amp;lt;/code&amp;gt;. However, we found that many attributes used not belonging to &amp;lt;code&amp;gt;SignUpTopics&amp;lt;/code&amp;gt; class. So we deceide to use has tables instead. In order to keep update the staggered deadline, we put this variable in session. We also comprehended the relationship of corresponding tables. The original due dates are stored in &amp;lt;code&amp;gt;due_date&amp;lt;/code&amp;gt; table. And staggered-deadlines are stored in &amp;lt;code&amp;gt;TopicDeadline&amp;lt;/code&amp;gt; table. This table also stores different deadline types.&lt;br /&gt;
&lt;br /&gt;
Below is &amp;lt;code&amp;gt;save_topic_deadlines&amp;lt;/code&amp;gt; method after refactoring.&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
  #session[:duedates] stores all original duedates info&lt;br /&gt;
  #due_dates stores staggered duedates&lt;br /&gt;
  due_dates = params[:due_date]&lt;br /&gt;
  topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
  review_rounds = Assignment.find(params[:assignment_id]).get_review_rounds&lt;br /&gt;
  # j represents the review rounds&lt;br /&gt;
  j = 0&lt;br /&gt;
  topics.each { |topic|&lt;br /&gt;
    for i in 1..review_rounds&lt;br /&gt;
      topic_deadline_type_subm = DeadlineType.find_by_name('submission').id&lt;br /&gt;
      topic_deadline_subm = TopicDeadline.where(topic_id: session[:duedates][j]['id'].to_i, deadline_type_id: topic_deadline_type_subm, round: i).first&lt;br /&gt;
      topic_deadline_subm.update_attributes({'due_at' =&amp;gt; due_dates[session[:duedates][j]['id'].to_s + '_submission_' + i.to_s + '_due_date']})&lt;br /&gt;
      flash[:error] = &amp;quot;Please enter a valid &amp;quot; + (i &amp;gt; 1 ? &amp;quot;Resubmission deadline &amp;quot; + (i-1).to_s : &amp;quot;Submission deadline&amp;quot;) if topic_deadline_subm.errors.length &amp;gt; 0&lt;br /&gt;
      topic_deadline_type_rev = DeadlineType.find_by_name('review').id&lt;br /&gt;
      topic_deadline_rev = TopicDeadline.where(topic_id: session[:duedates][j]['id'].to_i, deadline_type_id: topic_deadline_type_rev, round:i).first&lt;br /&gt;
      topic_deadline_rev.update_attributes({'due_at' =&amp;gt; due_dates[session[:duedates][j]['id'].to_s + '_review_' + i.to_s + '_due_date']})&lt;br /&gt;
      flash[:error] = &amp;quot;Please enter a valid Review deadline &amp;quot; + (i &amp;gt; 1 ? (i-1).to_s : &amp;quot;&amp;quot;) if topic_deadline_rev.errors.length &amp;gt; 0&lt;br /&gt;
    end&lt;br /&gt;
    topic_deadline_subm = TopicDeadline.where(topic_id: session[:duedates][j]['id'], deadline_type_id:  DeadlineType.find_by_name('metareview').id).first&lt;br /&gt;
    topic_deadline_subm.update_attributes({'due_at' =&amp;gt; due_dates[session[:duedates][j]['id'].to_s + '_submission_' + (review_rounds+1).to_s + '_due_date']})&lt;br /&gt;
    flash[:error] = &amp;quot;Please enter a valid Meta review deadline&amp;quot; if topic_deadline_subm.errors.length &amp;gt; 0&lt;br /&gt;
    j = j + 1&lt;br /&gt;
  }&lt;br /&gt;
  redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==='''Save topics dependency and show dependency graph'''===&lt;br /&gt;
In edit signup sheet for assignment, we want to save topic dependency and show the depandency graph, as show below:&lt;br /&gt;
[[File:save_denpendency.jpg |frame|center|Assignment panel 1]]&lt;br /&gt;
In order to show the dependency graph, we must first save topics dependency and save the topic dependency graph under &amp;lt;code&amp;gt; public/assets/staggered_deadline_assignment_graph &amp;lt;/code&amp;gt; path. We first add new method in 'due_date' model:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def self.assign_start_due_date(assignment_id, set_of_topics)&lt;br /&gt;
&lt;br /&gt;
    #Remember, in create_common_start_time_topics function we reversed the graph so reverse it back&lt;br /&gt;
    set_of_topics = set_of_topics.reverse&lt;br /&gt;
&lt;br /&gt;
    set_of_topics_due_dates = Array.new&lt;br /&gt;
    i=0&lt;br /&gt;
    days_between_submissions = Assignment.find(assignment_id)['days_between_submissions'].to_i&lt;br /&gt;
    set_of_topics.each { |set_of_topic|&lt;br /&gt;
      set_of_due_dates = nil&lt;br /&gt;
      if i==0&lt;br /&gt;
        #take the first set from the table which user stores&lt;br /&gt;
        set_of_due_dates = DueDate.where(assignment_id)&lt;br /&gt;
        offset = 0&lt;br /&gt;
      else&lt;br /&gt;
        set_of_due_dates = TopicDeadline.where(set_of_topics[i-1][0])&lt;br /&gt;
        set_of_due_dates.sort_by { |a, b| a.due_at &amp;lt;=&amp;gt; b.due_at }&lt;br /&gt;
        offset = days_between_submissions&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      set_of_topic.each { |topic_id|&lt;br /&gt;
        #if the due dates have already been created and the save dependency is being clicked,&lt;br /&gt;
        #then delete existing n create again&lt;br /&gt;
        prev_saved_due_dates = TopicDeadline.where(topic_id)&lt;br /&gt;
&lt;br /&gt;
        #Only if there is a dependency for the topic&lt;br /&gt;
        if !prev_saved_due_dates.nil?&lt;br /&gt;
          num_due_dates = prev_saved_due_dates.length&lt;br /&gt;
          #for each due date in the current topic he want to compare it to the previous due date&lt;br /&gt;
          for x in 0..num_due_dates - 1&lt;br /&gt;
            #we don't want the old date to move earlier in time so we save it as the new due date and destroy the old one  &lt;br /&gt;
            if DateTime.parse(set_of_due_dates[x].due_at.to_s) + offset.to_i &amp;lt; DateTime.parse(prev_saved_due_dates[x].due_at.to_s)&lt;br /&gt;
              set_of_due_dates[x] = prev_saved_due_dates[x]&lt;br /&gt;
              offset = 0&lt;br /&gt;
            end&lt;br /&gt;
            prev_saved_due_dates[x].destroy&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        set_of_due_dates.each { |due_date|&lt;br /&gt;
          create_topic_deadline(due_date, offset, topic_id)&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      i = i+1&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, change the &amp;lt;code&amp;gt;save_topic_dependencies&amp;lt;/code&amp;gt; method in &amp;lt;code&amp;gt; sign_up_sheet_controller.rb &amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - redirect_to_sign_up(params[:assignment_id])&lt;br /&gt;
  + redirect_to :action =&amp;gt; 'add_signup_topics_staggered', :id =&amp;gt; params[:assignment_id] &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since we use &amp;lt;code&amp;gt;RGL:Graph#write_to_graphic_file&amp;lt;/code&amp;gt; method to turn the dependency graph into &amp;lt;code&amp;gt;jpg&amp;lt;/code&amp;gt; file, we need to install graphviz in our gems. Otherwise, the RGL will uses &amp;lt;code&amp;gt;dot&amp;lt;/code&amp;gt; files as an intermediary format to produce image formats. If we download the &amp;lt;code&amp;gt;GraphViz&amp;lt;/code&amp;gt; packege, RGL will invoke it to produce a &amp;lt;code&amp;gt;jpg&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'graphviz' &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Then, after we click the &amp;lt;code&amp;gt;Save dependency&amp;lt;/code&amp;gt; button, and click &amp;lt;code&amp;gt;show dependency graph&amp;lt;/code&amp;gt; button, the dependency graph is shown below:&lt;br /&gt;
[[File:show_denpendency.jpg |frame|center|Assignment panel 2]]&lt;br /&gt;
&lt;br /&gt;
==='''Test'''===&lt;br /&gt;
Since we have done several modifications to the Expertiza program, some new tests are needed to test the features.&lt;br /&gt;
* We use the stub to simulate an authorized login (as instructor).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ApplicationController.any_instance.stub(:current_role_name).and_return('Instructor')&lt;br /&gt;
ApplicationController.any_instance.stub(:undo_link).and_return(TRUE)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Each time the program executes the &amp;lt;code&amp;gt;current_role_name&amp;lt;/code&amp;gt; function, it gets &amp;quot;instructor&amp;quot;.&lt;br /&gt;
* Firstly, we test some operations to topic&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should be able to create topic for assignment&amp;quot; do&lt;br /&gt;
    get :create, id: @assignment.id, topic: {topic_name: &amp;quot;New Topic&amp;quot;, max_choosers: 2, topic_identifier: &amp;quot;Ch1&amp;quot;, category: &amp;quot;Programming&amp;quot;}&lt;br /&gt;
    expect(response).should redirect_to(edit_assignment_path(@assignment.id) + &amp;quot;#tabs-5&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
it &amp;quot;should be able to edit topic&amp;quot; do&lt;br /&gt;
  get :edit, id: @topic.id&lt;br /&gt;
  expect(response).to be_success&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
it &amp;quot;should be able to delete topic&amp;quot; do&lt;br /&gt;
  delete :destroy, id: @topic.id, assignment_id: @assignment.id&lt;br /&gt;
  expect(response).should redirect_to edit_assignment_path(@assignment.id) + &amp;quot;#tabs-5&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Deploy on VCL'''===&lt;br /&gt;
&lt;br /&gt;
* Visit http://vcl.ncsu.edu/ &amp;gt; Make a Reservation&lt;br /&gt;
* Select Ruby on Rails / Expertiza from the &amp;quot;Please select the environment ...&amp;quot; dropdown, select a duration, and then click Create Reservation&lt;br /&gt;
* Once the reservation is available, click Connect&lt;br /&gt;
* Follow the instructions on the connect screen (connect via SSH and then VNC). Connecting to SSH starts up VNC, the graphical environment to which you will connect.&lt;br /&gt;
* When connecting for the first time, it will prompt you for a password to access your (VNC) desktop. You can use any password, and it will be saved for later sessions.&lt;br /&gt;
* Follow the instructions given to connect to VNC. It is recommended to use [https://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=1&amp;amp;cad=rja&amp;amp;uact=8&amp;amp;ved=0CB0QFjAA&amp;amp;url=https%3A%2F%2Fchrome.google.com%2Fwebstore%2Fdetail%2Fvnc%25C2%25AE-viewer-for-google-ch%2Fiabmpiboiopbgfabjmgeedhcmjenhbla&amp;amp;ei=LEY7Veq8C8GNNrvhgegI&amp;amp;usg=AFQjCNGxB1W4GwZrwQWHyBfik1cbjvXMkw VNC Viewer for Google Chrome].&lt;br /&gt;
* Once connected to VNC, you should see Rubymine running.&lt;br /&gt;
* Open a terminal (Applications &amp;gt; Accessories &amp;gt; Terminal), try hitting &amp;lt;ctrl&amp;gt;-C to kill pending task if your terminal does not work properly.&lt;br /&gt;
* Ensure you have at least 20M disk quota available: fs lq . You can allocate more space at https://sysnews.ncsu.edu/tools-bin/usmdb-quota&lt;br /&gt;
* Clone the git repository: git clone (expertiza repository URL)&lt;br /&gt;
* Change to the directory (cd expertiza). You may create a &amp;quot;database.yml&amp;quot; file based on &amp;quot;database.yml.example&amp;quot;.&lt;br /&gt;
* Use rvm use (ruby version) to switch to proper ruby version. Then run bundle install (you may need to downgrade the bundler to avoid bundle install failure) and rake db:migrate to set up development environment.&lt;br /&gt;
* Use &amp;quot;rails s -b 0.0.0.0&amp;quot; to start server which allows the access outside VCL by using url: VCL_ip:3000.&lt;br /&gt;
&lt;br /&gt;
=='''Related materials'''==&lt;br /&gt;
*An [http://research.csc.ncsu.edu/efg/expertiza/reports/Instructor_documentation.doc instructor manual], explaining how to create an deploy an assignment in Expertiza.&lt;br /&gt;
*An [http://research.csc.ncsu.edu/efg/expertiza/presentations/videos/instructor.swf instructor video], slightly dated, showing how to create and deploy an assignment&lt;br /&gt;
* A guide for [[Creating_Custom_Rubric]]&lt;br /&gt;
*For students, a [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_documentation.ppt Powerpoint] or [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_documentation.pdf PDF] presentation explaining how to submit and review an assignment with Expertiza.&lt;br /&gt;
*For students, a [http://research.csc.ncsu.edu/efg/expertiza/presentations/videos/student.swf video] showing how to use the system to submit and review an assignment.&lt;br /&gt;
*For students, a [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_wiki_documentation.ppt Powerpoint] or [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_wiki_documentation.pdf PDF] presentation explaining how to submit and review wiki pages with Expertiza.&lt;br /&gt;
*For students, a [http://courses.ncsu.edu/csc517/common/homework/topic-signup-team-formation.ppt Powerpoint] or [http://courses.ncsu.edu/csc517/common/homework/topic-signup-team-formation.pdf PDF] presentation explaining how to form teams and sign up for topics&amp;lt;ref&amp;gt;[http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza. Wolfwikis]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Szhang29</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96996</id>
		<title>CSC/ECE 517 Spring 2015 S1524 FSZZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96996"/>
		<updated>2015-04-27T23:09:22Z</updated>

		<summary type="html">&lt;p&gt;Szhang29: /* Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1524. Refactor staggered-deadline assignments&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Overview'''==&lt;br /&gt;
===Introduction to Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities&amp;lt;ref&amp;gt;[https://github.com/expertiza/expertiza Expertiza. Github]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Staggered Deadlines===&lt;br /&gt;
Staggered deadlines involve planning alternate submission dates for papers, projects, or exams when a student has conflicting due dates for these.  The key part of staggered deadlines is the planning. Staggered deadlines are always established well in advance of the scheduled due date. It is the advanced planning of these deadlines that makes them &amp;quot;staggered deadlines&amp;quot; rather than extensions&amp;lt;ref&amp;gt;[http://pages.vassar.edu/accessingvassar/2013/01/15/difficulties-with-staggered-deadlines/ Elmichaels. ''Difficulties with Staggered Deadlines''. Jan 15, 2013]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=='''Documentation'''==&lt;br /&gt;
'''Controller'''&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/5c7c8579b6fe44e19f96183af43fab26cd26d1d1/app/controllers/sign_up_sheet_controller.rb sign_up_sheet_controller.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/rails4/app/controllers/assignments_controller.rb assignments_controller.rb]&lt;br /&gt;
&lt;br /&gt;
'''Model'''&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/142a9134a18bd7cc552c6937fe5c93a1e0f4947d/app/models/assignment_form.rb assignment_form.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/72b61129c70a88d1c1ae814a53cb83b6a15a3fa8/app/models/assignment.rb assignment.rb]&lt;br /&gt;
&lt;br /&gt;
'''View'''&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/3443fe119ee4ae02c676131b07cd42c2771f88e5/app/views/sign_up_sheet/add_signup_topics_staggered.html.erb add_signup_topics_staggered.html.erb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/651176622bff84b09c7de9f745a246279501deb8/app/views/tree_display/actions/_assignments_actions.html.erb _assignments_actions.html.erb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/f2495041c0d66ee5d35c3da23d45e043072f7a1c/app/views/sign_up_sheet/_table_header.html.erb _table_header.html.erb]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
==='''Background'''===&lt;br /&gt;
In this semester's 517 class.  Wiki 1a and Wiki 1b are structured as separate assignments, with separate signup sheets, teams, and reviews.  But really, since only one of the two was done by any student, it would've been better to have a single assignment.  Still, some topics could be done soon after the course started, whereas others were better done after we had studied related topics in class.&lt;br /&gt;
&lt;br /&gt;
==='''Staggered-deadline Assignment'''===&lt;br /&gt;
This raises the idea of a ''staggered-deadline assignment'', where different topics have different submission and review deadlines, rather than all topics having the same deadline. &lt;br /&gt;
&lt;br /&gt;
==='''Benefit'''===&lt;br /&gt;
* '''Easy to manage.''' Because in the past, instructor has to build two separate assignments for Wiki 1a and 1b, now one assignment for Wiki is enough. &lt;br /&gt;
&lt;br /&gt;
* '''Increase flexibility.''' For instance, when an OSS team facing a much more difficult problem than other teams, instructor may postpone their deadline several days. It will make Expertiza more humanize.&lt;br /&gt;
&lt;br /&gt;
* '''Take time to do calibration.''' We find that two Wiki assignments started at Jan. 28th and ended at Feb. 25th, which takes too much time. And with staggered-deadline assignment, we can distribute less time on them. And we can take redundant time to do calibrating. Because we find that many students actually do not know how to evaluate other ones' work, even there are some rubrics offered. So we recommend to let students grade sample assignments first, then calibrate their grading behaviors. Although it will take some time, we consider it is important to help students distinguish good assignments from common ones.&lt;br /&gt;
&lt;br /&gt;
=='''Product Verion Functionality'''==&lt;br /&gt;
* In production version, instructor can set ''Submission deadline'', ''Review deadline'' and ''Metareview deadline'' for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments_M.png‎  |frame|center|Set different deadline for each topic]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Also, instructor can set the dependencies of different topics. And there is a dependency graph generated automatically.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments1_M.png‎  |frame|center|Dependency graph for all topics]]&lt;br /&gt;
&lt;br /&gt;
=='''Design Pattern'''==&lt;br /&gt;
* '''MVC'''&lt;br /&gt;
**Model–view–controller (MVC) is a software architectural pattern for implementing user interfaces. It divides a given software application into three interconnected parts, so as to separate internal representations of information from the ways that information is presented to or accepted from the user.&amp;lt;ref&amp;gt;[http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller. ''Model–view–controller''. Wikipedia]&amp;lt;/ref&amp;gt;&lt;br /&gt;
**We need to modify model, view and controller in order to fix this functionality.&lt;br /&gt;
&lt;br /&gt;
* '''Publish-subscribe'''&lt;br /&gt;
**In software architecture, publish–subscribe is a messaging pattern where senders of messages, called publishers, do not program the messages to be sent directly to specific receivers, called subscribers. Instead, published messages are characterized into classes, without knowledge of what, if any, subscribers there may be. Similarly, subscribers express interest in one or more classes, and only receive messages that are of interest, without knowledge of what, if any, publishers there are.&amp;lt;ref&amp;gt;[http://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern. ''Publish–subscribe pattern''. Wikipedia]&amp;lt;/ref&amp;gt;&lt;br /&gt;
** When instructor set an assignment as staggered-dealine assignment, in theory, all the students will know.&lt;br /&gt;
&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Create staggered-deadline assignment'''&lt;br /&gt;
** '''Actor:''' Instructor&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** Instructor logs in Expertiza.&lt;br /&gt;
*** Instructor creates a new staggered-deadline assignment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Peer review only'''&lt;br /&gt;
** '''Actor:''' Student finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Hand in assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
*** Write author feedback to reviewer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Peer review and still work on assignments'''&lt;br /&gt;
** '''Actor:''' Student not finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Work on assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:UseCaseDiagram1_M.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Error Message Present'''==&lt;br /&gt;
* First, login expertiza, in the &amp;quot;Manage Content&amp;quot; page, create a new assignment. Then, as shown below, choose the &amp;quot;pencil&amp;quot; icon to edit the assignment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment1.jpg |frame|center|Assignment panel 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Check&amp;quot;Has topics?&amp;quot; and &amp;quot;Staggered deadline assignment?&amp;quot; two checkbox, and create new topics in &amp;quot;Topics&amp;quot; panel, click &amp;quot;save&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment2.jpg |frame|center|Create Topics]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Back to the &amp;quot;Manage Content&amp;quot; page, choose the &amp;quot;Edit signup sheet&amp;quot; icon.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment3.jpg |frame|center|Assignment panel 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Error: can't write unknown attribute 't_id'.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:assignment4.jpg |frame|center|Error]]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Analysis'''==&lt;br /&gt;
* After discussing with professor, the &amp;quot;sign up sheet&amp;quot; icon in assignment pop up panel should be moved. Because that icon has the same functionality as &amp;quot;topic&amp;quot; panel in assignment edit window. These work has already done by [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2015/oss_E1509_lds OSS1509]. So we have to move all the staggered-deadline realted code to the [https://github.com/expertiza/expertiza/blob/rails4/app/controllers/assignments_controller.rb assignments_controller.rb] and [https://github.com/expertiza/expertiza/blob/rails4/app/views/assignments/edit.html.erb assignments/edit.html.erb].&lt;br /&gt;
&lt;br /&gt;
* In &amp;quot;sign_up_sheet_controller&amp;quot;, there are several errors and confusions in function &amp;quot;add_sign_up_topic&amp;quot;. The function is used to display a page that lists all the available topics for a staggered-deadline assignment.&amp;lt;br&amp;gt; &lt;br /&gt;
See the function code below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_signup_topic&lt;br /&gt;
  load_add_signup_topics(params[:id])&lt;br /&gt;
&lt;br /&gt;
  @review_rounds = Assignment.find(params[:id]).get_review_rounds&lt;br /&gt;
  @topics = SignUpTopic.where(assignment_id: params[:id])&lt;br /&gt;
&lt;br /&gt;
  #Use this until you figure out how to initialize this array&lt;br /&gt;
  @duedates = SignUpTopic.find_by_sql(&amp;quot;SELECT s.id as topic_id FROM sign_up_topics s WHERE s.assignment_id = &amp;quot; + params[:id].to_s)&lt;br /&gt;
&lt;br /&gt;
  unless @topics.nil?&lt;br /&gt;
    i=0&lt;br /&gt;
    @topics.each { |topic|&lt;br /&gt;
&lt;br /&gt;
      @duedates[i]['t_id'] = topic.id&lt;br /&gt;
      @duedates[i]['topic_identifier'] = topic.topic_identifier&lt;br /&gt;
      @duedates[i]['topic_name'] = topic.topic_name&lt;br /&gt;
&lt;br /&gt;
      for j in 1..@review_rounds&lt;br /&gt;
        duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('submission').id).first&lt;br /&gt;
        duedate_rev = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('review').id).first&lt;br /&gt;
        if !duedate_subm.nil? &amp;amp;&amp;amp; !duedate_rev.nil?&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        else&lt;br /&gt;
          #the topic is new. so copy deadlines from assignment&lt;br /&gt;
          set_of_due_dates = DueDate.where(assignment_id: params[:id])&lt;br /&gt;
          set_of_due_dates.each { |due_date|&lt;br /&gt;
            create_topic_deadline(due_date, 0, topic.id)&lt;br /&gt;
          }&lt;br /&gt;
&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
      end&lt;br /&gt;
      duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('metareview').id).first&lt;br /&gt;
      @duedates[i]['submission_'+ (@review_rounds+1).to_s] = !(duedate_subm.nil?)?(DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)):nil&lt;br /&gt;
      i = i + 1&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The main confusions are:&lt;br /&gt;
* In line 8, the variable &amp;quot;duedates&amp;quot; are declared as type &amp;quot;SignUpTopic&amp;quot;. The naming is quite confusing.&lt;br /&gt;
* In line 14, the SignUpTopic class doesn't have a column &amp;quot;t_id&amp;quot;, it raises an error. We think it should be &amp;quot;topic_id&amp;quot;.&lt;br /&gt;
* From the code we can guess the variable &amp;quot;duedates&amp;quot; is used to store the deadline for each topic. The class &amp;quot;DueData&amp;quot; does exist, but it does not have column &amp;quot;topic_identifier&amp;quot; or &amp;quot;topic_name&amp;quot;. It only stores the deadline for a single assignment.&lt;br /&gt;
&lt;br /&gt;
=='''Puzzle'''==&lt;br /&gt;
* If there is more than one round, which means students can submit their assignments more than once, so the staggered-deadline should refer to which deadline?&lt;br /&gt;
'''[Professor]''' In a staggered-deadline assignment, there is one submission deadline and one review deadline per round.  These are always set on a per-topic basis.&lt;br /&gt;
If the view currently works (and I think it might), as soon as you make an assignment a staggered-deadline assignment, the Signup Sheet (Topics) page will have a link at the bottom to show deadlines for each topic.  Click it, and you will see a separate text box for each deadline for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* If staggered-deadline of one assignment is even later than the second-round review, is it means that that assignment do not need peer review and go directly into meta-review stage?&lt;br /&gt;
'''[Professor]''' No, there are also separate meta-review deadlines for a staggered-deadline assignment.&lt;br /&gt;
I think in the current implementation, only submission deadlines, review deadlines, and meta-review deadlines vary by topic.  In a more complete implementation, there would be a way for ANY deadline to vary by topic.  This would include signup deadlines, drop-topic deadlines, team-formation deadlines, and any other kind of deadline that is defined later.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* When to set staggered-deadline assignments? Create assignment or Before submission?&lt;br /&gt;
'''[Professor]''' Basically, the staggered-deadline is set at the same time when an assignment is created. But if one team cannot hand in their work with sufficient reasons, instructor may extend the deadline of their topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* What is the meaning of &amp;quot;dependencies&amp;quot; between topics?&lt;br /&gt;
'''[Professor]''' The ''dependencies'' of topics means one topic cannot start until another topic finishes. For instance, ''Ruby'' topic must be finished before ''Rails'' topic.&lt;br /&gt;
&lt;br /&gt;
=='''Workflow'''==&lt;br /&gt;
&lt;br /&gt;
==='''Set topics staggered deadline'''===&lt;br /&gt;
At very beginning, we find that the type of &amp;lt;code&amp;gt;due_date&amp;lt;/code&amp;gt; variable &amp;lt;code&amp;gt;SignUpTopics&amp;lt;/code&amp;gt;. However, we found that many attributes used not belonging to &amp;lt;code&amp;gt;SignUpTopics&amp;lt;/code&amp;gt; class. So we deceide to use has tables instead. In order to keep update the staggered deadline, we put this variable in session. We also comprehended the relationship of corresponding tables. The original due dates are stored in &amp;lt;code&amp;gt;due_date&amp;lt;/code&amp;gt; table. And staggered-deadlines are stored in &amp;lt;code&amp;gt;TopicDeadline&amp;lt;/code&amp;gt; table. This table also stores different deadline types.&lt;br /&gt;
&lt;br /&gt;
Below is &amp;lt;code&amp;gt;save_topic_deadlines&amp;lt;/code&amp;gt; method after refactoring.&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
  #session[:duedates] stores all original duedates info&lt;br /&gt;
  #due_dates stores staggered duedates&lt;br /&gt;
  due_dates = params[:due_date]&lt;br /&gt;
  topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
  review_rounds = Assignment.find(params[:assignment_id]).get_review_rounds&lt;br /&gt;
  # j represents the review rounds&lt;br /&gt;
  j = 0&lt;br /&gt;
  topics.each { |topic|&lt;br /&gt;
    for i in 1..review_rounds&lt;br /&gt;
      topic_deadline_type_subm = DeadlineType.find_by_name('submission').id&lt;br /&gt;
      topic_deadline_subm = TopicDeadline.where(topic_id: session[:duedates][j]['id'].to_i, deadline_type_id: topic_deadline_type_subm, round: i).first&lt;br /&gt;
      topic_deadline_subm.update_attributes({'due_at' =&amp;gt; due_dates[session[:duedates][j]['id'].to_s + '_submission_' + i.to_s + '_due_date']})&lt;br /&gt;
      flash[:error] = &amp;quot;Please enter a valid &amp;quot; + (i &amp;gt; 1 ? &amp;quot;Resubmission deadline &amp;quot; + (i-1).to_s : &amp;quot;Submission deadline&amp;quot;) if topic_deadline_subm.errors.length &amp;gt; 0&lt;br /&gt;
      topic_deadline_type_rev = DeadlineType.find_by_name('review').id&lt;br /&gt;
      topic_deadline_rev = TopicDeadline.where(topic_id: session[:duedates][j]['id'].to_i, deadline_type_id: topic_deadline_type_rev, round:i).first&lt;br /&gt;
      topic_deadline_rev.update_attributes({'due_at' =&amp;gt; due_dates[session[:duedates][j]['id'].to_s + '_review_' + i.to_s + '_due_date']})&lt;br /&gt;
      flash[:error] = &amp;quot;Please enter a valid Review deadline &amp;quot; + (i &amp;gt; 1 ? (i-1).to_s : &amp;quot;&amp;quot;) if topic_deadline_rev.errors.length &amp;gt; 0&lt;br /&gt;
    end&lt;br /&gt;
    topic_deadline_subm = TopicDeadline.where(topic_id: session[:duedates][j]['id'], deadline_type_id:  DeadlineType.find_by_name('metareview').id).first&lt;br /&gt;
    topic_deadline_subm.update_attributes({'due_at' =&amp;gt; due_dates[session[:duedates][j]['id'].to_s + '_submission_' + (review_rounds+1).to_s + '_due_date']})&lt;br /&gt;
    flash[:error] = &amp;quot;Please enter a valid Meta review deadline&amp;quot; if topic_deadline_subm.errors.length &amp;gt; 0&lt;br /&gt;
    j = j + 1&lt;br /&gt;
  }&lt;br /&gt;
  redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==='''Save topics dependency and show dependency graph'''===&lt;br /&gt;
In edit signup sheet for assignment, we want to save topic dependency and show the depandency graph, as show below:&lt;br /&gt;
[[File:save_denpendency.jpg |frame|center|Assignment panel 1]]&lt;br /&gt;
In order to show the dependency graph, we must first save topics dependency and save the topic dependency graph under &amp;lt;code&amp;gt; public/assets/staggered_deadline_assignment_graph &amp;lt;/code&amp;gt; path. We first add new method in 'due_date' model:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def self.assign_start_due_date(assignment_id, set_of_topics)&lt;br /&gt;
&lt;br /&gt;
    #Remember, in create_common_start_time_topics function we reversed the graph so reverse it back&lt;br /&gt;
    set_of_topics = set_of_topics.reverse&lt;br /&gt;
&lt;br /&gt;
    set_of_topics_due_dates = Array.new&lt;br /&gt;
    i=0&lt;br /&gt;
    days_between_submissions = Assignment.find(assignment_id)['days_between_submissions'].to_i&lt;br /&gt;
    set_of_topics.each { |set_of_topic|&lt;br /&gt;
      set_of_due_dates = nil&lt;br /&gt;
      if i==0&lt;br /&gt;
        #take the first set from the table which user stores&lt;br /&gt;
        set_of_due_dates = DueDate.where(assignment_id)&lt;br /&gt;
        offset = 0&lt;br /&gt;
      else&lt;br /&gt;
        set_of_due_dates = TopicDeadline.where(set_of_topics[i-1][0])&lt;br /&gt;
        set_of_due_dates.sort_by { |a, b| a.due_at &amp;lt;=&amp;gt; b.due_at }&lt;br /&gt;
        offset = days_between_submissions&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      set_of_topic.each { |topic_id|&lt;br /&gt;
        #if the due dates have already been created and the save dependency is being clicked,&lt;br /&gt;
        #then delete existing n create again&lt;br /&gt;
        prev_saved_due_dates = TopicDeadline.where(topic_id)&lt;br /&gt;
&lt;br /&gt;
        #Only if there is a dependency for the topic&lt;br /&gt;
        if !prev_saved_due_dates.nil?&lt;br /&gt;
          num_due_dates = prev_saved_due_dates.length&lt;br /&gt;
          #for each due date in the current topic he want to compare it to the previous due date&lt;br /&gt;
          for x in 0..num_due_dates - 1&lt;br /&gt;
            #we don't want the old date to move earlier in time so we save it as the new due date and destroy the old one  &lt;br /&gt;
            if DateTime.parse(set_of_due_dates[x].due_at.to_s) + offset.to_i &amp;lt; DateTime.parse(prev_saved_due_dates[x].due_at.to_s)&lt;br /&gt;
              set_of_due_dates[x] = prev_saved_due_dates[x]&lt;br /&gt;
              offset = 0&lt;br /&gt;
            end&lt;br /&gt;
            prev_saved_due_dates[x].destroy&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        set_of_due_dates.each { |due_date|&lt;br /&gt;
          create_topic_deadline(due_date, offset, topic_id)&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      i = i+1&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, change the &amp;lt;code&amp;gt;save_topic_dependencies&amp;lt;/code&amp;gt; method in &amp;lt;code&amp;gt; sign_up_sheet_controller.rb &amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - redirect_to_sign_up(params[:assignment_id])&lt;br /&gt;
  + redirect_to :action =&amp;gt; 'add_signup_topics_staggered', :id =&amp;gt; params[:assignment_id] &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since we use &amp;lt;code&amp;gt;RGL:Graph#write_to_graphic_file&amp;lt;/code&amp;gt; method to turn the dependency graph into &amp;lt;code&amp;gt;jpg&amp;lt;/code&amp;gt; file, we need to install graphviz in our gems. Otherwise, the RGL will uses &amp;lt;code&amp;gt;dot&amp;lt;/code&amp;gt; files as an intermediary format to produce image formats. If we download the &amp;lt;code&amp;gt;GraphViz&amp;lt;/code&amp;gt; packege, RGL will invoke it to produce a &amp;lt;code&amp;gt;jpg&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gem 'graphviz' &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Then, after we click the &amp;lt;code&amp;gt;Save dependency&amp;lt;/code&amp;gt; button, and click &amp;lt;code&amp;gt;show dependency graph&amp;lt;/code&amp;gt; button, the dependency graph is shown below:&lt;br /&gt;
[[File:show_denpendency.jpg |frame|center|Assignment panel 2]]&lt;br /&gt;
&lt;br /&gt;
==='''Test'''===&lt;br /&gt;
Since we have done several modifications to the Expertiza program, some new tests are needed to test the features.&lt;br /&gt;
* We use the stub to simulate an authorized login (as instructor).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ApplicationController.any_instance.stub(:current_role_name).and_return('Instructor')&lt;br /&gt;
ApplicationController.any_instance.stub(:undo_link).and_return(TRUE)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Each time the program executes the current_role_name function, it gets &amp;quot;instructor&amp;quot;.&lt;br /&gt;
* Firstly, we test some operations to topic&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should be able to create topic for assignment&amp;quot; do&lt;br /&gt;
    get :create, id: @assignment.id, topic: {topic_name: &amp;quot;New Topic&amp;quot;, max_choosers: 2, topic_identifier: &amp;quot;Ch1&amp;quot;, category: &amp;quot;Programming&amp;quot;}&lt;br /&gt;
    expect(response).should redirect_to(edit_assignment_path(@assignment.id) + &amp;quot;#tabs-5&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
it &amp;quot;should be able to edit topic&amp;quot; do&lt;br /&gt;
  get :edit, id: @topic.id&lt;br /&gt;
  expect(response).to be_success&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
it &amp;quot;should be able to delete topic&amp;quot; do&lt;br /&gt;
  delete :destroy, id: @topic.id, assignment_id: @assignment.id&lt;br /&gt;
  expect(response).should redirect_to edit_assignment_path(@assignment.id) + &amp;quot;#tabs-5&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Deploy on VCL'''===&lt;br /&gt;
&lt;br /&gt;
* Visit http://vcl.ncsu.edu/ &amp;gt; Make a Reservation&lt;br /&gt;
* Select Ruby on Rails / Expertiza from the &amp;quot;Please select the environment ...&amp;quot; dropdown, select a duration, and then click Create Reservation&lt;br /&gt;
* Once the reservation is available, click Connect&lt;br /&gt;
* Follow the instructions on the connect screen (connect via SSH and then VNC). Connecting to SSH starts up VNC, the graphical environment to which you will connect.&lt;br /&gt;
* When connecting for the first time, it will prompt you for a password to access your (VNC) desktop. You can use any password, and it will be saved for later sessions.&lt;br /&gt;
* Follow the instructions given to connect to VNC. It is recommended to use [https://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=1&amp;amp;cad=rja&amp;amp;uact=8&amp;amp;ved=0CB0QFjAA&amp;amp;url=https%3A%2F%2Fchrome.google.com%2Fwebstore%2Fdetail%2Fvnc%25C2%25AE-viewer-for-google-ch%2Fiabmpiboiopbgfabjmgeedhcmjenhbla&amp;amp;ei=LEY7Veq8C8GNNrvhgegI&amp;amp;usg=AFQjCNGxB1W4GwZrwQWHyBfik1cbjvXMkw VNC Viewer for Google Chrome].&lt;br /&gt;
* Once connected to VNC, you should see Rubymine running.&lt;br /&gt;
* Open a terminal (Applications &amp;gt; Accessories &amp;gt; Terminal), try hitting &amp;lt;ctrl&amp;gt;-C to kill pending task if your terminal does not work properly.&lt;br /&gt;
* Ensure you have at least 20M disk quota available: fs lq . You can allocate more space at https://sysnews.ncsu.edu/tools-bin/usmdb-quota&lt;br /&gt;
* Clone the git repository: git clone (expertiza repository URL)&lt;br /&gt;
* Change to the directory (cd expertiza). You may create a &amp;quot;database.yml&amp;quot; file based on &amp;quot;database.yml.example&amp;quot;.&lt;br /&gt;
* Use rvm use (ruby version) to switch to proper ruby version. Then run bundle install (you may need to downgrade the bundler to avoid bundle install failure) and rake db:migrate to set up development environment.&lt;br /&gt;
* Use &amp;quot;rails s -b 0.0.0.0&amp;quot; to start server which allows the access outside VCL by using url: VCL_ip:3000.&lt;br /&gt;
&lt;br /&gt;
=='''Related materials'''==&lt;br /&gt;
*An [http://research.csc.ncsu.edu/efg/expertiza/reports/Instructor_documentation.doc instructor manual], explaining how to create an deploy an assignment in Expertiza.&lt;br /&gt;
*An [http://research.csc.ncsu.edu/efg/expertiza/presentations/videos/instructor.swf instructor video], slightly dated, showing how to create and deploy an assignment&lt;br /&gt;
* A guide for [[Creating_Custom_Rubric]]&lt;br /&gt;
*For students, a [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_documentation.ppt Powerpoint] or [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_documentation.pdf PDF] presentation explaining how to submit and review an assignment with Expertiza.&lt;br /&gt;
*For students, a [http://research.csc.ncsu.edu/efg/expertiza/presentations/videos/student.swf video] showing how to use the system to submit and review an assignment.&lt;br /&gt;
*For students, a [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_wiki_documentation.ppt Powerpoint] or [http://research.csc.ncsu.edu/efg/expertiza/presentations/student_wiki_documentation.pdf PDF] presentation explaining how to submit and review wiki pages with Expertiza.&lt;br /&gt;
*For students, a [http://courses.ncsu.edu/csc517/common/homework/topic-signup-team-formation.ppt Powerpoint] or [http://courses.ncsu.edu/csc517/common/homework/topic-signup-team-formation.pdf PDF] presentation explaining how to form teams and sign up for topics&amp;lt;ref&amp;gt;[http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza. Wolfwikis]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Szhang29</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96050</id>
		<title>CSC/ECE 517 Spring 2015 S1524 FSZZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96050"/>
		<updated>2015-03-30T19:49:43Z</updated>

		<summary type="html">&lt;p&gt;Szhang29: /* Initial Analyse */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1524. Refactor staggered-deadline assignments&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Overview'''==&lt;br /&gt;
===Introduction to Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
===Staggered Deadlines===&lt;br /&gt;
Staggered deadlines involve planning alternate submission dates for papers, projects, or exams when a student has conflicting due dates for these.  The key part of staggered deadlines is the planning. Staggered deadlines are always established well in advance of the scheduled due date. It is the advanced planning of these deadlines that makes them &amp;quot;staggered deadlines&amp;quot; rather than extensions&amp;lt;ref&amp;gt;[http://pages.vassar.edu/accessingvassar/2013/01/15/difficulties-with-staggered-deadlines/ Elmichaels. ''Difficulties with Staggered Deadlines''. Jan 15, 2013]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
==='''Background'''===&lt;br /&gt;
In this semester’s 517 class.  Wiki 1a and Wiki 1b are structured as separate assignments, with separate signup sheets, teams, and reviews.  But really, since only one of the two was done by any student, it would’ve been better to have a single assignment.  Still, some topics could be done soon after the course started, whereas others were better done after we had studied related topics in class.&lt;br /&gt;
&lt;br /&gt;
==='''Staggered-deadline Assignment'''===&lt;br /&gt;
This raises the idea of a ''staggered-deadline assignment'', where different topics have different submission and review deadlines, rather than all topics having the same deadline. &lt;br /&gt;
&lt;br /&gt;
==='''Benefit'''===&lt;br /&gt;
* '''Easy to manage.''' Because in the past, instructor has to build two separate assignments for Wiki 1a and 1b, now one assignment for Wiki is enough. &lt;br /&gt;
&lt;br /&gt;
* '''Increase flexibility.''' For instance, when an OSS team facing a much more difficult problem than other teams, instructor may postpone their deadline several days. It will make Expertiza more humanize.&lt;br /&gt;
&lt;br /&gt;
* '''Take time to do calibration.''' We find that two Wiki assignments started at Jan. 28th and ended at Feb. 25th, which takes too much time. And with staggered-deadline assignment, we can distribute less time on them. And we can take redundant time to do calibrating. Because we find that many students actually do not know how to evaluate other ones’ work, even there are some rubrics offered. So we recommend to let students grade sample assignments first, then calibrate their grading behaviors. Although it will take some time, we consider it is important to help students distinguish good assignments from common ones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Product Verion Functionality'''==&lt;br /&gt;
* In production version, instructor can set ''Submission deadline'', ''Review deadline'' and ''Metareview deadline'' for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments_M.png‎  |frame|center|Set different deadline for each topic]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Also, instructor can set the dependencies of different topics. And there is a dependency graph generated automatically.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments1_M.png‎  |frame|center|Dependency graph for all topics]]&lt;br /&gt;
&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Create staggered-deadline assignment'''&lt;br /&gt;
** '''Actor:''' Instructor&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** Instructor logs in Expertiza.&lt;br /&gt;
*** Instructor creates a new staggered-deadline assignment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Peer review only'''&lt;br /&gt;
** '''Actor:''' Student finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Hand in assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
*** Write author feedback to reviewer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Peer review and still work on assignments'''&lt;br /&gt;
** '''Actor:''' Student not finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Work on assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:UseCaseDiagram1_M.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=='''Error Message Present'''==&lt;br /&gt;
* First, login expertiza, in the “Manage Content” page, create a new assignment, for example, the name is “assignment 1b”. Then, as shown below, choose the first icon to edit this assignment.&lt;br /&gt;
[[File:assignment1.jpg |frame|center]]&lt;br /&gt;
* Select “Has topics?” and “Staggered deadline assignment?” box in General, and create new topics in Topics, save the properties.&lt;br /&gt;
[[File:assignment2.jpg |frame|center]]&lt;br /&gt;
* Back to the “Manage Content” page, this time choose the “Edit signup sheet” button.&lt;br /&gt;
[[File:assignment3.jpg |frame|center]]&lt;br /&gt;
* Then, it shows the error: can’t write unknown attribute ‘t_id’.&lt;br /&gt;
[[File:assignment4.jpg |frame|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Initial Analyse'''==&lt;br /&gt;
In “sign_up_sheet_controller”, there are several errors and confusions in function “add_sign_up_topic”. The function is used to displays a page that lists all the available topics for a staggered-deadline assignment.&amp;lt;br&amp;gt; &lt;br /&gt;
See the function code below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_signup_topic&lt;br /&gt;
  load_add_signup_topics(params[:id])&lt;br /&gt;
&lt;br /&gt;
  @review_rounds = Assignment.find(params[:id]).get_review_rounds&lt;br /&gt;
  @topics = SignUpTopic.where(assignment_id: params[:id])&lt;br /&gt;
&lt;br /&gt;
  #Use this until you figure out how to initialize this array&lt;br /&gt;
  @duedates = SignUpTopic.find_by_sql(&amp;quot;SELECT s.id as topic_id FROM sign_up_topics s WHERE s.assignment_id = &amp;quot; + params[:id].to_s)&lt;br /&gt;
&lt;br /&gt;
  unless @topics.nil?&lt;br /&gt;
    i=0&lt;br /&gt;
    @topics.each { |topic|&lt;br /&gt;
&lt;br /&gt;
      @duedates[i]['t_id'] = topic.id&lt;br /&gt;
      @duedates[i]['topic_identifier'] = topic.topic_identifier&lt;br /&gt;
      @duedates[i]['topic_name'] = topic.topic_name&lt;br /&gt;
&lt;br /&gt;
      for j in 1..@review_rounds&lt;br /&gt;
        duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('submission').id).first&lt;br /&gt;
        duedate_rev = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('review').id).first&lt;br /&gt;
        if !duedate_subm.nil? &amp;amp;&amp;amp; !duedate_rev.nil?&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        else&lt;br /&gt;
          #the topic is new. so copy deadlines from assignment&lt;br /&gt;
          set_of_due_dates = DueDate.where(assignment_id: params[:id])&lt;br /&gt;
          set_of_due_dates.each { |due_date|&lt;br /&gt;
            create_topic_deadline(due_date, 0, topic.id)&lt;br /&gt;
          }&lt;br /&gt;
&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
      end&lt;br /&gt;
      duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('metareview').id).first&lt;br /&gt;
      @duedates[i]['submission_'+ (@review_rounds+1).to_s] = !(duedate_subm.nil?)?(DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)):nil&lt;br /&gt;
      i = i + 1&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The main confusions are:&lt;br /&gt;
* In line 8, the variable &amp;quot;duedates&amp;quot; are declared as type &amp;quot;SignUpTopic&amp;quot;. The naming is quite confusing.&lt;br /&gt;
* In line 14, the SignUpTopic class doesn’t have a column “t_id”, it raises an error. We think it should be &amp;quot;topic_id&amp;quot;.&lt;br /&gt;
* From the code we can guess the variable &amp;quot;duedates&amp;quot; is used to store the deadline for each topic. The class “DueData” does exist, but it does not have column “topic_identifier” or “topic_name”. It only stores the deadline for a single assignment.&lt;br /&gt;
&lt;br /&gt;
=='''Puzzle'''==&lt;br /&gt;
* If there is more than one round, which means students can submit their assignments more than once, so the staggered-deadline should refer to which deadline?&lt;br /&gt;
'''[Professor]'''In a staggered-deadline assignment, there is one submission deadline and one review deadline per round.  These are always set on a per-topic basis.&lt;br /&gt;
If the view currently works (and I think it might), as soon as you make an assignment a staggered-deadline assignment, the Signup Sheet (Topics) page will have a link at the bottom to show deadlines for each topic.  Click it, and you will see a separate text box for each deadline for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* If staggered-deadline of one assignment is even later than the second-round review, is it means that that assignment do not need peer review and go directly into meta-review stage?&lt;br /&gt;
'''[Professor]'''No, there are also separate meta-review deadlines for a staggered-deadline assignment.&lt;br /&gt;
I think in the current implementation, only submission deadlines, review deadlines, and meta-review deadlines vary by topic.  In a more complete implementation, there would be a way for ANY deadline to vary by topic.  This would include signup deadlines, drop-topic deadlines, team-formation deadlines, and any other kind of deadline that is defined later.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* When to set staggered-deadline assignments? Create assignment or Before submission?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* What is the meaning of &amp;quot;dependencies&amp;quot; between topics?&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Szhang29</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96049</id>
		<title>CSC/ECE 517 Spring 2015 S1524 FSZZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96049"/>
		<updated>2015-03-30T19:48:57Z</updated>

		<summary type="html">&lt;p&gt;Szhang29: /* Initial Analyse */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1524. Refactor staggered-deadline assignments&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Overview'''==&lt;br /&gt;
===Introduction to Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
===Staggered Deadlines===&lt;br /&gt;
Staggered deadlines involve planning alternate submission dates for papers, projects, or exams when a student has conflicting due dates for these.  The key part of staggered deadlines is the planning. Staggered deadlines are always established well in advance of the scheduled due date. It is the advanced planning of these deadlines that makes them &amp;quot;staggered deadlines&amp;quot; rather than extensions&amp;lt;ref&amp;gt;[http://pages.vassar.edu/accessingvassar/2013/01/15/difficulties-with-staggered-deadlines/ Elmichaels. ''Difficulties with Staggered Deadlines''. Jan 15, 2013]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
==='''Background'''===&lt;br /&gt;
In this semester’s 517 class.  Wiki 1a and Wiki 1b are structured as separate assignments, with separate signup sheets, teams, and reviews.  But really, since only one of the two was done by any student, it would’ve been better to have a single assignment.  Still, some topics could be done soon after the course started, whereas others were better done after we had studied related topics in class.&lt;br /&gt;
&lt;br /&gt;
==='''Staggered-deadline Assignment'''===&lt;br /&gt;
This raises the idea of a ''staggered-deadline assignment'', where different topics have different submission and review deadlines, rather than all topics having the same deadline. &lt;br /&gt;
&lt;br /&gt;
==='''Benefit'''===&lt;br /&gt;
* '''Easy to manage.''' Because in the past, instructor has to build two separate assignments for Wiki 1a and 1b, now one assignment for Wiki is enough. &lt;br /&gt;
&lt;br /&gt;
* '''Increase flexibility.''' For instance, when an OSS team facing a much more difficult problem than other teams, instructor may postpone their deadline several days. It will make Expertiza more humanize.&lt;br /&gt;
&lt;br /&gt;
* '''Take time to do calibration.''' We find that two Wiki assignments started at Jan. 28th and ended at Feb. 25th, which takes too much time. And with staggered-deadline assignment, we can distribute less time on them. And we can take redundant time to do calibrating. Because we find that many students actually do not know how to evaluate other ones’ work, even there are some rubrics offered. So we recommend to let students grade sample assignments first, then calibrate their grading behaviors. Although it will take some time, we consider it is important to help students distinguish good assignments from common ones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Product Verion Functionality'''==&lt;br /&gt;
* In production version, instructor can set ''Submission deadline'', ''Review deadline'' and ''Metareview deadline'' for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments_M.png‎  |frame|center|Set different deadline for each topic]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Also, instructor can set the dependencies of different topics. And there is a dependency graph generated automatically.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments1_M.png‎  |frame|center|Dependency graph for all topics]]&lt;br /&gt;
&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Create staggered-deadline assignment'''&lt;br /&gt;
** '''Actor:''' Instructor&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** Instructor logs in Expertiza.&lt;br /&gt;
*** Instructor creates a new staggered-deadline assignment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Peer review only'''&lt;br /&gt;
** '''Actor:''' Student finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Hand in assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
*** Write author feedback to reviewer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Peer review and still work on assignments'''&lt;br /&gt;
** '''Actor:''' Student not finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Work on assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:UseCaseDiagram1_M.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=='''Error Message Present'''==&lt;br /&gt;
* First, login expertiza, in the “Manage Content” page, create a new assignment, for example, the name is “assignment 1b”. Then, as shown below, choose the first icon to edit this assignment.&lt;br /&gt;
[[File:assignment1.jpg |frame|center]]&lt;br /&gt;
* Select “Has topics?” and “Staggered deadline assignment?” box in General, and create new topics in Topics, save the properties.&lt;br /&gt;
[[File:assignment2.jpg |frame|center]]&lt;br /&gt;
* Back to the “Manage Content” page, this time choose the “Edit signup sheet” button.&lt;br /&gt;
[[File:assignment3.jpg |frame|center]]&lt;br /&gt;
* Then, it shows the error: can’t write unknown attribute ‘t_id’.&lt;br /&gt;
[[File:assignment4.jpg |frame|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Initial Analyse'''==&lt;br /&gt;
In “sign_up_sheet_controller”, there are several errors and confusions in function “add_sign_up_topic”. The function is used to displays a page that lists all the available topics for a staggered-deadline assignment.&amp;lt;br&amp;gt; &lt;br /&gt;
See the function code below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_signup_topic&lt;br /&gt;
  load_add_signup_topics(params[:id])&lt;br /&gt;
&lt;br /&gt;
  @review_rounds = Assignment.find(params[:id]).get_review_rounds&lt;br /&gt;
  @topics = SignUpTopic.where(assignment_id: params[:id])&lt;br /&gt;
&lt;br /&gt;
  #Use this until you figure out how to initialize this array&lt;br /&gt;
  @duedates = SignUpTopic.find_by_sql(&amp;quot;SELECT s.id as topic_id FROM sign_up_topics s WHERE s.assignment_id = &amp;quot; + params[:id].to_s)&lt;br /&gt;
&lt;br /&gt;
  unless @topics.nil?&lt;br /&gt;
    i=0&lt;br /&gt;
    @topics.each { |topic|&lt;br /&gt;
&lt;br /&gt;
      @duedates[i]['t_id'] = topic.id&lt;br /&gt;
      @duedates[i]['topic_identifier'] = topic.topic_identifier&lt;br /&gt;
      @duedates[i]['topic_name'] = topic.topic_name&lt;br /&gt;
&lt;br /&gt;
      for j in 1..@review_rounds&lt;br /&gt;
        duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('submission').id).first&lt;br /&gt;
        duedate_rev = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('review').id).first&lt;br /&gt;
        if !duedate_subm.nil? &amp;amp;&amp;amp; !duedate_rev.nil?&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        else&lt;br /&gt;
          #the topic is new. so copy deadlines from assignment&lt;br /&gt;
          set_of_due_dates = DueDate.where(assignment_id: params[:id])&lt;br /&gt;
          set_of_due_dates.each { |due_date|&lt;br /&gt;
            create_topic_deadline(due_date, 0, topic.id)&lt;br /&gt;
          }&lt;br /&gt;
&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
      end&lt;br /&gt;
      duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('metareview').id).first&lt;br /&gt;
      @duedates[i]['submission_'+ (@review_rounds+1).to_s] = !(duedate_subm.nil?)?(DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)):nil&lt;br /&gt;
      i = i + 1&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The main confusions are:&lt;br /&gt;
* In line 8, the variable &amp;quot;duedates&amp;quot; are declared as type &amp;quot;SignUpTopic&amp;quot;. The naming is quite confusing.&lt;br /&gt;
* In line 14, the SignUpTopic class doesn’t have a column “t_id”, it raises an error. &lt;br /&gt;
* From the code we can guess the variable &amp;quot;duedates&amp;quot; is used to store the deadline for each topic. The class “DueData” does exist, but it does not have column “topic_identifier” or “topic_name”. It only stores the deadline for a single assignment.&lt;br /&gt;
&lt;br /&gt;
=='''Puzzle'''==&lt;br /&gt;
* If there is more than one round, which means students can submit their assignments more than once, so the staggered-deadline should refer to which deadline?&lt;br /&gt;
'''[Professor]'''In a staggered-deadline assignment, there is one submission deadline and one review deadline per round.  These are always set on a per-topic basis.&lt;br /&gt;
If the view currently works (and I think it might), as soon as you make an assignment a staggered-deadline assignment, the Signup Sheet (Topics) page will have a link at the bottom to show deadlines for each topic.  Click it, and you will see a separate text box for each deadline for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* If staggered-deadline of one assignment is even later than the second-round review, is it means that that assignment do not need peer review and go directly into meta-review stage?&lt;br /&gt;
'''[Professor]'''No, there are also separate meta-review deadlines for a staggered-deadline assignment.&lt;br /&gt;
I think in the current implementation, only submission deadlines, review deadlines, and meta-review deadlines vary by topic.  In a more complete implementation, there would be a way for ANY deadline to vary by topic.  This would include signup deadlines, drop-topic deadlines, team-formation deadlines, and any other kind of deadline that is defined later.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* When to set staggered-deadline assignments? Create assignment or Before submission?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* What is the meaning of &amp;quot;dependencies&amp;quot; between topics?&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Szhang29</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96048</id>
		<title>CSC/ECE 517 Spring 2015 S1524 FSZZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96048"/>
		<updated>2015-03-30T19:48:42Z</updated>

		<summary type="html">&lt;p&gt;Szhang29: /* Initial Analyse */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1524. Refactor staggered-deadline assignments&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Overview'''==&lt;br /&gt;
===Introduction to Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
===Staggered Deadlines===&lt;br /&gt;
Staggered deadlines involve planning alternate submission dates for papers, projects, or exams when a student has conflicting due dates for these.  The key part of staggered deadlines is the planning. Staggered deadlines are always established well in advance of the scheduled due date. It is the advanced planning of these deadlines that makes them &amp;quot;staggered deadlines&amp;quot; rather than extensions&amp;lt;ref&amp;gt;[http://pages.vassar.edu/accessingvassar/2013/01/15/difficulties-with-staggered-deadlines/ Elmichaels. ''Difficulties with Staggered Deadlines''. Jan 15, 2013]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
==='''Background'''===&lt;br /&gt;
In this semester’s 517 class.  Wiki 1a and Wiki 1b are structured as separate assignments, with separate signup sheets, teams, and reviews.  But really, since only one of the two was done by any student, it would’ve been better to have a single assignment.  Still, some topics could be done soon after the course started, whereas others were better done after we had studied related topics in class.&lt;br /&gt;
&lt;br /&gt;
==='''Staggered-deadline Assignment'''===&lt;br /&gt;
This raises the idea of a ''staggered-deadline assignment'', where different topics have different submission and review deadlines, rather than all topics having the same deadline. &lt;br /&gt;
&lt;br /&gt;
==='''Benefit'''===&lt;br /&gt;
* '''Easy to manage.''' Because in the past, instructor has to build two separate assignments for Wiki 1a and 1b, now one assignment for Wiki is enough. &lt;br /&gt;
&lt;br /&gt;
* '''Increase flexibility.''' For instance, when an OSS team facing a much more difficult problem than other teams, instructor may postpone their deadline several days. It will make Expertiza more humanize.&lt;br /&gt;
&lt;br /&gt;
* '''Take time to do calibration.''' We find that two Wiki assignments started at Jan. 28th and ended at Feb. 25th, which takes too much time. And with staggered-deadline assignment, we can distribute less time on them. And we can take redundant time to do calibrating. Because we find that many students actually do not know how to evaluate other ones’ work, even there are some rubrics offered. So we recommend to let students grade sample assignments first, then calibrate their grading behaviors. Although it will take some time, we consider it is important to help students distinguish good assignments from common ones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Product Verion Functionality'''==&lt;br /&gt;
* In production version, instructor can set ''Submission deadline'', ''Review deadline'' and ''Metareview deadline'' for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments_M.png‎  |frame|center|Set different deadline for each topic]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Also, instructor can set the dependencies of different topics. And there is a dependency graph generated automatically.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments1_M.png‎  |frame|center|Dependency graph for all topics]]&lt;br /&gt;
&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Create staggered-deadline assignment'''&lt;br /&gt;
** '''Actor:''' Instructor&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** Instructor logs in Expertiza.&lt;br /&gt;
*** Instructor creates a new staggered-deadline assignment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Peer review only'''&lt;br /&gt;
** '''Actor:''' Student finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Hand in assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
*** Write author feedback to reviewer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Peer review and still work on assignments'''&lt;br /&gt;
** '''Actor:''' Student not finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Work on assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:UseCaseDiagram1_M.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=='''Error Message Present'''==&lt;br /&gt;
* First, login expertiza, in the “Manage Content” page, create a new assignment, for example, the name is “assignment 1b”. Then, as shown below, choose the first icon to edit this assignment.&lt;br /&gt;
[[File:assignment1.jpg |frame|center]]&lt;br /&gt;
* Select “Has topics?” and “Staggered deadline assignment?” box in General, and create new topics in Topics, save the properties.&lt;br /&gt;
[[File:assignment2.jpg |frame|center]]&lt;br /&gt;
* Back to the “Manage Content” page, this time choose the “Edit signup sheet” button.&lt;br /&gt;
[[File:assignment3.jpg |frame|center]]&lt;br /&gt;
* Then, it shows the error: can’t write unknown attribute ‘t_id’.&lt;br /&gt;
[[File:assignment4.jpg |frame|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Initial Analyse'''==&lt;br /&gt;
In “sign_up_sheet_controller”, there are several errors and confusions in function “add_sign_up_topic”. The function is used to displays a page that lists all the available topics for an staggered-deadline assignment.&amp;lt;br&amp;gt; &lt;br /&gt;
See the function code below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_signup_topic&lt;br /&gt;
  load_add_signup_topics(params[:id])&lt;br /&gt;
&lt;br /&gt;
  @review_rounds = Assignment.find(params[:id]).get_review_rounds&lt;br /&gt;
  @topics = SignUpTopic.where(assignment_id: params[:id])&lt;br /&gt;
&lt;br /&gt;
  #Use this until you figure out how to initialize this array&lt;br /&gt;
  @duedates = SignUpTopic.find_by_sql(&amp;quot;SELECT s.id as topic_id FROM sign_up_topics s WHERE s.assignment_id = &amp;quot; + params[:id].to_s)&lt;br /&gt;
&lt;br /&gt;
  unless @topics.nil?&lt;br /&gt;
    i=0&lt;br /&gt;
    @topics.each { |topic|&lt;br /&gt;
&lt;br /&gt;
      @duedates[i]['t_id'] = topic.id&lt;br /&gt;
      @duedates[i]['topic_identifier'] = topic.topic_identifier&lt;br /&gt;
      @duedates[i]['topic_name'] = topic.topic_name&lt;br /&gt;
&lt;br /&gt;
      for j in 1..@review_rounds&lt;br /&gt;
        duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('submission').id).first&lt;br /&gt;
        duedate_rev = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('review').id).first&lt;br /&gt;
        if !duedate_subm.nil? &amp;amp;&amp;amp; !duedate_rev.nil?&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        else&lt;br /&gt;
          #the topic is new. so copy deadlines from assignment&lt;br /&gt;
          set_of_due_dates = DueDate.where(assignment_id: params[:id])&lt;br /&gt;
          set_of_due_dates.each { |due_date|&lt;br /&gt;
            create_topic_deadline(due_date, 0, topic.id)&lt;br /&gt;
          }&lt;br /&gt;
&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
      end&lt;br /&gt;
      duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('metareview').id).first&lt;br /&gt;
      @duedates[i]['submission_'+ (@review_rounds+1).to_s] = !(duedate_subm.nil?)?(DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)):nil&lt;br /&gt;
      i = i + 1&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The main confusions are:&lt;br /&gt;
* In line 8, the variable &amp;quot;duedates&amp;quot; are declared as type &amp;quot;SignUpTopic&amp;quot;. The naming is quite confusing.&lt;br /&gt;
* In line 14, the SignUpTopic class doesn’t have a column “t_id”, it raises an error. &lt;br /&gt;
* From the code we can guess the variable &amp;quot;duedates&amp;quot; is used to store the deadline for each topic. The class “DueData” does exist, but it does not have column “topic_identifier” or “topic_name”. It only stores the deadline for a single assignment.&lt;br /&gt;
&lt;br /&gt;
=='''Puzzle'''==&lt;br /&gt;
* If there is more than one round, which means students can submit their assignments more than once, so the staggered-deadline should refer to which deadline?&lt;br /&gt;
'''[Professor]'''In a staggered-deadline assignment, there is one submission deadline and one review deadline per round.  These are always set on a per-topic basis.&lt;br /&gt;
If the view currently works (and I think it might), as soon as you make an assignment a staggered-deadline assignment, the Signup Sheet (Topics) page will have a link at the bottom to show deadlines for each topic.  Click it, and you will see a separate text box for each deadline for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* If staggered-deadline of one assignment is even later than the second-round review, is it means that that assignment do not need peer review and go directly into meta-review stage?&lt;br /&gt;
'''[Professor]'''No, there are also separate meta-review deadlines for a staggered-deadline assignment.&lt;br /&gt;
I think in the current implementation, only submission deadlines, review deadlines, and meta-review deadlines vary by topic.  In a more complete implementation, there would be a way for ANY deadline to vary by topic.  This would include signup deadlines, drop-topic deadlines, team-formation deadlines, and any other kind of deadline that is defined later.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* When to set staggered-deadline assignments? Create assignment or Before submission?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* What is the meaning of &amp;quot;dependencies&amp;quot; between topics?&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Szhang29</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96047</id>
		<title>CSC/ECE 517 Spring 2015 S1524 FSZZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96047"/>
		<updated>2015-03-30T19:48:05Z</updated>

		<summary type="html">&lt;p&gt;Szhang29: /* Initial Analyse */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1524. Refactor staggered-deadline assignments&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Overview'''==&lt;br /&gt;
===Introduction to Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
===Staggered Deadlines===&lt;br /&gt;
Staggered deadlines involve planning alternate submission dates for papers, projects, or exams when a student has conflicting due dates for these.  The key part of staggered deadlines is the planning. Staggered deadlines are always established well in advance of the scheduled due date. It is the advanced planning of these deadlines that makes them &amp;quot;staggered deadlines&amp;quot; rather than extensions&amp;lt;ref&amp;gt;[http://pages.vassar.edu/accessingvassar/2013/01/15/difficulties-with-staggered-deadlines/ Elmichaels. ''Difficulties with Staggered Deadlines''. Jan 15, 2013]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
==='''Background'''===&lt;br /&gt;
In this semester’s 517 class.  Wiki 1a and Wiki 1b are structured as separate assignments, with separate signup sheets, teams, and reviews.  But really, since only one of the two was done by any student, it would’ve been better to have a single assignment.  Still, some topics could be done soon after the course started, whereas others were better done after we had studied related topics in class.&lt;br /&gt;
&lt;br /&gt;
==='''Staggered-deadline Assignment'''===&lt;br /&gt;
This raises the idea of a ''staggered-deadline assignment'', where different topics have different submission and review deadlines, rather than all topics having the same deadline. &lt;br /&gt;
&lt;br /&gt;
==='''Benefit'''===&lt;br /&gt;
* '''Easy to manage.''' Because in the past, instructor has to build two separate assignments for Wiki 1a and 1b, now one assignment for Wiki is enough. &lt;br /&gt;
&lt;br /&gt;
* '''Increase flexibility.''' For instance, when an OSS team facing a much more difficult problem than other teams, instructor may postpone their deadline several days. It will make Expertiza more humanize.&lt;br /&gt;
&lt;br /&gt;
* '''Take time to do calibration.''' We find that two Wiki assignments started at Jan. 28th and ended at Feb. 25th, which takes too much time. And with staggered-deadline assignment, we can distribute less time on them. And we can take redundant time to do calibrating. Because we find that many students actually do not know how to evaluate other ones’ work, even there are some rubrics offered. So we recommend to let students grade sample assignments first, then calibrate their grading behaviors. Although it will take some time, we consider it is important to help students distinguish good assignments from common ones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Product Verion Functionality'''==&lt;br /&gt;
* In production version, instructor can set ''Submission deadline'', ''Review deadline'' and ''Metareview deadline'' for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments_M.png‎  |frame|center|Set different deadline for each topic]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Also, instructor can set the dependencies of different topics. And there is a dependency graph generated automatically.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments1_M.png‎  |frame|center|Dependency graph for all topics]]&lt;br /&gt;
&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Create staggered-deadline assignment'''&lt;br /&gt;
** '''Actor:''' Instructor&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** Instructor logs in Expertiza.&lt;br /&gt;
*** Instructor creates a new staggered-deadline assignment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Peer review only'''&lt;br /&gt;
** '''Actor:''' Student finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Hand in assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
*** Write author feedback to reviewer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Peer review and still work on assignments'''&lt;br /&gt;
** '''Actor:''' Student not finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Work on assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:UseCaseDiagram1_M.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=='''Error Message Present'''==&lt;br /&gt;
* First, login expertiza, in the “Manage Content” page, create a new assignment, for example, the name is “assignment 1b”. Then, as shown below, choose the first icon to edit this assignment.&lt;br /&gt;
[[File:assignment1.jpg |frame|center]]&lt;br /&gt;
* Select “Has topics?” and “Staggered deadline assignment?” box in General, and create new topics in Topics, save the properties.&lt;br /&gt;
[[File:assignment2.jpg |frame|center]]&lt;br /&gt;
* Back to the “Manage Content” page, this time choose the “Edit signup sheet” button.&lt;br /&gt;
[[File:assignment3.jpg |frame|center]]&lt;br /&gt;
* Then, it shows the error: can’t write unknown attribute ‘t_id’.&lt;br /&gt;
[[File:assignment4.jpg |frame|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Initial Analyse'''==&lt;br /&gt;
In “sign_up_sheet_controller”, there are several errors and confusions in function “add_sign_up_topic”. The function is used to displays a page that lists all the available topics for an assignment.&amp;lt;br&amp;gt; &lt;br /&gt;
See the function code below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_signup_topic&lt;br /&gt;
  load_add_signup_topics(params[:id])&lt;br /&gt;
&lt;br /&gt;
  @review_rounds = Assignment.find(params[:id]).get_review_rounds&lt;br /&gt;
  @topics = SignUpTopic.where(assignment_id: params[:id])&lt;br /&gt;
&lt;br /&gt;
  #Use this until you figure out how to initialize this array&lt;br /&gt;
  @duedates = SignUpTopic.find_by_sql(&amp;quot;SELECT s.id as topic_id FROM sign_up_topics s WHERE s.assignment_id = &amp;quot; + params[:id].to_s)&lt;br /&gt;
&lt;br /&gt;
  unless @topics.nil?&lt;br /&gt;
    i=0&lt;br /&gt;
    @topics.each { |topic|&lt;br /&gt;
&lt;br /&gt;
      @duedates[i]['t_id'] = topic.id&lt;br /&gt;
      @duedates[i]['topic_identifier'] = topic.topic_identifier&lt;br /&gt;
      @duedates[i]['topic_name'] = topic.topic_name&lt;br /&gt;
&lt;br /&gt;
      for j in 1..@review_rounds&lt;br /&gt;
        duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('submission').id).first&lt;br /&gt;
        duedate_rev = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('review').id).first&lt;br /&gt;
        if !duedate_subm.nil? &amp;amp;&amp;amp; !duedate_rev.nil?&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        else&lt;br /&gt;
          #the topic is new. so copy deadlines from assignment&lt;br /&gt;
          set_of_due_dates = DueDate.where(assignment_id: params[:id])&lt;br /&gt;
          set_of_due_dates.each { |due_date|&lt;br /&gt;
            create_topic_deadline(due_date, 0, topic.id)&lt;br /&gt;
          }&lt;br /&gt;
&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
      end&lt;br /&gt;
      duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('metareview').id).first&lt;br /&gt;
      @duedates[i]['submission_'+ (@review_rounds+1).to_s] = !(duedate_subm.nil?)?(DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)):nil&lt;br /&gt;
      i = i + 1&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The main confusions are:&lt;br /&gt;
* In line 8, the variable &amp;quot;duedates&amp;quot; are declared as type &amp;quot;SignUpTopic&amp;quot;. The naming is quite confusing.&lt;br /&gt;
* In line 14, the SignUpTopic class doesn’t have a column “t_id”, it raises an error. &lt;br /&gt;
* From the code we can guess the variable &amp;quot;duedates&amp;quot; is used to store the deadline for each topic. The class “DueData” does exist, but it does not have column “topic_identifier” or “topic_name”. It only stores the deadline for a single assignment.&lt;br /&gt;
&lt;br /&gt;
=='''Puzzle'''==&lt;br /&gt;
* If there is more than one round, which means students can submit their assignments more than once, so the staggered-deadline should refer to which deadline?&lt;br /&gt;
'''[Professor]'''In a staggered-deadline assignment, there is one submission deadline and one review deadline per round.  These are always set on a per-topic basis.&lt;br /&gt;
If the view currently works (and I think it might), as soon as you make an assignment a staggered-deadline assignment, the Signup Sheet (Topics) page will have a link at the bottom to show deadlines for each topic.  Click it, and you will see a separate text box for each deadline for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* If staggered-deadline of one assignment is even later than the second-round review, is it means that that assignment do not need peer review and go directly into meta-review stage?&lt;br /&gt;
'''[Professor]'''No, there are also separate meta-review deadlines for a staggered-deadline assignment.&lt;br /&gt;
I think in the current implementation, only submission deadlines, review deadlines, and meta-review deadlines vary by topic.  In a more complete implementation, there would be a way for ANY deadline to vary by topic.  This would include signup deadlines, drop-topic deadlines, team-formation deadlines, and any other kind of deadline that is defined later.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* When to set staggered-deadline assignments? Create assignment or Before submission?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* What is the meaning of &amp;quot;dependencies&amp;quot; between topics?&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Szhang29</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96046</id>
		<title>CSC/ECE 517 Spring 2015 S1524 FSZZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96046"/>
		<updated>2015-03-30T19:47:29Z</updated>

		<summary type="html">&lt;p&gt;Szhang29: /* Initial Analyse */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1524. Refactor staggered-deadline assignments&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Overview'''==&lt;br /&gt;
===Introduction to Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
===Staggered Deadlines===&lt;br /&gt;
Staggered deadlines involve planning alternate submission dates for papers, projects, or exams when a student has conflicting due dates for these.  The key part of staggered deadlines is the planning. Staggered deadlines are always established well in advance of the scheduled due date. It is the advanced planning of these deadlines that makes them &amp;quot;staggered deadlines&amp;quot; rather than extensions&amp;lt;ref&amp;gt;[http://pages.vassar.edu/accessingvassar/2013/01/15/difficulties-with-staggered-deadlines/ Elmichaels. ''Difficulties with Staggered Deadlines''. Jan 15, 2013]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
==='''Background'''===&lt;br /&gt;
In this semester’s 517 class.  Wiki 1a and Wiki 1b are structured as separate assignments, with separate signup sheets, teams, and reviews.  But really, since only one of the two was done by any student, it would’ve been better to have a single assignment.  Still, some topics could be done soon after the course started, whereas others were better done after we had studied related topics in class.&lt;br /&gt;
&lt;br /&gt;
==='''Staggered-deadline Assignment'''===&lt;br /&gt;
This raises the idea of a ''staggered-deadline assignment'', where different topics have different submission and review deadlines, rather than all topics having the same deadline. &lt;br /&gt;
&lt;br /&gt;
==='''Benefit'''===&lt;br /&gt;
* '''Easy to manage.''' Because in the past, instructor has to build two separate assignments for Wiki 1a and 1b, now one assignment for Wiki is enough. &lt;br /&gt;
&lt;br /&gt;
* '''Increase flexibility.''' For instance, when an OSS team facing a much more difficult problem than other teams, instructor may postpone their deadline several days. It will make Expertiza more humanize.&lt;br /&gt;
&lt;br /&gt;
* '''Take time to do calibration.''' We find that two Wiki assignments started at Jan. 28th and ended at Feb. 25th, which takes too much time. And with staggered-deadline assignment, we can distribute less time on them. And we can take redundant time to do calibrating. Because we find that many students actually do not know how to evaluate other ones’ work, even there are some rubrics offered. So we recommend to let students grade sample assignments first, then calibrate their grading behaviors. Although it will take some time, we consider it is important to help students distinguish good assignments from common ones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Product Verion Functionality'''==&lt;br /&gt;
* In production version, instructor can set ''Submission deadline'', ''Review deadline'' and ''Metareview deadline'' for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments_M.png‎  |frame|center|Set different deadline for each topic]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Also, instructor can set the dependencies of different topics. And there is a dependency graph generated automatically.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments1_M.png‎  |frame|center|Dependency graph for all topics]]&lt;br /&gt;
&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Create staggered-deadline assignment'''&lt;br /&gt;
** '''Actor:''' Instructor&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** Instructor logs in Expertiza.&lt;br /&gt;
*** Instructor creates a new staggered-deadline assignment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Peer review only'''&lt;br /&gt;
** '''Actor:''' Student finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Hand in assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
*** Write author feedback to reviewer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Peer review and still work on assignments'''&lt;br /&gt;
** '''Actor:''' Student not finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Work on assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:UseCaseDiagram1_M.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=='''Error Message Present'''==&lt;br /&gt;
* First, login expertiza, in the “Manage Content” page, create a new assignment, for example, the name is “assignment 1b”. Then, as shown below, choose the first icon to edit this assignment.&lt;br /&gt;
[[File:assignment1.jpg |frame|center]]&lt;br /&gt;
* Select “Has topics?” and “Staggered deadline assignment?” box in General, and create new topics in Topics, save the properties.&lt;br /&gt;
[[File:assignment2.jpg |frame|center]]&lt;br /&gt;
* Back to the “Manage Content” page, this time choose the “Edit signup sheet” button.&lt;br /&gt;
[[File:assignment3.jpg |frame|center]]&lt;br /&gt;
* Then, it shows the error: can’t write unknown attribute ‘t_id’.&lt;br /&gt;
[[File:assignment4.jpg |frame|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Initial Analyse'''==&lt;br /&gt;
In “sign_up_sheet_controller”, there are several errors and confusions in function “add_sign_up_topic”. The function is used to displays a page that lists all the available topics for an assignment. The codes are listed below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_signup_topic&lt;br /&gt;
  load_add_signup_topics(params[:id])&lt;br /&gt;
&lt;br /&gt;
  @review_rounds = Assignment.find(params[:id]).get_review_rounds&lt;br /&gt;
  @topics = SignUpTopic.where(assignment_id: params[:id])&lt;br /&gt;
&lt;br /&gt;
  #Use this until you figure out how to initialize this array&lt;br /&gt;
  @duedates = SignUpTopic.find_by_sql(&amp;quot;SELECT s.id as topic_id FROM sign_up_topics s WHERE s.assignment_id = &amp;quot; + params[:id].to_s)&lt;br /&gt;
&lt;br /&gt;
  unless @topics.nil?&lt;br /&gt;
    i=0&lt;br /&gt;
    @topics.each { |topic|&lt;br /&gt;
&lt;br /&gt;
      @duedates[i]['t_id'] = topic.id&lt;br /&gt;
      @duedates[i]['topic_identifier'] = topic.topic_identifier&lt;br /&gt;
      @duedates[i]['topic_name'] = topic.topic_name&lt;br /&gt;
&lt;br /&gt;
      for j in 1..@review_rounds&lt;br /&gt;
        duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('submission').id).first&lt;br /&gt;
        duedate_rev = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('review').id).first&lt;br /&gt;
        if !duedate_subm.nil? &amp;amp;&amp;amp; !duedate_rev.nil?&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        else&lt;br /&gt;
          #the topic is new. so copy deadlines from assignment&lt;br /&gt;
          set_of_due_dates = DueDate.where(assignment_id: params[:id])&lt;br /&gt;
          set_of_due_dates.each { |due_date|&lt;br /&gt;
            create_topic_deadline(due_date, 0, topic.id)&lt;br /&gt;
          }&lt;br /&gt;
&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
      end&lt;br /&gt;
      duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('metareview').id).first&lt;br /&gt;
      @duedates[i]['submission_'+ (@review_rounds+1).to_s] = !(duedate_subm.nil?)?(DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)):nil&lt;br /&gt;
      i = i + 1&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The main confusions are:&lt;br /&gt;
* In line 8, the variable &amp;quot;duedates&amp;quot; are declared as type &amp;quot;SignUpTopic&amp;quot;. The naming is quite confusing.&lt;br /&gt;
* In line 14, the SignUpTopic class doesn’t have a column “t_id”, it raises an error. &lt;br /&gt;
* From the code we can guess the variable &amp;quot;duedates&amp;quot; is used to store the deadline for each topic. The class “DueData” does exist, but it does not have column “topic_identifier” or “topic_name”. It only stores the deadline for a single assignment.&lt;br /&gt;
&lt;br /&gt;
=='''Puzzle'''==&lt;br /&gt;
* If there is more than one round, which means students can submit their assignments more than once, so the staggered-deadline should refer to which deadline?&lt;br /&gt;
'''[Professor]'''In a staggered-deadline assignment, there is one submission deadline and one review deadline per round.  These are always set on a per-topic basis.&lt;br /&gt;
If the view currently works (and I think it might), as soon as you make an assignment a staggered-deadline assignment, the Signup Sheet (Topics) page will have a link at the bottom to show deadlines for each topic.  Click it, and you will see a separate text box for each deadline for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* If staggered-deadline of one assignment is even later than the second-round review, is it means that that assignment do not need peer review and go directly into meta-review stage?&lt;br /&gt;
'''[Professor]'''No, there are also separate meta-review deadlines for a staggered-deadline assignment.&lt;br /&gt;
I think in the current implementation, only submission deadlines, review deadlines, and meta-review deadlines vary by topic.  In a more complete implementation, there would be a way for ANY deadline to vary by topic.  This would include signup deadlines, drop-topic deadlines, team-formation deadlines, and any other kind of deadline that is defined later.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* When to set staggered-deadline assignments? Create assignment or Before submission?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* What is the meaning of &amp;quot;dependencies&amp;quot; between topics?&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Szhang29</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96045</id>
		<title>CSC/ECE 517 Spring 2015 S1524 FSZZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96045"/>
		<updated>2015-03-30T19:44:10Z</updated>

		<summary type="html">&lt;p&gt;Szhang29: /* Initial Analyse */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1524. Refactor staggered-deadline assignments&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Overview'''==&lt;br /&gt;
===Introduction to Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
===Staggered Deadlines===&lt;br /&gt;
Staggered deadlines involve planning alternate submission dates for papers, projects, or exams when a student has conflicting due dates for these.  The key part of staggered deadlines is the planning. Staggered deadlines are always established well in advance of the scheduled due date. It is the advanced planning of these deadlines that makes them &amp;quot;staggered deadlines&amp;quot; rather than extensions&amp;lt;ref&amp;gt;[http://pages.vassar.edu/accessingvassar/2013/01/15/difficulties-with-staggered-deadlines/ Elmichaels. ''Difficulties with Staggered Deadlines''. Jan 15, 2013]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
==='''Background'''===&lt;br /&gt;
In this semester’s 517 class.  Wiki 1a and Wiki 1b are structured as separate assignments, with separate signup sheets, teams, and reviews.  But really, since only one of the two was done by any student, it would’ve been better to have a single assignment.  Still, some topics could be done soon after the course started, whereas others were better done after we had studied related topics in class.&lt;br /&gt;
&lt;br /&gt;
==='''Staggered-deadline Assignment'''===&lt;br /&gt;
This raises the idea of a ''staggered-deadline assignment'', where different topics have different submission and review deadlines, rather than all topics having the same deadline. &lt;br /&gt;
&lt;br /&gt;
==='''Benefit'''===&lt;br /&gt;
* '''Easy to manage.''' Because in the past, instructor has to build two separate assignments for Wiki 1a and 1b, now one assignment for Wiki is enough. &lt;br /&gt;
&lt;br /&gt;
* '''Increase flexibility.''' For instance, when an OSS team facing a much more difficult problem than other teams, instructor may postpone their deadline several days. It will make Expertiza more humanize.&lt;br /&gt;
&lt;br /&gt;
* '''Take time to do calibration.''' We find that two Wiki assignments started at Jan. 28th and ended at Feb. 25th, which takes too much time. And with staggered-deadline assignment, we can distribute less time on them. And we can take redundant time to do calibrating. Because we find that many students actually do not know how to evaluate other ones’ work, even there are some rubrics offered. So we recommend to let students grade sample assignments first, then calibrate their grading behaviors. Although it will take some time, we consider it is important to help students distinguish good assignments from common ones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Product Verion Functionality'''==&lt;br /&gt;
* In production version, instructor can set ''Submission deadline'', ''Review deadline'' and ''Metareview deadline'' for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments_M.png‎  |frame|center|Set different deadline for each topic]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Also, instructor can set the dependencies of different topics. And there is a dependency graph generated automatically.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments1_M.png‎  |frame|center|Dependency graph for all topics]]&lt;br /&gt;
&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Create staggered-deadline assignment'''&lt;br /&gt;
** '''Actor:''' Instructor&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** Instructor logs in Expertiza.&lt;br /&gt;
*** Instructor creates a new staggered-deadline assignment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Peer review only'''&lt;br /&gt;
** '''Actor:''' Student finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Hand in assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
*** Write author feedback to reviewer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Peer review and still work on assignments'''&lt;br /&gt;
** '''Actor:''' Student not finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Work on assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:UseCaseDiagram1_M.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=='''Error Message Present'''==&lt;br /&gt;
* First, login expertiza, in the “Manage Content” page, create a new assignment, for example, the name is “assignment 1b”. Then, as shown below, choose the first icon to edit this assignment.&lt;br /&gt;
[[File:assignment1.jpg |frame|center]]&lt;br /&gt;
* Select “Has topics?” and “Staggered deadline assignment?” box in General, and create new topics in Topics, save the properties.&lt;br /&gt;
[[File:assignment2.jpg |frame|center]]&lt;br /&gt;
* Back to the “Manage Content” page, this time choose the “Edit signup sheet” button.&lt;br /&gt;
[[File:assignment3.jpg |frame|center]]&lt;br /&gt;
* Then, it shows the error: can’t write unknown attribute ‘t_id’.&lt;br /&gt;
[[File:assignment4.jpg |frame|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Initial Analyse'''==&lt;br /&gt;
In “sign_up_sheet_controller”, there are several errors and confusions in function “add_sign_up_topic”. See this function below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_signup_topic&lt;br /&gt;
  load_add_signup_topics(params[:id])&lt;br /&gt;
&lt;br /&gt;
  @review_rounds = Assignment.find(params[:id]).get_review_rounds&lt;br /&gt;
  @topics = SignUpTopic.where(assignment_id: params[:id])&lt;br /&gt;
&lt;br /&gt;
  #Use this until you figure out how to initialize this array&lt;br /&gt;
  @duedates = SignUpTopic.find_by_sql(&amp;quot;SELECT s.id as topic_id FROM sign_up_topics s WHERE s.assignment_id = &amp;quot; + params[:id].to_s)&lt;br /&gt;
&lt;br /&gt;
  unless @topics.nil?&lt;br /&gt;
    i=0&lt;br /&gt;
    @topics.each { |topic|&lt;br /&gt;
&lt;br /&gt;
      @duedates[i]['t_id'] = topic.id&lt;br /&gt;
      @duedates[i]['topic_identifier'] = topic.topic_identifier&lt;br /&gt;
      @duedates[i]['topic_name'] = topic.topic_name&lt;br /&gt;
&lt;br /&gt;
      for j in 1..@review_rounds&lt;br /&gt;
        duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('submission').id).first&lt;br /&gt;
        duedate_rev = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('review').id).first&lt;br /&gt;
        if !duedate_subm.nil? &amp;amp;&amp;amp; !duedate_rev.nil?&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        else&lt;br /&gt;
          #the topic is new. so copy deadlines from assignment&lt;br /&gt;
          set_of_due_dates = DueDate.where(assignment_id: params[:id])&lt;br /&gt;
          set_of_due_dates.each { |due_date|&lt;br /&gt;
            create_topic_deadline(due_date, 0, topic.id)&lt;br /&gt;
          }&lt;br /&gt;
&lt;br /&gt;
          @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
          @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
      end&lt;br /&gt;
      duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('metareview').id).first&lt;br /&gt;
      @duedates[i]['submission_'+ (@review_rounds+1).to_s] = !(duedate_subm.nil?)?(DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)):nil&lt;br /&gt;
      i = i + 1&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The main confusions are:&lt;br /&gt;
* In line 8, the variable &amp;quot;duedates&amp;quot; are declared as type &amp;quot;SignUpTopic&amp;quot;. The naming is quite confusing.&lt;br /&gt;
* In line 14, the SignUpTopic class doesn’t have a column “t_id”, it raises an error. &lt;br /&gt;
* From the code we can guess the variable &amp;quot;duedates&amp;quot; is used to store the deadline for each topic. The class “DueData” does exist, but it does not have column “topic_identifier” or “topic_name”. It only stores the deadline for a single assignment.&lt;br /&gt;
&lt;br /&gt;
=='''Puzzle'''==&lt;br /&gt;
* If there is more than one round, which means students can submit their assignments more than once, so the staggered-deadline should refer to which deadline?&lt;br /&gt;
'''[Professor]'''In a staggered-deadline assignment, there is one submission deadline and one review deadline per round.  These are always set on a per-topic basis.&lt;br /&gt;
If the view currently works (and I think it might), as soon as you make an assignment a staggered-deadline assignment, the Signup Sheet (Topics) page will have a link at the bottom to show deadlines for each topic.  Click it, and you will see a separate text box for each deadline for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* If staggered-deadline of one assignment is even later than the second-round review, is it means that that assignment do not need peer review and go directly into meta-review stage?&lt;br /&gt;
'''[Professor]'''No, there are also separate meta-review deadlines for a staggered-deadline assignment.&lt;br /&gt;
I think in the current implementation, only submission deadlines, review deadlines, and meta-review deadlines vary by topic.  In a more complete implementation, there would be a way for ANY deadline to vary by topic.  This would include signup deadlines, drop-topic deadlines, team-formation deadlines, and any other kind of deadline that is defined later.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* When to set staggered-deadline assignments? Create assignment or Before submission?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* What is the meaning of &amp;quot;dependencies&amp;quot; between topics?&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Szhang29</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96044</id>
		<title>CSC/ECE 517 Spring 2015 S1524 FSZZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_S1524_FSZZ&amp;diff=96044"/>
		<updated>2015-03-30T19:41:29Z</updated>

		<summary type="html">&lt;p&gt;Szhang29: /* Initial Analyse */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1524. Refactor staggered-deadline assignments&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Overview'''==&lt;br /&gt;
===Introduction to Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
===Staggered Deadlines===&lt;br /&gt;
Staggered deadlines involve planning alternate submission dates for papers, projects, or exams when a student has conflicting due dates for these.  The key part of staggered deadlines is the planning. Staggered deadlines are always established well in advance of the scheduled due date. It is the advanced planning of these deadlines that makes them &amp;quot;staggered deadlines&amp;quot; rather than extensions&amp;lt;ref&amp;gt;[http://pages.vassar.edu/accessingvassar/2013/01/15/difficulties-with-staggered-deadlines/ Elmichaels. ''Difficulties with Staggered Deadlines''. Jan 15, 2013]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
==='''Background'''===&lt;br /&gt;
In this semester’s 517 class.  Wiki 1a and Wiki 1b are structured as separate assignments, with separate signup sheets, teams, and reviews.  But really, since only one of the two was done by any student, it would’ve been better to have a single assignment.  Still, some topics could be done soon after the course started, whereas others were better done after we had studied related topics in class.&lt;br /&gt;
&lt;br /&gt;
==='''Staggered-deadline Assignment'''===&lt;br /&gt;
This raises the idea of a ''staggered-deadline assignment'', where different topics have different submission and review deadlines, rather than all topics having the same deadline. &lt;br /&gt;
&lt;br /&gt;
==='''Benefit'''===&lt;br /&gt;
* '''Easy to manage.''' Because in the past, instructor has to build two separate assignments for Wiki 1a and 1b, now one assignment for Wiki is enough. &lt;br /&gt;
&lt;br /&gt;
* '''Increase flexibility.''' For instance, when an OSS team facing a much more difficult problem than other teams, instructor may postpone their deadline several days. It will make Expertiza more humanize.&lt;br /&gt;
&lt;br /&gt;
* '''Take time to do calibration.''' We find that two Wiki assignments started at Jan. 28th and ended at Feb. 25th, which takes too much time. And with staggered-deadline assignment, we can distribute less time on them. And we can take redundant time to do calibrating. Because we find that many students actually do not know how to evaluate other ones’ work, even there are some rubrics offered. So we recommend to let students grade sample assignments first, then calibrate their grading behaviors. Although it will take some time, we consider it is important to help students distinguish good assignments from common ones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Product Verion Functionality'''==&lt;br /&gt;
* In production version, instructor can set ''Submission deadline'', ''Review deadline'' and ''Metareview deadline'' for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments_M.png‎  |frame|center|Set different deadline for each topic]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Also, instructor can set the dependencies of different topics. And there is a dependency graph generated automatically.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Staggered-deadline_assignments1_M.png‎  |frame|center|Dependency graph for all topics]]&lt;br /&gt;
&lt;br /&gt;
=='''Use Case'''==&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #1: Create staggered-deadline assignment'''&lt;br /&gt;
** '''Actor:''' Instructor&lt;br /&gt;
** '''Actions:''' &lt;br /&gt;
*** Instructor logs in Expertiza.&lt;br /&gt;
*** Instructor creates a new staggered-deadline assignment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #2: Peer review only'''&lt;br /&gt;
** '''Actor:''' Student finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Hand in assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
*** Write author feedback to reviewer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Use Case #3: Peer review and still work on assignments'''&lt;br /&gt;
** '''Actor:''' Student not finish work for first round&lt;br /&gt;
** '''Actions:'''&lt;br /&gt;
*** Sign up topic.&lt;br /&gt;
*** Work on assignment.&lt;br /&gt;
*** Peer review.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:UseCaseDiagram1_M.png‎  |frame|center|Use Case Diagram]]&lt;br /&gt;
&lt;br /&gt;
=='''Error Message Present'''==&lt;br /&gt;
* First, login expertiza, in the “Manage Content” page, create a new assignment, for example, the name is “assignment 1b”. Then, as shown below, choose the first icon to edit this assignment.&lt;br /&gt;
[[File:assignment1.jpg |frame|center]]&lt;br /&gt;
* Select “Has topics?” and “Staggered deadline assignment?” box in General, and create new topics in Topics, save the properties.&lt;br /&gt;
[[File:assignment2.jpg |frame|center]]&lt;br /&gt;
* Back to the “Manage Content” page, this time choose the “Edit signup sheet” button.&lt;br /&gt;
[[File:assignment3.jpg |frame|center]]&lt;br /&gt;
* Then, it shows the error: can’t write unknown attribute ‘t_id’.&lt;br /&gt;
[[File:assignment4.jpg |frame|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Initial Analyse'''==&lt;br /&gt;
In “sign_up_sheet_controller”, there are several errors and confusions in function “add_sign_up_topic”. See this function below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_signup_topic&lt;br /&gt;
      load_add_signup_topics(params[:id])&lt;br /&gt;
&lt;br /&gt;
      @review_rounds = Assignment.find(params[:id]).get_review_rounds&lt;br /&gt;
      @topics = SignUpTopic.where(assignment_id: params[:id])&lt;br /&gt;
&lt;br /&gt;
      #Use this until you figure out how to initialize this array&lt;br /&gt;
      @duedates = SignUpTopic.find_by_sql(&amp;quot;SELECT s.id as topic_id FROM sign_up_topics s WHERE s.assignment_id = &amp;quot; + params[:id].to_s)&lt;br /&gt;
&lt;br /&gt;
      unless @topics.nil?&lt;br /&gt;
        i=0&lt;br /&gt;
        @topics.each { |topic|&lt;br /&gt;
&lt;br /&gt;
          @duedates[i]['t_id'] = topic.id&lt;br /&gt;
          @duedates[i]['topic_identifier'] = topic.topic_identifier&lt;br /&gt;
          @duedates[i]['topic_name'] = topic.topic_name&lt;br /&gt;
&lt;br /&gt;
          for j in 1..@review_rounds&lt;br /&gt;
            duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('submission').id).first&lt;br /&gt;
            duedate_rev = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('review').id).first&lt;br /&gt;
            if !duedate_subm.nil? &amp;amp;&amp;amp; !duedate_rev.nil?&lt;br /&gt;
              @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
              @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
            else&lt;br /&gt;
              #the topic is new. so copy deadlines from assignment&lt;br /&gt;
              set_of_due_dates = DueDate.where(assignment_id: params[:id])&lt;br /&gt;
              set_of_due_dates.each { |due_date|&lt;br /&gt;
                create_topic_deadline(due_date, 0, topic.id)&lt;br /&gt;
              }&lt;br /&gt;
&lt;br /&gt;
              @duedates[i]['submission_'+ j.to_s] = DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
              @duedates[i]['review_'+ j.to_s] = DateTime.parse(duedate_rev['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
            end&lt;br /&gt;
&lt;br /&gt;
          end&lt;br /&gt;
          duedate_subm = TopicDeadline.where(topic_id: topic.id, deadline_type_id:  DeadlineType.find_by_name('metareview').id).first&lt;br /&gt;
          @duedates[i]['submission_'+ (@review_rounds+1).to_s] = !(duedate_subm.nil?)?(DateTime.parse(duedate_subm['due_at'].to_s).strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)):nil&lt;br /&gt;
          i = i + 1&lt;br /&gt;
        }&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The main confusions are:&lt;br /&gt;
* In line 8, the variable &amp;quot;duedates&amp;quot; are declared as type &amp;quot;SignUpTopic&amp;quot;. The naming is quite confusing.&lt;br /&gt;
* In line 14, the SignUpTopic class doesn’t have a column “t_id”, it raises an error. &lt;br /&gt;
* From the code we can guess the variable &amp;quot;duedates&amp;quot; is used to store the deadline for each topic. The class “DueData” does exist, but it does not have column “topic_identifier” or “topic_name”. It only stores the deadline for a single assignment.&lt;br /&gt;
&lt;br /&gt;
=='''Puzzle'''==&lt;br /&gt;
* If there is more than one round, which means students can submit their assignments more than once, so the staggered-deadline should refer to which deadline?&lt;br /&gt;
'''[Professor]'''In a staggered-deadline assignment, there is one submission deadline and one review deadline per round.  These are always set on a per-topic basis.&lt;br /&gt;
If the view currently works (and I think it might), as soon as you make an assignment a staggered-deadline assignment, the Signup Sheet (Topics) page will have a link at the bottom to show deadlines for each topic.  Click it, and you will see a separate text box for each deadline for each topic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* If staggered-deadline of one assignment is even later than the second-round review, is it means that that assignment do not need peer review and go directly into meta-review stage?&lt;br /&gt;
'''[Professor]'''No, there are also separate meta-review deadlines for a staggered-deadline assignment.&lt;br /&gt;
I think in the current implementation, only submission deadlines, review deadlines, and meta-review deadlines vary by topic.  In a more complete implementation, there would be a way for ANY deadline to vary by topic.  This would include signup deadlines, drop-topic deadlines, team-formation deadlines, and any other kind of deadline that is defined later.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* When to set staggered-deadline assignments? Create assignment or Before submission?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* What is the meaning of &amp;quot;dependencies&amp;quot; between topics?&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Szhang29</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/oss_E1506_SYZ&amp;diff=95323</id>
		<title>CSC/ECE 517 Spring 2015/oss E1506 SYZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/oss_E1506_SYZ&amp;diff=95323"/>
		<updated>2015-03-22T06:37:41Z</updated>

		<summary type="html">&lt;p&gt;Szhang29: /* Refactor the “paginate_list” method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1506: Refactoring, testing and new features related to “users”&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Overview'''==&lt;br /&gt;
===Code refactoring===&lt;br /&gt;
''Refactoring'' is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior&amp;lt;ref&amp;gt;[http://refactoring.com/ Refactoring]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Refactoring adds to the value of any program that has at least one of the following shortcomings&amp;lt;ref&amp;gt;[http://jexp.de/papers/refactoring/refactoring/node9.html#SECTION00330000000000000000 Benefits of Code Refactoring] Michael Hunger. Oct. 25, 2000&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
* Programs that are hard to read are hard to modify;&lt;br /&gt;
* Programs that have duplicate logic are hard to modify;&lt;br /&gt;
* Programs that require additional behavior that requires you to change running code are hard to modify;&lt;br /&gt;
* Programs with complex conditional logic are hard to modify.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Rspec===&lt;br /&gt;
RSpec is a [http://en.wikipedia.org/wiki/Behavior-driven_development behavior-driven development] (BDD) framework for the [http://en.wikipedia.org/wiki/Ruby_(programming_language) Ruby programming language], inspired by JBehave. It contains its own mocking framework that is fully integrated into the framework based upon JMock. The framework can be considered a [http://en.wikipedia.org/wiki/Domain-specific_language domain-specific language] (DSL) and resembles a natural language specification&amp;lt;ref&amp;gt;[http://en.wikipedia.org/wiki/RSpec#cite_note-origin-4g Rspec]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Object-oriented Design Principles===&lt;br /&gt;
Object-oriented programming (OOP) is a programming language model organized around objects rather than &amp;quot;actions&amp;quot; and data rather than logic&amp;lt;ref&amp;gt;[http://searchsoa.techtarget.com/definition/object-oriented-programming Margaret Rouse. ''object-oriented programming (OOP) definition''. Aug 3, 2008]&amp;lt;/ref&amp;gt;. Historically, a program has been viewed as a logical procedure that takes input data, processes it, and produces output data. Though an Object oriented language provides us with highly useful and important programming concepts like '''Inheritance''', '''Polymorphism''', '''Abstraction''' and '''Encapsulation''' which definitely makes the code more efficient, it is equally important to have the knowledge of using them in the code. &lt;br /&gt;
''Object Oriented Design'' Principles are core of OOPS programming&amp;lt;ref&amp;gt;[http://javarevisited.blogspot.com/2012/03/10-object-oriented-design-principles.html#ixzz3Ha8L3cfz Javin Paul. ''Blogspot''. March 3, 2012]&amp;lt;/ref&amp;gt;. It is important to know these design principles, to create clean and modular design. There are many design principles that help us to create clean and efficient code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=='''Project Resources'''==&lt;br /&gt;
* [https://github.com/CSC517-Proj2-E1506/expertiza GitHub Repository]&lt;br /&gt;
* [http://152.46.16.178:3001/ VCL IP] (Log in as user2/password. Go to [http://152.46.16.178:3001/analytic/index VCL analytic page])&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/505 GitHub Pull Request Link]&lt;br /&gt;
&lt;br /&gt;
=='''Todo List'''==&lt;br /&gt;
&amp;lt;b&amp;gt;Related files:&amp;lt;/b&amp;gt; users_controller.rb, participants_controller.rb, user.rb, users/show.html.erb&lt;br /&gt;
*  Find the un-called methods if any and delete them. &amp;lt;b&amp;gt;[done]&amp;lt;/b&amp;gt;&lt;br /&gt;
*  Change the Rails 2 syntax to Rails 4 style.&lt;br /&gt;
*  Refactor users_controller.rb&lt;br /&gt;
** Change the white space for the second harf of this file, starts at “def edit”. &amp;lt;b&amp;gt;[done]&amp;lt;/b&amp;gt;&lt;br /&gt;
** Separate the “paginate_list” method into two methods. The search method should be in model and the paginating method should be in the controller.  &amp;lt;b&amp;gt;[done]&amp;lt;/b&amp;gt;&lt;br /&gt;
* New feature: delete users&lt;br /&gt;
** A user can be deleted if (s)he has not participated in an assignment. &amp;lt;b&amp;gt;[done]&amp;lt;/b&amp;gt;&lt;br /&gt;
** If the user is participating in an assignment, the system will ask, “User is participating in k assignments.  Delete as a participant in these assignment(s)?”  &amp;lt;b&amp;gt;[done]&amp;lt;/b&amp;gt;&lt;br /&gt;
** If the user has submitted or reviewed in any of these assignments, the system will say the user cannot be deleted, but offer to rename the user account to &amp;lt;current_account_name&amp;gt;_hidden.&lt;br /&gt;
*** rename (javascript calling update method in users_controller.rb) &amp;lt;b&amp;gt;[done]&amp;lt;/b&amp;gt;&lt;br /&gt;
*** different users have different delete methods.  &amp;lt;b&amp;gt;[done]&amp;lt;/b&amp;gt;&lt;br /&gt;
** If the person trying to delete does not want to rename the account, the system will just say that the user can’t be deleted. &amp;lt;b&amp;gt;[done]&amp;lt;/b&amp;gt;&lt;br /&gt;
** Write tests (with Rspec) for this feature.&amp;lt;b&amp;gt;[done]&amp;lt;/b&amp;gt;&lt;br /&gt;
* Testing feature: search for users&lt;br /&gt;
** In rails 4 branch, admins can search for the users with 1) users’ login names 2) users’ last or first names and 3) users’ emails. Please write tests (with Rspec) for this feature &amp;lt;b&amp;gt;[done]&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Delete Uncalled Methods'''==&lt;br /&gt;
&lt;br /&gt;
==='''Method'''===&lt;br /&gt;
&lt;br /&gt;
* The primary way we find unused method is right-click on each method's name, then choose &amp;quot;Find Usages&amp;quot;, as the following picture shows:&lt;br /&gt;
[[File:FindUsages.PNG  |frame|center|Delete confirm box]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Then the finding results will be displayed in the bottom, as the following picture shows:&lt;br /&gt;
[[File:FindResult.PNG  |frame|center|Delete confirm box]]&lt;br /&gt;
&lt;br /&gt;
==='''Implementation'''===&lt;br /&gt;
&lt;br /&gt;
* In this way we identified the following method from '''''UserController.rb''''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.participants_in(assignment_id)&lt;br /&gt;
 users = Array.new&lt;br /&gt;
 participants = AssignmentParticipant.find_by_parent_id(assignment_id)&lt;br /&gt;
 participants.each{&lt;br /&gt;
   |participant|&lt;br /&gt;
   users &amp;lt;&amp;lt; User.find(participant.user_id)&lt;br /&gt;
 }&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* And the following methods from '''''User.rb'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def assign_random_password&lt;br /&gt;
 if self.password.blank?&lt;br /&gt;
   self.password = self.random_password&lt;br /&gt;
 end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def self.random_password(size=8)&lt;br /&gt;
 random_pronouncable_password((size/2).round) + rand.to_s[2,3]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def get_author_name&lt;br /&gt;
 return self.fullname&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* There's one method '''''salt_first''''' in '''''User.rb''''' cannot be deleted. Salt is a small chunk of random data to the password before it's hashed. The salt is then stored along with the hash in the database, and used to check potentially valid passwords&amp;lt;ref&amp;gt;[https://github.com/codahale/bcrypt-ruby Salt]&amp;lt;/ref&amp;gt;. Here's the function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def salt_first?&lt;br /&gt;
    true&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Change Rails 2 syntax to Rails 4'''==&lt;br /&gt;
&amp;lt;b&amp;gt;'''with_scope'''&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Refactor users_controller.rb'''==&lt;br /&gt;
===='''Refactor the “paginate_list” method'''====&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;paginate_list&amp;quot; method is a function in &amp;quot;users_controller.rb&amp;quot;. It will be called if you do search in Manage-&amp;gt;Users page. It has two components: search for users, paginate the results.&lt;br /&gt;
&lt;br /&gt;
However, the controller should not know how the information is retrieved. So we would like to refactor this method by seperating it into search method and paginating method. The search method is in model and the paginating method is still in controller.&lt;br /&gt;
&lt;br /&gt;
The code below is the &amp;quot;paginate_list&amp;quot; method in official Expertiza:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# For filtering the users list with proper search and pagination.&lt;br /&gt;
def paginate_list(role, user_id, letter)&lt;br /&gt;
  paginate_options = {&amp;quot;1&amp;quot; =&amp;gt; 25, &amp;quot;2&amp;quot; =&amp;gt; 50, &amp;quot;3&amp;quot; =&amp;gt; 100}&lt;br /&gt;
&lt;br /&gt;
  # If the above hash does not have a value for the key,&lt;br /&gt;
  # it means that we need to show all the users on the page&lt;br /&gt;
  #&lt;br /&gt;
  # Just a point to remember, when we use pagination, the&lt;br /&gt;
  # 'users' variable should be an object, not an array&lt;br /&gt;
&lt;br /&gt;
  #The type of condition for the search depends on what the user has selected from the search_by dropdown&lt;br /&gt;
  condition = &amp;quot;(role_id in (?) or id = ?) and name like ?&amp;quot; #default used when clicking on letters&lt;br /&gt;
  search_filter = letter + '%'&lt;br /&gt;
  @search_by = params[:search_by]&lt;br /&gt;
  if @search_by == '1'  #search by user name&lt;br /&gt;
    condition = &amp;quot;(role_id in (?) or id = ?) and name like ?&amp;quot;&lt;br /&gt;
    search_filter = '%' + letter + '%'&lt;br /&gt;
  elsif @search_by == '2' # search by full name&lt;br /&gt;
    condition = &amp;quot;(role_id in (?) or id = ?) and fullname like ?&amp;quot;&lt;br /&gt;
    search_filter = '%' + letter + '%'&lt;br /&gt;
  elsif @search_by == '3' # search by email&lt;br /&gt;
     condition = &amp;quot;(role_id in (?) or id = ?) and email like ?&amp;quot;&lt;br /&gt;
     search_filter = '%' + letter + '%'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  if (paginate_options[&amp;quot;#{@per_page}&amp;quot;].nil?) #displaying all - no pagination&lt;br /&gt;
    users = User.order('name').where( [condition, role.get_available_roles, user_id, search_filter]).paginate(:page =&amp;gt; params[:page], :per_page =&amp;gt; User.count)&lt;br /&gt;
  else #some pagination is active - use the per_page&lt;br /&gt;
    users = User.page(params[:page]).order('name').per_page(paginate_options[&amp;quot;#{@per_page}&amp;quot;]).where([condition, role.get_available_roles, user_id, search_filter])&lt;br /&gt;
  end&lt;br /&gt;
  users&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
From the code we can see that the search method needs four parameters:&lt;br /&gt;
* role: user can only search users below his role&lt;br /&gt;
* user_id: current user id&lt;br /&gt;
* letter: keyword in search&lt;br /&gt;
* search_by: search by user name, full name or email&lt;br /&gt;
&lt;br /&gt;
Base on this, we implemented the search method in &amp;quot;user.rb&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.search_users(role, user_id, letter, search_by)&lt;br /&gt;
  if search_by == '1'  #search by user name&lt;br /&gt;
    search_filter = '%' + letter + '%'&lt;br /&gt;
    users = User.order('name').where( &amp;quot;(role_id in (?) or id = ?) and name like ?&amp;quot;, role.get_available_roles, user_id, search_filter )&lt;br /&gt;
  elsif search_by == '2' # search by full name&lt;br /&gt;
    search_filter = '%' + letter + '%'&lt;br /&gt;
    users = User.order('name').where( &amp;quot;(role_id in (?) or id = ?) and fullname like ?&amp;quot;, role.get_available_roles, user_id, search_filter )&lt;br /&gt;
  elsif search_by == '3' # search by email&lt;br /&gt;
    search_filter = '%' + letter + '%'&lt;br /&gt;
    users = User.order('name').where( &amp;quot;(role_id in (?) or id = ?) and email like ?&amp;quot;, role.get_available_roles, user_id, search_filter )&lt;br /&gt;
  else #default used when clicking on letters&lt;br /&gt;
    search_filter = letter + '%'&lt;br /&gt;
    users = User.order('name').where( &amp;quot;(role_id in (?) or id = ?) and name like ?&amp;quot;, role.get_available_roles, user_id, search_filter )&lt;br /&gt;
  end&lt;br /&gt;
  users&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the original &amp;quot;paginate_list&amp;quot; method is modified as:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# For filtering the users list with proper search and pagination.&lt;br /&gt;
def paginate_list(role, user_id, letter)&lt;br /&gt;
  paginate_options = {&amp;quot;1&amp;quot; =&amp;gt; 25, &amp;quot;2&amp;quot; =&amp;gt; 50, &amp;quot;3&amp;quot; =&amp;gt; 100}&lt;br /&gt;
&lt;br /&gt;
  # If the above hash does not have a value for the key,&lt;br /&gt;
  # it means that we need to show all the users on the page&lt;br /&gt;
  #&lt;br /&gt;
  # Just a point to remember, when we use pagination, the&lt;br /&gt;
  # 'users' variable should be an object, not an array&lt;br /&gt;
&lt;br /&gt;
  #The type of condition for the search depends on what the user has selected from the search_by dropdown&lt;br /&gt;
  @search_by = params[:search_by]&lt;br /&gt;
&lt;br /&gt;
  # search for corresponding users&lt;br /&gt;
  users = User.search_users(role, user_id, letter, @search_by)&lt;br /&gt;
&lt;br /&gt;
  # paginate&lt;br /&gt;
  if (paginate_options[&amp;quot;#{@per_page}&amp;quot;].nil?) #displaying all - no pagination&lt;br /&gt;
    users = users.paginate(:page =&amp;gt; params[:page], :per_page =&amp;gt; User.count)&lt;br /&gt;
  else #some pagination is active - use the per_page&lt;br /&gt;
    users = users.page(params[:page]).per_page(paginate_options[&amp;quot;#{@per_page}&amp;quot;])&lt;br /&gt;
  end&lt;br /&gt;
  users&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''New feature: delete users'''==&lt;br /&gt;
&lt;br /&gt;
===='''Design'''====&lt;br /&gt;
&lt;br /&gt;
At the very beginning, we decide to use &amp;quot;Cascading Delete&amp;quot; to delete users. Because there are many relationship between different users. They can be reviewer, reviewee, teaching assistant, and so on.If we have to delete an user, we have to not only delete the record in ''user'' table, but also other related tables.&lt;br /&gt;
&lt;br /&gt;
So, we divide all users into two set, one is '''new users''' without any relationship, the other is the '''old user''' with some relationships. And we find that it is quite easy to achieve the functionality of deleting new users. When deleting old users, we find some problems. Because old users may be a reviewer before and score some assignments. If we delete some old users, the assignments' review scores will be a mess.&lt;br /&gt;
&lt;br /&gt;
After discussing with professor, we decide to deprecate&amp;quot;Cascading Delete&amp;quot;. And we use below algorithm to handle user deletion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:OSS0.png‎  |frame|center|Confirm box flow diagram]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* A user can be deleted if (s)he has not participated in an assignment;&lt;br /&gt;
* If the user is participating in an assignment, the system will ask, “User is participating in k assignments. Delete as a participant in these assignment(s)?”;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:OSS1.png‎  |frame|center|Delete confirm box]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* If the user has submitted or reviewed in any of these assignments, the system will say the user cannot be deleted, but offer to rename the user account to &amp;lt;current_account_name&amp;gt;_hidden;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:OSS2.png‎  |frame|center|Rename confirm box]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Rename (javascript calling update method in users_controller.rb);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:OSS3.png‎  |frame|center|Rename success 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* If the person trying to delete does not want to rename the account, the system will just say that the user can’t be deleted.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:OSS4.png‎  |frame|center|Cannot delete]]&lt;br /&gt;
&lt;br /&gt;
===='''Implementation'''====&lt;br /&gt;
&lt;br /&gt;
We add a '''userDeleteConfirmBox.js''' file to implement this unique confirm box algorithm.&lt;br /&gt;
&lt;br /&gt;
* First, we overwrite the Rails default confirm function.&lt;br /&gt;
 $.rails.allowAction = function(link) {&lt;br /&gt;
   console.log(link.attr('data-relationship'))&lt;br /&gt;
   console.log(link.attr('data-username'))&lt;br /&gt;
   if ((!link.attr('data-confirm')) || (link.attr('data-relationship') &amp;amp;&amp;amp; link.attr('data-relationship') == 'false')) {&lt;br /&gt;
    return true;&lt;br /&gt;
   }&lt;br /&gt;
   $.rails.showConfirmDialog(link);&lt;br /&gt;
   return false;&lt;br /&gt;
 };&lt;br /&gt;
 $.rails.confirmed = function(link) {&lt;br /&gt;
   link.removeAttr('data-confirm');&lt;br /&gt;
   return link.trigger('click.rails');&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
* Then, we write code to achieve customed confirm box using our own algorithm.&lt;br /&gt;
 $.rails.showConfirmDialog = function(link) {&lt;br /&gt;
  var message = link.attr('data-confirm');&lt;br /&gt;
  //confirmation box style&lt;br /&gt;
  $(function() {&lt;br /&gt;
    $(html1).modal();&lt;br /&gt;
    $(&amp;quot;#dialog-confirm1&amp;quot;).dialog({&lt;br /&gt;
      width: 340,&lt;br /&gt;
      buttons: {&lt;br /&gt;
        &amp;quot;Cancel&amp;quot;: function() {&lt;br /&gt;
          $( this ).dialog( &amp;quot;close&amp;quot; );&lt;br /&gt;
          location.reload();&lt;br /&gt;
        },&lt;br /&gt;
        &amp;quot;Yes&amp;quot;: function() {&lt;br /&gt;
          //return $.rails.confirmed(link);&lt;br /&gt;
          $( this ).dialog( &amp;quot;close&amp;quot; );&lt;br /&gt;
          $(html2).modal();&lt;br /&gt;
          $(&amp;quot;#dialog-confirm2&amp;quot;).dialog({&lt;br /&gt;
            width: 340,&lt;br /&gt;
            buttons: {&lt;br /&gt;
              &amp;quot;Cancel&amp;quot;: function() {&lt;br /&gt;
                $( this ).dialog( &amp;quot;close&amp;quot; );&lt;br /&gt;
                location.reload();&lt;br /&gt;
              },&lt;br /&gt;
              &amp;quot;Yes&amp;quot;: function() {                 &lt;br /&gt;
                    $('#rename').click() &lt;br /&gt;
                  $( this ).dialog( &amp;quot;close&amp;quot; );&lt;br /&gt;
                  $(html3).modal();&lt;br /&gt;
                  $(&amp;quot;#dialog-confirm3&amp;quot;).dialog({&lt;br /&gt;
                    width: 340,&lt;br /&gt;
                  });&lt;br /&gt;
              },&lt;br /&gt;
              &amp;quot;No, delete any way!&amp;quot;: function() {&lt;br /&gt;
                  $( this ).dialog( &amp;quot;close&amp;quot; );&lt;br /&gt;
                  $(html4).modal();&lt;br /&gt;
                  $(&amp;quot;#dialog-confirm4&amp;quot;).dialog({&lt;br /&gt;
                      width: 340,&lt;br /&gt;
                      buttons: {&lt;br /&gt;
                        &amp;quot;Close&amp;quot;: function() {&lt;br /&gt;
                          $( this ).dialog( &amp;quot;close&amp;quot; );&lt;br /&gt;
                          location.reload();&lt;br /&gt;
                        }&lt;br /&gt;
                      }&lt;br /&gt;
                  });&lt;br /&gt;
                }&lt;br /&gt;
              }&lt;br /&gt;
           });&lt;br /&gt;
         }&lt;br /&gt;
       }&lt;br /&gt;
     });&lt;br /&gt;
  });&lt;br /&gt;
  return $('#dialog-confirm .confirm').on('click', function() {&lt;br /&gt;
    return $.rails.confirmed(link);&lt;br /&gt;
  });&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
* After that, we all the if condition in '''/users/show.html.erb''' file. So when deleting the old users, Expertiza uses the functionality and customed confirm box we define; when deleting the new users, Expertiza will use the default confirm box.&lt;br /&gt;
  &amp;lt;% if @assignment_participant_num != 0 and (!@maps.nil? or @maps.length != 0)%&amp;gt; &lt;br /&gt;
      &amp;lt;%= link_to 'Delete', {:action =&amp;gt; 'destroy', :id =&amp;gt; @user}, data:{:confirm =&amp;gt; &amp;quot;User is participating in #{@assignment_participant_num} assignments.&amp;lt;br/&amp;gt;Delete as a participant in these assignment(s)?&amp;quot;, :relationship =&amp;gt; 'true', :username =&amp;gt; @user.name}, :method =&amp;gt; :delete, remote: true%&amp;gt;   &lt;br /&gt;
  &amp;lt;% else %&amp;gt;&lt;br /&gt;
       &amp;lt;%= link_to 'Delete', {:action =&amp;gt; 'destroy', :id =&amp;gt; @user}, data:{:confirm =&amp;gt; &amp;quot;User joins in #{@assignment_participant_num} assignment(s), but without participates in&lt;br /&gt;
 any assignments. Delete as a participant in these assignment(s)?&amp;quot;, :relationship =&amp;gt; 'false'}, :method =&amp;gt; :delete, remote: true%&amp;gt;&lt;br /&gt;
   &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Testing feature: search for users'''==&lt;br /&gt;
&lt;br /&gt;
==='''Design'''===&lt;br /&gt;
&lt;br /&gt;
We write some features test to test &amp;quot;search for users&amp;quot; functionality.&lt;br /&gt;
&lt;br /&gt;
* Instructor searches users bylogin names&lt;br /&gt;
 feature 'Method 1: Instructor search a user' do&lt;br /&gt;
  before(:all) do&lt;br /&gt;
    instructor.save&lt;br /&gt;
    student.save&lt;br /&gt;
    log_in instructor.name, &amp;quot;password&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  scenario 'by login name' do&lt;br /&gt;
    visit '/users/list'&lt;br /&gt;
    fill_in 'letter', with: 'student'&lt;br /&gt;
    find('#search_by').select 'Username'&lt;br /&gt;
    click_button 'Search'&lt;br /&gt;
    expect(page).to have_content(&amp;quot;Student, Perfect&amp;quot;)&lt;br /&gt;
    expect(page).to have_content(&amp;quot;pstudent@dev.null&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
* Instructor searches users by first name or last name&lt;br /&gt;
 feature 'Method2: Instructor search a user' do&lt;br /&gt;
  before(:all) do&lt;br /&gt;
    instructor.save&lt;br /&gt;
    student.save&lt;br /&gt;
    log_in instructor.name, &amp;quot;password&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  scenario 'by last or first name' do&lt;br /&gt;
    visit '/users/list'&lt;br /&gt;
    fill_in 'letter', with: 'Bob'&lt;br /&gt;
    find('#search_by').select 'Full name'&lt;br /&gt;
    click_button 'Search'&lt;br /&gt;
    expect(page).to have_content(&amp;quot;Dole, Bob&amp;quot;)&lt;br /&gt;
    expect(page).to have_content(&amp;quot;bdole@dev.null&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
* Instructor searches users by email&lt;br /&gt;
 feature 'Method3: Instructor search a user' do&lt;br /&gt;
  before(:all) do&lt;br /&gt;
    instructor.save&lt;br /&gt;
    student.save&lt;br /&gt;
    log_in instructor.name, &amp;quot;password&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  scenario 'by email' do&lt;br /&gt;
    visit '/users/list'&lt;br /&gt;
    fill_in 'letter', with: 'bdole@dev.null'&lt;br /&gt;
    find('#search_by').select 'Email'&lt;br /&gt;
    click_button 'Search'&lt;br /&gt;
    expect(page).to have_content(&amp;quot;Dole, Bob&amp;quot;)&lt;br /&gt;
    expect(page).to have_content(&amp;quot;bdole@dev.null&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
* Instructor deletes new users&lt;br /&gt;
 feature 'Instructor delete a user' do&lt;br /&gt;
  before(:all) do&lt;br /&gt;
    instructor.save&lt;br /&gt;
    student.save&lt;br /&gt;
    log_in instructor.name, &amp;quot;password&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  scenario 'which has no relationship' do&lt;br /&gt;
    visit '/users/list'&lt;br /&gt;
    #in order to show whole user list&lt;br /&gt;
    fill_in 'letter', with: ''&lt;br /&gt;
    find('#search_by').select 'Username'&lt;br /&gt;
    click_button 'Search'&lt;br /&gt;
    click_link 'student'&lt;br /&gt;
    click_link 'Delete'&lt;br /&gt;
    expect(page).to_not have_content(&amp;quot;student&amp;quot;)&lt;br /&gt;
    expect(page).to have_content(&amp;quot;instructor&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==='''Implementation'''===&lt;br /&gt;
 rspec spec/features/users_spec.rb&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec1.png‎  |frame|center|Rspec feature test pass]]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Szhang29</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/oss_E1506_SYZ&amp;diff=95309</id>
		<title>CSC/ECE 517 Spring 2015/oss E1506 SYZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/oss_E1506_SYZ&amp;diff=95309"/>
		<updated>2015-03-22T01:44:56Z</updated>

		<summary type="html">&lt;p&gt;Szhang29: /* Refactor users_controller.rb */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1506: Refactoring, testing and new features related to “users”&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Overview'''==&lt;br /&gt;
===Code refactoring===&lt;br /&gt;
''Refactoring'' is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior&amp;lt;ref&amp;gt;[http://refactoring.com/ Refactoring]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Refactoring adds to the value of any program that has at least one of the following shortcomings&amp;lt;ref&amp;gt;[http://jexp.de/papers/refactoring/refactoring/node9.html#SECTION00330000000000000000 Benefits of Code Refactoring] Michael Hunger. Oct. 25, 2000&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
* Programs that are hard to read are hard to modify;&lt;br /&gt;
* Programs that have duplicate logic are hard to modify;&lt;br /&gt;
* Programs that require additional behavior that requires you to change running code are hard to modify;&lt;br /&gt;
* Programs with complex conditional logic are hard to modify.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Rspec===&lt;br /&gt;
RSpec is a [http://en.wikipedia.org/wiki/Behavior-driven_development behavior-driven development] (BDD) framework for the [http://en.wikipedia.org/wiki/Ruby_(programming_language) Ruby programming language], inspired by JBehave. It contains its own mocking framework that is fully integrated into the framework based upon JMock. The framework can be considered a [http://en.wikipedia.org/wiki/Domain-specific_language domain-specific language] (DSL) and resembles a natural language specification&amp;lt;ref&amp;gt;[http://en.wikipedia.org/wiki/RSpec#cite_note-origin-4g Rspec]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Object-oriented Design Principles===&lt;br /&gt;
Object-oriented programming (OOP) is a programming language model organized around objects rather than &amp;quot;actions&amp;quot; and data rather than logic&amp;lt;ref&amp;gt;[http://searchsoa.techtarget.com/definition/object-oriented-programming Margaret Rouse. ''object-oriented programming (OOP) definition''. Aug 3, 2008]&amp;lt;/ref&amp;gt;. Historically, a program has been viewed as a logical procedure that takes input data, processes it, and produces output data. Though an Object oriented language provides us with highly useful and important programming concepts like '''Inheritance''', '''Polymorphism''', '''Abstraction''' and '''Encapsulation''' which definitely makes the code more efficient, it is equally important to have the knowledge of using them in the code. &lt;br /&gt;
''Object Oriented Design'' Principles are core of OOPS programming&amp;lt;ref&amp;gt;[http://javarevisited.blogspot.com/2012/03/10-object-oriented-design-principles.html#ixzz3Ha8L3cfz Javin Paul. ''Blogspot''. March 3, 2012]&amp;lt;/ref&amp;gt;. It is important to know these design principles, to create clean and modular design. There are many design principles that help us to create clean and efficient code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=='''Project Resources'''==&lt;br /&gt;
* [https://github.com/CSC517-Proj2-E1506/expertiza GitHub Repository]&lt;br /&gt;
* [http://152.46.16.178:3001/ VCL IP] (Log in as user2/password. Go to [http://152.46.16.178:3001/analytic/index VCL analytic page])&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/505 GitHub Pull Request Link]&lt;br /&gt;
&lt;br /&gt;
=='''Todo List'''==&lt;br /&gt;
&amp;lt;b&amp;gt;Related files:&amp;lt;/b&amp;gt; users_controller.rb, participants_controller.rb, user.rb, users/show.html.erb&lt;br /&gt;
*  Find the un-called methods if any and delete them. &amp;lt;b&amp;gt;[done]&amp;lt;/b&amp;gt;&lt;br /&gt;
*  Change the Rails 2 syntax to Rails 4 style.&lt;br /&gt;
*  Refactor users_controller.rb&lt;br /&gt;
** Change the white space for the second harf of this file, starts at “def edit”. &amp;lt;b&amp;gt;[done]&amp;lt;/b&amp;gt;&lt;br /&gt;
** Separate the “paginate_list” method into two methods. The search method should be in model and the paginating method should be in the controller.  &amp;lt;b&amp;gt;[done]&amp;lt;/b&amp;gt;&lt;br /&gt;
* New feature: delete users&lt;br /&gt;
** A user can be deleted if (s)he has not participated in an assignment. &amp;lt;b&amp;gt;[done]&amp;lt;/b&amp;gt;&lt;br /&gt;
** If the user is participating in an assignment, the system will ask, “User is participating in k assignments.  Delete as a participant in these assignment(s)?”  &amp;lt;b&amp;gt;[done]&amp;lt;/b&amp;gt;&lt;br /&gt;
** If the user has submitted or reviewed in any of these assignments, the system will say the user cannot be deleted, but offer to rename the user account to &amp;lt;current_account_name&amp;gt;_hidden.&lt;br /&gt;
*** rename (javascript calling update method in users_controller.rb) &amp;lt;b&amp;gt;[done]&amp;lt;/b&amp;gt;&lt;br /&gt;
*** different users have different delete methods.  &amp;lt;b&amp;gt;[done]&amp;lt;/b&amp;gt;&lt;br /&gt;
** If the person trying to delete does not want to rename the account, the system will just say that the user can’t be deleted. &amp;lt;b&amp;gt;[done]&amp;lt;/b&amp;gt;&lt;br /&gt;
** Write tests (with Rspec) for this feature.&amp;lt;b&amp;gt;[done]&amp;lt;/b&amp;gt;&lt;br /&gt;
* Testing feature: search for users&lt;br /&gt;
** In rails 4 branch, admins can search for the users with 1) users’ login names 2) users’ last or first names and 3) users’ emails. Please write tests (with Rspec) for this feature &amp;lt;b&amp;gt;[done]&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Delete Uncalled Methods'''==&lt;br /&gt;
The primary way we find unused method is right-click on each method's name, then choose &amp;quot;Find Usage&amp;quot;, as the following picture shows:&lt;br /&gt;
[[File:FindUsages.PNG]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then the finding results will be displayed in the bottom, as the following picture shows:&lt;br /&gt;
[[File:FindResult.PNG]]&lt;br /&gt;
&lt;br /&gt;
=='''Change Rails 2 syntax to Rails 4'''==&lt;br /&gt;
&amp;lt;b&amp;gt;'''with_scope'''&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Refactor users_controller.rb'''==&lt;br /&gt;
===='''Refactor the “paginate_list” method'''====&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;paginate_list&amp;quot; method is a function in &amp;quot;user_controller.rb&amp;quot;. It will be called if you do search in Manage-&amp;gt;Users page. It has two components: search for users, paginate the results.&lt;br /&gt;
&lt;br /&gt;
However, the controller should not know how the information is retrieved. So we would like to refactor this method by seperating it into search method and paginating method. The search method is in model and the paginating method is still in controller.&lt;br /&gt;
&lt;br /&gt;
The code below is the &amp;quot;paginate_list&amp;quot; method in official Expertiza:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# For filtering the users list with proper search and pagination.&lt;br /&gt;
def paginate_list(role, user_id, letter)&lt;br /&gt;
  paginate_options = {&amp;quot;1&amp;quot; =&amp;gt; 25, &amp;quot;2&amp;quot; =&amp;gt; 50, &amp;quot;3&amp;quot; =&amp;gt; 100}&lt;br /&gt;
&lt;br /&gt;
  # If the above hash does not have a value for the key,&lt;br /&gt;
  # it means that we need to show all the users on the page&lt;br /&gt;
  #&lt;br /&gt;
  # Just a point to remember, when we use pagination, the&lt;br /&gt;
  # 'users' variable should be an object, not an array&lt;br /&gt;
&lt;br /&gt;
  #The type of condition for the search depends on what the user has selected from the search_by dropdown&lt;br /&gt;
  condition = &amp;quot;(role_id in (?) or id = ?) and name like ?&amp;quot; #default used when clicking on letters&lt;br /&gt;
  search_filter = letter + '%'&lt;br /&gt;
  @search_by = params[:search_by]&lt;br /&gt;
  if @search_by == '1'  #search by user name&lt;br /&gt;
    condition = &amp;quot;(role_id in (?) or id = ?) and name like ?&amp;quot;&lt;br /&gt;
    search_filter = '%' + letter + '%'&lt;br /&gt;
  elsif @search_by == '2' # search by full name&lt;br /&gt;
    condition = &amp;quot;(role_id in (?) or id = ?) and fullname like ?&amp;quot;&lt;br /&gt;
    search_filter = '%' + letter + '%'&lt;br /&gt;
  elsif @search_by == '3' # search by email&lt;br /&gt;
     condition = &amp;quot;(role_id in (?) or id = ?) and email like ?&amp;quot;&lt;br /&gt;
     search_filter = '%' + letter + '%'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  if (paginate_options[&amp;quot;#{@per_page}&amp;quot;].nil?) #displaying all - no pagination&lt;br /&gt;
    users = User.order('name').where( [condition, role.get_available_roles, user_id, search_filter]).paginate(:page =&amp;gt; params[:page], :per_page =&amp;gt; User.count)&lt;br /&gt;
    else #some pagination is active - use the per_page&lt;br /&gt;
    users = User.page(params[:page]).order('name').per_page(paginate_options[&amp;quot;#{@per_page}&amp;quot;]).where([condition, role.get_available_roles, user_id, search_filter])&lt;br /&gt;
  end&lt;br /&gt;
  users&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''New feature: delete users'''==&lt;br /&gt;
&lt;br /&gt;
===='''Design'''====&lt;br /&gt;
&lt;br /&gt;
At the very beginning, we decide to use &amp;quot;Cascading Delete&amp;quot; to delete users. Because there are many relationship between different users. They can be reviewer, reviewee, teaching assistant, and so on.If we have to delete an user, we have to not only delete the record in ''user'' table, but also other related tables.&lt;br /&gt;
&lt;br /&gt;
So, we divide all users into two set, one is '''new users''' without any relationship, the other is the '''old user''' with some relationships. And we find that it is quite easy to achieve the functionality of deleting new users. When deleting old users, we find some problems. Because old users may be a reviewer before and score some assignments. If we delete some old users, the assignments' review scores will be a mess.&lt;br /&gt;
&lt;br /&gt;
After discussing with professor, we decide to deprecate&amp;quot;Cascading Delete&amp;quot;. And we use below algorithm to handle user deletion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:OSS0.png‎  |frame|center|Confirm box flow diagram]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* A user can be deleted if (s)he has not participated in an assignment;&lt;br /&gt;
* If the user is participating in an assignment, the system will ask, “User is participating in k assignments. Delete as a participant in these assignment(s)?”;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:OSS1.png‎  |frame|center|Delete confirm box]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* If the user has submitted or reviewed in any of these assignments, the system will say the user cannot be deleted, but offer to rename the user account to &amp;lt;current_account_name&amp;gt;_hidden;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:OSS2.png‎  |frame|center|Rename confirm box]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Rename (javascript calling update method in users_controller.rb);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:OSS3.png‎  |frame|center|Rename success 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* If the person trying to delete does not want to rename the account, the system will just say that the user can’t be deleted.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:OSS4.png‎  |frame|center|Cannot delete]]&lt;br /&gt;
&lt;br /&gt;
===='''Implementation'''====&lt;br /&gt;
&lt;br /&gt;
We add a '''userDeleteConfirmBox.js''' file to implement this unique confirm box algorithm.&lt;br /&gt;
&lt;br /&gt;
* First, we overwrite the Rails default confirm function.&lt;br /&gt;
 $.rails.allowAction = function(link) {&lt;br /&gt;
   console.log(link.attr('data-relationship'))&lt;br /&gt;
   console.log(link.attr('data-username'))&lt;br /&gt;
   if ((!link.attr('data-confirm')) || (link.attr('data-relationship') &amp;amp;&amp;amp; link.attr('data-relationship') == 'false')) {&lt;br /&gt;
    return true;&lt;br /&gt;
   }&lt;br /&gt;
   $.rails.showConfirmDialog(link);&lt;br /&gt;
   return false;&lt;br /&gt;
 };&lt;br /&gt;
 $.rails.confirmed = function(link) {&lt;br /&gt;
   link.removeAttr('data-confirm');&lt;br /&gt;
   return link.trigger('click.rails');&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
* Then, we write code to achieve customed confirm box using our own algorithm.&lt;br /&gt;
 $.rails.showConfirmDialog = function(link) {&lt;br /&gt;
  var message = link.attr('data-confirm');&lt;br /&gt;
  //confirmation box style&lt;br /&gt;
  $(function() {&lt;br /&gt;
    $(html1).modal();&lt;br /&gt;
    $(&amp;quot;#dialog-confirm1&amp;quot;).dialog({&lt;br /&gt;
      width: 340,&lt;br /&gt;
      buttons: {&lt;br /&gt;
        &amp;quot;Cancel&amp;quot;: function() {&lt;br /&gt;
          $( this ).dialog( &amp;quot;close&amp;quot; );&lt;br /&gt;
          location.reload();&lt;br /&gt;
        },&lt;br /&gt;
        &amp;quot;Yes&amp;quot;: function() {&lt;br /&gt;
          //return $.rails.confirmed(link);&lt;br /&gt;
          $( this ).dialog( &amp;quot;close&amp;quot; );&lt;br /&gt;
          $(html2).modal();&lt;br /&gt;
          $(&amp;quot;#dialog-confirm2&amp;quot;).dialog({&lt;br /&gt;
            width: 340,&lt;br /&gt;
            buttons: {&lt;br /&gt;
              &amp;quot;Cancel&amp;quot;: function() {&lt;br /&gt;
                $( this ).dialog( &amp;quot;close&amp;quot; );&lt;br /&gt;
                location.reload();&lt;br /&gt;
              },&lt;br /&gt;
              &amp;quot;Yes&amp;quot;: function() {                 &lt;br /&gt;
                    $('#rename').click() &lt;br /&gt;
                  $( this ).dialog( &amp;quot;close&amp;quot; );&lt;br /&gt;
                  $(html3).modal();&lt;br /&gt;
                  $(&amp;quot;#dialog-confirm3&amp;quot;).dialog({&lt;br /&gt;
                    width: 340,&lt;br /&gt;
                  });&lt;br /&gt;
              },&lt;br /&gt;
              &amp;quot;No, delete any way!&amp;quot;: function() {&lt;br /&gt;
                  $( this ).dialog( &amp;quot;close&amp;quot; );&lt;br /&gt;
                  $(html4).modal();&lt;br /&gt;
                  $(&amp;quot;#dialog-confirm4&amp;quot;).dialog({&lt;br /&gt;
                      width: 340,&lt;br /&gt;
                      buttons: {&lt;br /&gt;
                        &amp;quot;Close&amp;quot;: function() {&lt;br /&gt;
                          $( this ).dialog( &amp;quot;close&amp;quot; );&lt;br /&gt;
                          location.reload();&lt;br /&gt;
                        }&lt;br /&gt;
                      }&lt;br /&gt;
                  });&lt;br /&gt;
                }&lt;br /&gt;
              }&lt;br /&gt;
           });&lt;br /&gt;
         }&lt;br /&gt;
       }&lt;br /&gt;
     });&lt;br /&gt;
  });&lt;br /&gt;
  return $('#dialog-confirm .confirm').on('click', function() {&lt;br /&gt;
    return $.rails.confirmed(link);&lt;br /&gt;
  });&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
* After that, we all the if condition in '''/users/show.html.erb''' file. So when deleting the old users, Expertiza uses the functionality and customed confirm box we define; when deleting the new users, Expertiza will use the default confirm box.&lt;br /&gt;
  &amp;lt;% if @assignment_participant_num != 0 and (!@maps.nil? or @maps.length != 0)%&amp;gt; &lt;br /&gt;
      &amp;lt;%= link_to 'Delete', {:action =&amp;gt; 'destroy', :id =&amp;gt; @user}, data:{:confirm =&amp;gt; &amp;quot;User is participating in #{@assignment_participant_num} assignments.&amp;lt;br/&amp;gt;Delete as a participant in these assignment(s)?&amp;quot;, :relationship =&amp;gt; 'true', :username =&amp;gt; @user.name}, :method =&amp;gt; :delete, remote: true%&amp;gt;   &lt;br /&gt;
  &amp;lt;% else %&amp;gt;&lt;br /&gt;
       &amp;lt;%= link_to 'Delete', {:action =&amp;gt; 'destroy', :id =&amp;gt; @user}, data:{:confirm =&amp;gt; &amp;quot;User joins in #{@assignment_participant_num} assignment(s), but without participates in&lt;br /&gt;
 any assignments. Delete as a participant in these assignment(s)?&amp;quot;, :relationship =&amp;gt; 'false'}, :method =&amp;gt; :delete, remote: true%&amp;gt;&lt;br /&gt;
   &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Testing feature: search for users'''==&lt;br /&gt;
&lt;br /&gt;
==='''Design'''===&lt;br /&gt;
&lt;br /&gt;
We write some features test to test &amp;quot;search for users&amp;quot; functionality.&lt;br /&gt;
&lt;br /&gt;
* Instructor searches users bylogin names&lt;br /&gt;
 feature 'Method 1: Instructor search a user' do&lt;br /&gt;
  before(:all) do&lt;br /&gt;
    instructor.save&lt;br /&gt;
    student.save&lt;br /&gt;
    log_in instructor.name, &amp;quot;password&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  scenario 'by login name' do&lt;br /&gt;
    visit '/users/list'&lt;br /&gt;
    fill_in 'letter', with: 'student'&lt;br /&gt;
    find('#search_by').select 'Username'&lt;br /&gt;
    click_button 'Search'&lt;br /&gt;
    expect(page).to have_content(&amp;quot;Student, Perfect&amp;quot;)&lt;br /&gt;
    expect(page).to have_content(&amp;quot;pstudent@dev.null&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
* Instructor searches users by first name or last name&lt;br /&gt;
 feature 'Method2: Instructor search a user' do&lt;br /&gt;
  before(:all) do&lt;br /&gt;
    instructor.save&lt;br /&gt;
    student.save&lt;br /&gt;
    log_in instructor.name, &amp;quot;password&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  scenario 'by last or first name' do&lt;br /&gt;
    visit '/users/list'&lt;br /&gt;
    fill_in 'letter', with: 'Bob'&lt;br /&gt;
    find('#search_by').select 'Full name'&lt;br /&gt;
    click_button 'Search'&lt;br /&gt;
    expect(page).to have_content(&amp;quot;Dole, Bob&amp;quot;)&lt;br /&gt;
    expect(page).to have_content(&amp;quot;bdole@dev.null&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
* Instructor searches users by email&lt;br /&gt;
 feature 'Method3: Instructor search a user' do&lt;br /&gt;
  before(:all) do&lt;br /&gt;
    instructor.save&lt;br /&gt;
    student.save&lt;br /&gt;
    log_in instructor.name, &amp;quot;password&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  scenario 'by email' do&lt;br /&gt;
    visit '/users/list'&lt;br /&gt;
    fill_in 'letter', with: 'bdole@dev.null'&lt;br /&gt;
    find('#search_by').select 'Email'&lt;br /&gt;
    click_button 'Search'&lt;br /&gt;
    expect(page).to have_content(&amp;quot;Dole, Bob&amp;quot;)&lt;br /&gt;
    expect(page).to have_content(&amp;quot;bdole@dev.null&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
* Instructor deletes new users&lt;br /&gt;
 feature 'Instructor delete a user' do&lt;br /&gt;
  before(:all) do&lt;br /&gt;
    instructor.save&lt;br /&gt;
    student.save&lt;br /&gt;
    log_in instructor.name, &amp;quot;password&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  scenario 'which has no relationship' do&lt;br /&gt;
    visit '/users/list'&lt;br /&gt;
    #in order to show whole user list&lt;br /&gt;
    fill_in 'letter', with: ''&lt;br /&gt;
    find('#search_by').select 'Username'&lt;br /&gt;
    click_button 'Search'&lt;br /&gt;
    click_link 'student'&lt;br /&gt;
    click_link 'Delete'&lt;br /&gt;
    expect(page).to_not have_content(&amp;quot;student&amp;quot;)&lt;br /&gt;
    expect(page).to have_content(&amp;quot;instructor&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==='''Implement'''===&lt;br /&gt;
 rspec spec/features/users_spec.rb&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec1.png‎  |frame|center|Rspec feature test pass]]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Szhang29</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_1_DZ&amp;diff=93514</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 1 DZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_1_DZ&amp;diff=93514"/>
		<updated>2015-02-09T14:49:10Z</updated>

		<summary type="html">&lt;p&gt;Szhang29: /* Vagrant Box */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Vagrant&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Vagrant''' is a computer software that helps create, configure and manage virtual development or work environments. With its great portability and compatibility, team members can share a common development environment. Therefore minimize the cost of time for deployment and maximize the productivity and flexibility.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
Vagrant works with mainstream virtualization softwares like [https://www.virtualbox.org/ VirtualBox], [http://www.vmware.com/ VMware] and [http://aws.amazon.com/ AWS] or any other provider&amp;lt;ref&amp;gt;Other supported Virtualization softwares: https://docs.vagrantup.com/v2/providers/&amp;lt;/ref&amp;gt;. &lt;br /&gt;
=== Virtualization Machine ===&lt;br /&gt;
Virtualization machine, aka Virtual Machine or VM, which is created by virtualization software, is an emulation of a real computer that provides a complete operating system. In other words, a virtual machine(VM) is a computer with a complete set of hardwares and operating system which runs in your own operating system. In that way, for example, one using Windows operating system can easily install Linux operating system in the VM rather than actually installing it on local machine. Therefore, any changes or modifications in the VM will not propagate to the operating system on which it runs. &lt;br /&gt;
&lt;br /&gt;
=== Vagrant Box ===&lt;br /&gt;
'''Boxes''' are the package format for Vagrant environments. In other words, a box is a packed operating system used by Vagrant. &amp;lt;code&amp;gt;'''vagrant box'''&amp;lt;/code&amp;gt; is the utility that downloads and manages different types of boxes.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'''vagrant box add {url}'''&amp;lt;/code&amp;gt; can be executed under both Windows and Unix operating system to add a new box to Vagrant. &amp;lt;code&amp;gt;'''url'''&amp;lt;/code&amp;gt; is the network location of the box. &amp;lt;br&amp;gt;&lt;br /&gt;
For example: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'''vagrant box add hashicorp/precise64'''&amp;lt;/code&amp;gt; downloads a standard Ubuntu 12.04 LTS 64-bit box from [https://atlas.hashicorp.com/boxes/search?utm_source=vagrantcloud.com&amp;amp;vagrantcloud=1 HashiCorp's Atlas box catalog].&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'''vagrant box add https://dl.dropboxusercontent.com/u/29173892/vagrant-boxes/debian7.3.0-vbox4.3.6-puppet3.4.1.box'''&amp;lt;/code&amp;gt; downloads a Debian 7.3.0 64-bit Puppet 3.4.1 box which is shared by personal user.&amp;lt;br&amp;gt;&lt;br /&gt;
By default, Vagrant automatically check for updates during any &amp;lt;code&amp;gt;vagrant up&amp;lt;/code&amp;gt;. You can also disable this by adding &amp;lt;code&amp;gt;config.vm.box_check_update = false&amp;lt;/code&amp;gt; in your Vagrantfile.&lt;br /&gt;
&lt;br /&gt;
=== Vagrantfile ===&lt;br /&gt;
'''Vagrantfile''' is a configuration file&amp;lt;ref&amp;gt;Definition of configuration file: http://en.wikipedia.org/wiki/Configuration_file&amp;lt;/ref&amp;gt; which exists in every single vagrant folder. It is written in Ruby, probably looks like this: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vagrant.configure(2) do |config|&lt;br /&gt;
    config.vm.box = &amp;quot;hashicorp/precise32&amp;quot;&lt;br /&gt;
    # other configuration here&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;quot;2&amp;quot; in the first line is the version of configuration object &amp;lt;code&amp;gt;config&amp;lt;/code&amp;gt;. This number is either &amp;quot;1&amp;quot; for Vagrant 1.0.x, or &amp;quot;2&amp;quot; for Vagrant 1.1+. &amp;lt;br&amp;gt;&lt;br /&gt;
This file allows you to configure some basic settings (including shared folder location, cpu core number and etc.) of the virtual machine. For example: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.provider &amp;quot;virtualbox&amp;quot; do |vb|&lt;br /&gt;
    vb.memory = &amp;quot;1024&amp;quot;&lt;br /&gt;
    vb.cpus=&amp;quot;2&amp;quot;&lt;br /&gt;
    config.vm.network :forwarded_port, host: 8000, guest: 80&lt;br /&gt;
    config.vm.network :forwarded_port, host: 33060, guest: 33060&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This section of code specifies the memory and CPU core number of the virtual machine. Also, any network traffic on localhost:8000 and localhost:33060 will be forwarded to port 80 and 33060, respectively. &amp;lt;br&amp;gt;&lt;br /&gt;
Some more examples: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.synced_folder &amp;quot;src/&amp;quot;, &amp;quot;/srv/website&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This command is used to sync folder. The first parameter is a path to a directory on the host machine, the second parameter must be an absolute path of where to share the folder within the guest machine. &amp;lt;br&amp;gt;&lt;br /&gt;
By default, synced folders are mounted with the SSH user owner/group setting. You can mount them with a different owner and group using the configuration below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.synced_folder &amp;quot;src/&amp;quot;, &amp;quot;/srv/website&amp;quot;&lt;br /&gt;
  owner: &amp;quot;root&amp;quot;, group: &amp;quot;root&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Provision ===&lt;br /&gt;
Provision in Vagrant is a process of automatically install your own softwares and modify configurations during the VM booting up.&amp;lt;br&amp;gt;&lt;br /&gt;
Also, this process needs no human interaction and therefore makes it very convenient and repeatable. &amp;lt;br&amp;gt;&lt;br /&gt;
Every provisioner is configured within your Vagrantfile using the &amp;lt;code&amp;gt;config.vm.provision&amp;lt;/code&amp;gt; method call, for example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.provider &amp;quot;virtualbox&amp;quot; do |vb|&lt;br /&gt;
  config.vm.provision :shell, path: &amp;quot;bootstrap.sh&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This section of code enables &amp;lt;code&amp;gt;'''bootstrap.sh'''&amp;lt;/code&amp;gt; every time the VM is initialized or reloaded. &amp;lt;br&amp;gt;&lt;br /&gt;
Typically, provisioners are only run once, during the first &amp;lt;code&amp;gt;vagrant up&amp;lt;/code&amp;gt; since the last &amp;lt;code&amp;gt;vagrant destroy&amp;lt;/code&amp;gt;. If you want to run the provisioners on every &amp;lt;code&amp;gt;vagrant up&amp;lt;/code&amp;gt;, simply set the &amp;lt;code&amp;gt;run&amp;lt;/code&amp;gt; option to &amp;quot;always&amp;quot;, as shown below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.provider &amp;quot;virtualbox&amp;quot; do |vb|&lt;br /&gt;
  config.vm.provision :shell, path: &amp;quot;bootstrap.sh&amp;quot;&lt;br /&gt;
    run: &amp;quot;always&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Why use it? ==&lt;br /&gt;
Many people would ask why use vagrant rather than use Virtualbox or VMware directly to build several virtual machines?&amp;lt;br&amp;gt;&lt;br /&gt;
=== Easy to setup ===&lt;br /&gt;
Actually what Vagrant needs to setup a Virtual Machine is only a Vagrantfile, which is small text file containing the configuration of the VM and can be easily distributed online via USB drive.&lt;br /&gt;
For example, if I have a well-configured Vagrantfile on GitHub&amp;lt;ref&amp;gt;GitHub For Beginners: Don't Get Scared, Get Started: http://readwrite.com/2013/09/30/understanding-github-a-journey-for-beginners-part-1&amp;lt;/ref&amp;gt;, the following 3 steps are all I need to do to have the VM setup:&lt;br /&gt;
&amp;lt;li&amp;gt;Install Vagrant and Virtualbox&lt;br /&gt;
&amp;lt;li&amp;gt;git clone git@github.com:&amp;lt;git repo name&amp;gt;.git&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;'''vagrant up'''&amp;lt;/code&amp;gt;&lt;br /&gt;
Very simple and easy, isn't it? The whole process takes maybe only 15 minutes if you have a quick Internet access.&lt;br /&gt;
&lt;br /&gt;
=== Source Control ===&lt;br /&gt;
The files in the Vagrant folder are those that appear in the Vagrant Virtual Machine. So it is very easy to know which file is modified by source control tool like Git. But if you are using Virtualbox directly, all files of the VM are stored in a single and large disk image, so it is impossible to perform source control to single files. Although Virtualbox offers Snapshot functionality to implement version restoration, it takes up much more spaces than to use Vagrant.&lt;br /&gt;
&lt;br /&gt;
== How it works ==&lt;br /&gt;
=== Set up ===&lt;br /&gt;
'''Step 1: '''Install a mainstream VM software. (e.g. [https://www.virtualbox.org/wiki/Downloads VirtualBox Download Page])&amp;lt;br&amp;gt;&lt;br /&gt;
'''Step 2: '''Download [http://www.vagrantup.com/downloads Vagrant]&lt;br /&gt;
&lt;br /&gt;
=== Configure ===&lt;br /&gt;
'''Step 1: ''' &amp;lt;code&amp;gt;'''vagrant box add hashicorp/precise32'''&amp;lt;/code&amp;gt; to add a Ubuntu&amp;lt;ref&amp;gt;Using Ubuntu Linux/Introduction: http://en.wikibooks.org/wiki/Using_Ubuntu_Linux/Introduction&amp;lt;/ref&amp;gt; 32bit box&amp;lt;br&amp;gt; and &amp;quot;hashicorp/precise32&amp;quot; change be change to other Vagrant image name.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Step 2: ''' &amp;lt;code&amp;gt;'''vagrant init hashicorp/precise32'''&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Work ===&lt;br /&gt;
'''Step 1: ''' &amp;lt;code&amp;gt;'''vagrant up'''&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;'''vagrant up --provision'''&amp;lt;/code&amp;gt; if you want to run the VM in provision mode.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Step 2: ''' &amp;lt;code&amp;gt;'''vagrant ssh'''&amp;lt;/code&amp;gt; to login to the virtual machine.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
For example, I need two Virtual Machines to run two different Linux distributions(CentOS-6.5&amp;lt;ref&amp;gt;CentOS 6.5 Release Notes: http://wiki.centos.org/Manuals/ReleaseNotes/CentOS6.5#head-5e50f026e9d40ab3ed3c0f504420c4542fd1719a&amp;lt;/ref&amp;gt; and Ubuntu Server 14.04 LTS), and they can communicate with each other.&lt;br /&gt;
=== Add Boxes ===&lt;br /&gt;
First, to add the CentOS box.&lt;br /&gt;
&amp;lt;pre&amp;gt;vagrant box add chef/centos-6.5&amp;lt;/pre&amp;gt;&lt;br /&gt;
Then to select the VM provider. Because I have both Virtualbox and VMware Desktop installed, there are two options on my screen&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vagrant box add chef/centos-6.5&lt;br /&gt;
==&amp;gt; box: Loading metadata for box 'chef/centos-6.5'&lt;br /&gt;
    box: URL: https://vagrantcloud.com/chef/centos-6.5&lt;br /&gt;
This box can work with multiple providers! The providers that it&lt;br /&gt;
can work with are listed below. Please review the list and choose&lt;br /&gt;
the provider you will be working with.&lt;br /&gt;
&lt;br /&gt;
1) virtualbox&lt;br /&gt;
2) vmware_desktop&lt;br /&gt;
&lt;br /&gt;
Enter your choice: 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Then it will start downloading the box&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
==&amp;gt; box: Adding box 'chef/centos-6.5' (v1.0.0) for provider: virtualbox&lt;br /&gt;
    box: Downloading: https://vagrantcloud.com/chef/boxes/centos-6.5/versions/1.0.0/providers/virtualbox.box&lt;br /&gt;
==&amp;gt; box: Successfully added box 'chef/centos-6.5' (v1.0.0) for 'virtualbox'!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For Ubuntu box, do the same procedures with Ubuntu's box name&lt;br /&gt;
&amp;lt;pre&amp;gt;vagrant box add ubuntu/trusty64&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Then we can check whether both boxes are successfully installed.&lt;br /&gt;
&amp;lt;pre&amp;gt;vagrant box list&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Configure Vagrantfile ===&lt;br /&gt;
Run &amp;lt;code&amp;gt;'''vagrant init'''&amp;lt;/code&amp;gt; to create a Vagrantfile or manually create one, then replace the content with the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# -*- mode: ruby -*-&lt;br /&gt;
# vi: set ft=ruby :&lt;br /&gt;
&lt;br /&gt;
VAGRANTFILE_API_VERSION = &amp;quot;2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|&lt;br /&gt;
  config.vm.define :host1 do |host1|&lt;br /&gt;
    host1.vm.box = &amp;quot;chef/centos-6.5&amp;quot;&lt;br /&gt;
    host1.vm.hostname = &amp;quot;host1&amp;quot;&lt;br /&gt;
    host1.vm.network :private_network, ip: &amp;quot;11.11.1.10&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  config.vm.define :host2 do |host2|&lt;br /&gt;
    host2.vm.box = &amp;quot;ubuntu/trusty64&amp;quot;&lt;br /&gt;
    host2.vm.hostname = &amp;quot;host2&amp;quot;&lt;br /&gt;
    host2.vm.network :private_network, ip: &amp;quot;11.11.1.11&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Boot up ===&lt;br /&gt;
Then run&lt;br /&gt;
&amp;lt;pre&amp;gt;vagrant up&amp;lt;/pre&amp;gt;&lt;br /&gt;
After the machines are booted up, you can do ssh to any one of them using:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vagrant ssh host1      or       vagrant ssh host2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
So let's ssh to host1 by &amp;lt;code&amp;gt;'''vagrant ssh host1'''&amp;lt;/code&amp;gt;, then I can ssh to host2 inside the host1:&lt;br /&gt;
&amp;lt;pre&amp;gt;[vagrant@host1 ~]$ ssh 11.11.1.11&amp;lt;/pre&amp;gt;&lt;br /&gt;
The default password is 'vagrant' (no single quotes).&lt;br /&gt;
Finally, if you can see &amp;lt;pre&amp;gt;vagrant@host2:~$&amp;lt;/pre&amp;gt; in your terminal, host2 is successfully connected!&lt;br /&gt;
=== Halt Vagrant VMs ===&lt;br /&gt;
&amp;lt;pre&amp;gt;vagrant halt host1      or       vagrant halt host2&amp;lt;/pre&amp;gt; to halt anyone of them or&lt;br /&gt;
&amp;lt;pre&amp;gt;vagrant halt&amp;lt;/pre&amp;gt; to halt both of them at once.&lt;br /&gt;
== References ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Szhang29</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_1_DZ&amp;diff=93094</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 1 DZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_1_DZ&amp;diff=93094"/>
		<updated>2015-02-05T02:56:51Z</updated>

		<summary type="html">&lt;p&gt;Szhang29: /* Vagrantfile */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Vagrant&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Vagrant''' is a computer software that helps create, configure and manage virtual development or work environments. With its great portability and compatibility, team members can share a common development environment. Therefore minimize the cost of time for deployment and maximize the productivity and flexibility.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
Vagrant works with mainstream virtualization softwares like [https://www.virtualbox.org/ VirtualBox], [http://www.vmware.com/ VMware] and [http://aws.amazon.com/ AWS] or [https://docs.vagrantup.com/v2/providers/ any other provider]. &lt;br /&gt;
=== Virtualization Machine ===&lt;br /&gt;
Virtualization machine, which is created by virtualization software, is an emulation of a real computer that provides a complete operating system. In other words, a virtual machine(VM) is a computer with a complete set of hardwares and operating system which runs in your own operating system. In that way, for example, one using Windows operating system can easily install Linux operating system in the VM rather than actually installing it on local machine. Therefore, any changes or modifications in the VM will not propagate to the operating system on which it runs. &lt;br /&gt;
&lt;br /&gt;
=== Vagrant Box ===&lt;br /&gt;
'''Boxes''' are the package format for Vagrant environments. In other words, a box is a packed operating system used by Vagrant. &amp;lt;code&amp;gt;'''vagrant box'''&amp;lt;/code&amp;gt; is the utility that downloads and manages different types of boxes.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'''vagrant box add {title} {url}'''&amp;lt;/code&amp;gt; can be executed under either Windows and Unix operating system to add a new box to Vagrant. &amp;lt;code&amp;gt;'''title'''&amp;lt;/code&amp;gt; is a identifier and can be any text, and &amp;lt;code&amp;gt;'''url'''&amp;lt;/code&amp;gt; is the network location of the box. &amp;lt;br&amp;gt;&lt;br /&gt;
For example: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'''vagrant box add base hashicorp/precise64'''&amp;lt;/code&amp;gt; downloads a standard Ubuntu 12.04 LTS 64-bit box from [https://atlas.hashicorp.com/boxes/search?utm_source=vagrantcloud.com&amp;amp;vagrantcloud=1 Vagrant Cloud].&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'''vagrant box add base https://dl.dropboxusercontent.com/u/29173892/vagrant-boxes/debian7.3.0-vbox4.3.6-puppet3.4.1.box'''&amp;lt;/code&amp;gt; downloads a Debian 7.3.0 64-bit Puppet 3.4.1 box which is shared by personal user.&lt;br /&gt;
&lt;br /&gt;
=== Vagrantfile ===&lt;br /&gt;
'''Vagrantfile''' is a configuration file which exists in every single vagrant folder. It is written in Ruby, probably looks like this: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vagrant.configure(2) do |config|&lt;br /&gt;
    config.vm.box = &amp;quot;hashicorp/precise32&amp;quot;&lt;br /&gt;
    # other configuration here&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;quot;2&amp;quot; in the first line is the version of configuration object &amp;lt;code&amp;gt;config&amp;lt;/code&amp;gt;. This number is either &amp;quot;1&amp;quot; for Vagrant 1.0.x, or &amp;quot;2&amp;quot; for Vagrant 1.1+. &amp;lt;br&amp;gt;&lt;br /&gt;
This file allows you to configure some basic settings (including shared folder location, cpu core number and etc.) of the virtual machine. For example: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.provider &amp;quot;virtualbox&amp;quot; do |vb|&lt;br /&gt;
    vb.memory = &amp;quot;1024&amp;quot;&lt;br /&gt;
    vb.cpus=&amp;quot;2&amp;quot;&lt;br /&gt;
    config.vm.network :forwarded_port, host: 8000, guest: 80&lt;br /&gt;
    config.vm.network :forwarded_port, host: 33060, guest: 33060&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This section of code specifies the memory and CPU core number of the virtual machine. Also, any network traffic on localhost:8000 and localhost:33060 will be forwarded to port 80 and 33060, respectively. &amp;lt;br&amp;gt;&lt;br /&gt;
Some more examples: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.synced_folder &amp;quot;src/&amp;quot;, &amp;quot;/srv/website&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This command is used to sync folder. The first parameter is a path to a directory on the host machine, the second parameter must be an absolute path of where to share the folder within the guest machine. &amp;lt;br&amp;gt;&lt;br /&gt;
By default, synced folders are mounted with the SSH user owner/group setting. You can mount them with a different owner and group using the configuration below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.synced_folder &amp;quot;src/&amp;quot;, &amp;quot;/srv/website&amp;quot;&lt;br /&gt;
  owner: &amp;quot;root&amp;quot;, group: &amp;quot;root&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Provision ===&lt;br /&gt;
Provision in Vagrant is a process of automatically install your own softwares and modify configurations during the VM booting up.&amp;lt;br&amp;gt;&lt;br /&gt;
Also, this process needs no human interaction and therefore makes it very convenient and repeatable. &amp;lt;br&amp;gt;&lt;br /&gt;
Every provisioner is configured within your Vagrantfile using the &amp;lt;code&amp;gt;config.vm.provision&amp;lt;/code&amp;gt; method call, for example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.provider &amp;quot;virtualbox&amp;quot; do |vb|&lt;br /&gt;
  config.vm.provision :shell, path: &amp;quot;bootstrap.sh&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This section of code enables &amp;lt;code&amp;gt;'''bootstrap.sh'''&amp;lt;/code&amp;gt; every time the VM is initialized or reloaded. &amp;lt;br&amp;gt;&lt;br /&gt;
Typically, provisioners are only run once, during the first &amp;lt;code&amp;gt;vagrant up&amp;lt;/code&amp;gt; since the last &amp;lt;code&amp;gt;vagrant destroy&amp;lt;/code&amp;gt;. If you want to run the provisioners on every &amp;lt;code&amp;gt;vagrant up&amp;lt;/code&amp;gt;, simply set the &amp;lt;code&amp;gt;run&amp;lt;/code&amp;gt; option to &amp;quot;always&amp;quot;, as shown below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.provider &amp;quot;virtualbox&amp;quot; do |vb|&lt;br /&gt;
  config.vm.provision :shell, path: &amp;quot;bootstrap.sh&amp;quot;&lt;br /&gt;
    run: &amp;quot;always&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How it works ==&lt;br /&gt;
=== Set up ===&lt;br /&gt;
'''Step 1: '''Install a mainstream VM software. (e.g. [https://www.virtualbox.org/wiki/Downloads VirtualBox Download Page])&amp;lt;br&amp;gt;&lt;br /&gt;
'''Step 2: '''Download [http://www.vagrantup.com/downloads Vagrant]&lt;br /&gt;
&lt;br /&gt;
=== Configure ===&lt;br /&gt;
'''Step 1: ''' &amp;lt;code&amp;gt;'''vagrant box add base hashicorp/precise32'''&amp;lt;/code&amp;gt; to add a Ubuntu 32bit base box&amp;lt;br&amp;gt;&lt;br /&gt;
The title &amp;quot;base&amp;quot; can be replaced with any text, also &amp;quot;hashicorp/precise32&amp;quot; is replaceable.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Step 2: ''' &amp;lt;code&amp;gt;'''vagrant init'''&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
If the title of the box is not &amp;quot;base&amp;quot;, then you will need to specify the title of the box. For example, &amp;lt;code&amp;gt;'''vagrant init &amp;quot;my own box&amp;quot; '''&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Work ===&lt;br /&gt;
'''Step 1: ''' &amp;lt;code&amp;gt;'''vagrant up'''&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;'''vagrant up --provision'''&amp;lt;/code&amp;gt; if you want to run the VM in provision mode.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Step 2: ''' &amp;lt;code&amp;gt;'''vagrant ssh'''&amp;lt;/code&amp;gt; to login to the virtual machine.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Reflist}}&lt;/div&gt;</summary>
		<author><name>Szhang29</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_1_DZ&amp;diff=93093</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 1 DZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_1_DZ&amp;diff=93093"/>
		<updated>2015-02-05T02:56:30Z</updated>

		<summary type="html">&lt;p&gt;Szhang29: /* Vagrantfile */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Vagrant&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Vagrant''' is a computer software that helps create, configure and manage virtual development or work environments. With its great portability and compatibility, team members can share a common development environment. Therefore minimize the cost of time for deployment and maximize the productivity and flexibility.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
Vagrant works with mainstream virtualization softwares like [https://www.virtualbox.org/ VirtualBox], [http://www.vmware.com/ VMware] and [http://aws.amazon.com/ AWS] or [https://docs.vagrantup.com/v2/providers/ any other provider]. &lt;br /&gt;
=== Virtualization Machine ===&lt;br /&gt;
Virtualization machine, which is created by virtualization software, is an emulation of a real computer that provides a complete operating system. In other words, a virtual machine(VM) is a computer with a complete set of hardwares and operating system which runs in your own operating system. In that way, for example, one using Windows operating system can easily install Linux operating system in the VM rather than actually installing it on local machine. Therefore, any changes or modifications in the VM will not propagate to the operating system on which it runs. &lt;br /&gt;
&lt;br /&gt;
=== Vagrant Box ===&lt;br /&gt;
'''Boxes''' are the package format for Vagrant environments. In other words, a box is a packed operating system used by Vagrant. &amp;lt;code&amp;gt;'''vagrant box'''&amp;lt;/code&amp;gt; is the utility that downloads and manages different types of boxes.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'''vagrant box add {title} {url}'''&amp;lt;/code&amp;gt; can be executed under either Windows and Unix operating system to add a new box to Vagrant. &amp;lt;code&amp;gt;'''title'''&amp;lt;/code&amp;gt; is a identifier and can be any text, and &amp;lt;code&amp;gt;'''url'''&amp;lt;/code&amp;gt; is the network location of the box. &amp;lt;br&amp;gt;&lt;br /&gt;
For example: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'''vagrant box add base hashicorp/precise64'''&amp;lt;/code&amp;gt; downloads a standard Ubuntu 12.04 LTS 64-bit box from [https://atlas.hashicorp.com/boxes/search?utm_source=vagrantcloud.com&amp;amp;vagrantcloud=1 Vagrant Cloud].&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'''vagrant box add base https://dl.dropboxusercontent.com/u/29173892/vagrant-boxes/debian7.3.0-vbox4.3.6-puppet3.4.1.box'''&amp;lt;/code&amp;gt; downloads a Debian 7.3.0 64-bit Puppet 3.4.1 box which is shared by personal user.&lt;br /&gt;
&lt;br /&gt;
=== Vagrantfile ===&lt;br /&gt;
'''Vagrantfile''' is a configuration file which exists in every single vagrant folder. It is written in Ruby, probably looks like this: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vagrant.configure(2) do |config|&lt;br /&gt;
    config.vm.box = &amp;quot;hashicorp/precise32&amp;quot;&lt;br /&gt;
    # other configuration here&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;quot;2&amp;quot; in the first line is the version of configuration object &amp;lt;code&amp;gt;config&amp;lt;/code&amp;gt;. This number is either &amp;quot;1&amp;quot; for Vagrant 1.0.x, or &amp;quot;2&amp;quot; for Vagrant 1.1+. &amp;lt;br&amp;gt;&lt;br /&gt;
This file allows you to configure some basic settings (including shared folder location, cpu core number and etc.) of the virtual machine. For example: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.provider &amp;quot;virtualbox&amp;quot; do |vb|&lt;br /&gt;
    vb.memory = &amp;quot;1024&amp;quot;&lt;br /&gt;
    vb.cpus=&amp;quot;2&amp;quot;&lt;br /&gt;
    config.vm.network :forwarded_port, host: 8000, guest: 80&lt;br /&gt;
    config.vm.network :forwarded_port, host: 33060, guest: 33060&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This section of code specifies the memory and CPU core number of the virtual machine. Also, any network traffic on localhost:8000 and localhost:33060 will be forwarded to port 80 and 33060, respectively. &amp;lt;br&amp;gt;&lt;br /&gt;
Some more examples: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.synced_folder &amp;quot;src/&amp;quot;, &amp;quot;/srv/website&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This command is used to sync folder. The first parameter is a path to a directory on the host machine, the second parameter must be an absolute path of where to share the folder within the guest machine.&lt;br /&gt;
By default, synced folders are mounted with the SSH user owner/group setting. You can mount them with a different owner and group using the configuration below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.synced_folder &amp;quot;src/&amp;quot;, &amp;quot;/srv/website&amp;quot;&lt;br /&gt;
  owner: &amp;quot;root&amp;quot;, group: &amp;quot;root&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Provision ===&lt;br /&gt;
Provision in Vagrant is a process of automatically install your own softwares and modify configurations during the VM booting up.&amp;lt;br&amp;gt;&lt;br /&gt;
Also, this process needs no human interaction and therefore makes it very convenient and repeatable. &amp;lt;br&amp;gt;&lt;br /&gt;
Every provisioner is configured within your Vagrantfile using the &amp;lt;code&amp;gt;config.vm.provision&amp;lt;/code&amp;gt; method call, for example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.provider &amp;quot;virtualbox&amp;quot; do |vb|&lt;br /&gt;
  config.vm.provision :shell, path: &amp;quot;bootstrap.sh&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This section of code enables &amp;lt;code&amp;gt;'''bootstrap.sh'''&amp;lt;/code&amp;gt; every time the VM is initialized or reloaded. &amp;lt;br&amp;gt;&lt;br /&gt;
Typically, provisioners are only run once, during the first &amp;lt;code&amp;gt;vagrant up&amp;lt;/code&amp;gt; since the last &amp;lt;code&amp;gt;vagrant destroy&amp;lt;/code&amp;gt;. If you want to run the provisioners on every &amp;lt;code&amp;gt;vagrant up&amp;lt;/code&amp;gt;, simply set the &amp;lt;code&amp;gt;run&amp;lt;/code&amp;gt; option to &amp;quot;always&amp;quot;, as shown below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.provider &amp;quot;virtualbox&amp;quot; do |vb|&lt;br /&gt;
  config.vm.provision :shell, path: &amp;quot;bootstrap.sh&amp;quot;&lt;br /&gt;
    run: &amp;quot;always&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How it works ==&lt;br /&gt;
=== Set up ===&lt;br /&gt;
'''Step 1: '''Install a mainstream VM software. (e.g. [https://www.virtualbox.org/wiki/Downloads VirtualBox Download Page])&amp;lt;br&amp;gt;&lt;br /&gt;
'''Step 2: '''Download [http://www.vagrantup.com/downloads Vagrant]&lt;br /&gt;
&lt;br /&gt;
=== Configure ===&lt;br /&gt;
'''Step 1: ''' &amp;lt;code&amp;gt;'''vagrant box add base hashicorp/precise32'''&amp;lt;/code&amp;gt; to add a Ubuntu 32bit base box&amp;lt;br&amp;gt;&lt;br /&gt;
The title &amp;quot;base&amp;quot; can be replaced with any text, also &amp;quot;hashicorp/precise32&amp;quot; is replaceable.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Step 2: ''' &amp;lt;code&amp;gt;'''vagrant init'''&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
If the title of the box is not &amp;quot;base&amp;quot;, then you will need to specify the title of the box. For example, &amp;lt;code&amp;gt;'''vagrant init &amp;quot;my own box&amp;quot; '''&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Work ===&lt;br /&gt;
'''Step 1: ''' &amp;lt;code&amp;gt;'''vagrant up'''&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;'''vagrant up --provision'''&amp;lt;/code&amp;gt; if you want to run the VM in provision mode.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Step 2: ''' &amp;lt;code&amp;gt;'''vagrant ssh'''&amp;lt;/code&amp;gt; to login to the virtual machine.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Reflist}}&lt;/div&gt;</summary>
		<author><name>Szhang29</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_1_DZ&amp;diff=93092</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 1 DZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_1_DZ&amp;diff=93092"/>
		<updated>2015-02-05T02:40:04Z</updated>

		<summary type="html">&lt;p&gt;Szhang29: /* Vagrantfile */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Vagrant&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Vagrant''' is a computer software that helps create, configure and manage virtual development or work environments. With its great portability and compatibility, team members can share a common development environment. Therefore minimize the cost of time for deployment and maximize the productivity and flexibility.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
Vagrant works with mainstream virtualization softwares like [https://www.virtualbox.org/ VirtualBox], [http://www.vmware.com/ VMware] and [http://aws.amazon.com/ AWS] or [https://docs.vagrantup.com/v2/providers/ any other provider]. &lt;br /&gt;
=== Virtualization Machine ===&lt;br /&gt;
Virtualization machine, which is created by virtualization software, is an emulation of a real computer that provides a complete operating system. In other words, a virtual machine(VM) is a computer with a complete set of hardwares and operating system which runs in your own operating system. In that way, for example, one using Windows operating system can easily install Linux operating system in the VM rather than actually installing it on local machine. Therefore, any changes or modifications in the VM will not propagate to the operating system on which it runs. &lt;br /&gt;
&lt;br /&gt;
=== Vagrant Box ===&lt;br /&gt;
'''Boxes''' are the package format for Vagrant environments. In other words, a box is a packed operating system used by Vagrant. &amp;lt;code&amp;gt;'''vagrant box'''&amp;lt;/code&amp;gt; is the utility that downloads and manages different types of boxes.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'''vagrant box add {title} {url}'''&amp;lt;/code&amp;gt; can be executed under either Windows and Unix operating system to add a new box to Vagrant. &amp;lt;code&amp;gt;'''title'''&amp;lt;/code&amp;gt; is a identifier and can be any text, and &amp;lt;code&amp;gt;'''url'''&amp;lt;/code&amp;gt; is the network location of the box. &amp;lt;br&amp;gt;&lt;br /&gt;
For example: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'''vagrant box add base hashicorp/precise64'''&amp;lt;/code&amp;gt; downloads a standard Ubuntu 12.04 LTS 64-bit box from [https://atlas.hashicorp.com/boxes/search?utm_source=vagrantcloud.com&amp;amp;vagrantcloud=1 Vagrant Cloud].&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'''vagrant box add base https://dl.dropboxusercontent.com/u/29173892/vagrant-boxes/debian7.3.0-vbox4.3.6-puppet3.4.1.box'''&amp;lt;/code&amp;gt; downloads a Debian 7.3.0 64-bit Puppet 3.4.1 box which is shared by personal user.&lt;br /&gt;
&lt;br /&gt;
=== Vagrantfile ===&lt;br /&gt;
'''Vagrantfile''' is a configuration file which exists in every single vagrant folder. It is written in Ruby, probably looks like this: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vagrant.configure(2) do |config|&lt;br /&gt;
    config.vm.box = &amp;quot;hashicorp/precise32&amp;quot;&lt;br /&gt;
    # other configuration here&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;quot;2&amp;quot; in the first line is the version of configuration object &amp;lt;code&amp;gt;config&amp;lt;/code&amp;gt;. This number is either &amp;quot;1&amp;quot; for Vagrant 1.0.x, or &amp;quot;2&amp;quot; for Vagrant 1.1+. &amp;lt;br&amp;gt;&lt;br /&gt;
This file allows you to configure some basic settings (including shared folder location, cpu core number and etc.) of the virtual machine. For example: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.provider &amp;quot;virtualbox&amp;quot; do |vb|&lt;br /&gt;
    vb.memory = &amp;quot;1024&amp;quot;&lt;br /&gt;
    vb.cpus=&amp;quot;2&amp;quot;&lt;br /&gt;
    config.vm.network :forwarded_port, host: 8000, guest: 80&lt;br /&gt;
    config.vm.network :forwarded_port, host: 33060, guest: 33060&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This section of code specifies the memory and CPU core number of the virtual machine. Also, any network traffic on localhost:8000 and localhost:33060 will be forwarded to port 80 and 33060, respectively. &amp;lt;br&amp;gt;&lt;br /&gt;
Some more examples: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.synced_folder &amp;quot;src/&amp;quot;, &amp;quot;/srv/website&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This command is used to sync folder. The first parameter is a path to a directory on the host machine, the second parameter must be an absolute path of where to share the folder within the guest machine.&lt;br /&gt;
&lt;br /&gt;
=== Provision ===&lt;br /&gt;
Provision in Vagrant is a process of automatically install your own softwares and modify configurations during the VM booting up.&amp;lt;br&amp;gt;&lt;br /&gt;
Also, this process needs no human interaction and therefore makes it very convenient and repeatable. &amp;lt;br&amp;gt;&lt;br /&gt;
Every provisioner is configured within your Vagrantfile using the &amp;lt;code&amp;gt;config.vm.provision&amp;lt;/code&amp;gt; method call, for example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.provider &amp;quot;virtualbox&amp;quot; do |vb|&lt;br /&gt;
  config.vm.provision :shell, path: &amp;quot;bootstrap.sh&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This section of code enables &amp;lt;code&amp;gt;'''bootstrap.sh'''&amp;lt;/code&amp;gt; every time the VM is initialized or reloaded. &amp;lt;br&amp;gt;&lt;br /&gt;
Typically, provisioners are only run once, during the first &amp;lt;code&amp;gt;vagrant up&amp;lt;/code&amp;gt; since the last &amp;lt;code&amp;gt;vagrant destroy&amp;lt;/code&amp;gt;. If you want to run the provisioners on every &amp;lt;code&amp;gt;vagrant up&amp;lt;/code&amp;gt;, simply set the &amp;lt;code&amp;gt;run&amp;lt;/code&amp;gt; option to &amp;quot;always&amp;quot;, as shown below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.provider &amp;quot;virtualbox&amp;quot; do |vb|&lt;br /&gt;
  config.vm.provision :shell, path: &amp;quot;bootstrap.sh&amp;quot;&lt;br /&gt;
    run: &amp;quot;always&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How it works ==&lt;br /&gt;
=== Set up ===&lt;br /&gt;
'''Step 1: '''Install a mainstream VM software. (e.g. [https://www.virtualbox.org/wiki/Downloads VirtualBox Download Page])&amp;lt;br&amp;gt;&lt;br /&gt;
'''Step 2: '''Download [http://www.vagrantup.com/downloads Vagrant]&lt;br /&gt;
&lt;br /&gt;
=== Configure ===&lt;br /&gt;
'''Step 1: ''' &amp;lt;code&amp;gt;'''vagrant box add base hashicorp/precise32'''&amp;lt;/code&amp;gt; to add a Ubuntu 32bit base box&amp;lt;br&amp;gt;&lt;br /&gt;
The title &amp;quot;base&amp;quot; can be replaced with any text, also &amp;quot;hashicorp/precise32&amp;quot; is replaceable.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Step 2: ''' &amp;lt;code&amp;gt;'''vagrant init'''&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
If the title of the box is not &amp;quot;base&amp;quot;, then you will need to specify the title of the box. For example, &amp;lt;code&amp;gt;'''vagrant init &amp;quot;my own box&amp;quot; '''&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Work ===&lt;br /&gt;
'''Step 1: ''' &amp;lt;code&amp;gt;'''vagrant up'''&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;'''vagrant up --provision'''&amp;lt;/code&amp;gt; if you want to run the VM in provision mode.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Step 2: ''' &amp;lt;code&amp;gt;'''vagrant ssh'''&amp;lt;/code&amp;gt; to login to the virtual machine.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Reflist}}&lt;/div&gt;</summary>
		<author><name>Szhang29</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_1_DZ&amp;diff=93091</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 1 DZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_1_DZ&amp;diff=93091"/>
		<updated>2015-02-05T02:39:31Z</updated>

		<summary type="html">&lt;p&gt;Szhang29: /* Provision */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Vagrant&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Vagrant''' is a computer software that helps create, configure and manage virtual development or work environments. With its great portability and compatibility, team members can share a common development environment. Therefore minimize the cost of time for deployment and maximize the productivity and flexibility.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
Vagrant works with mainstream virtualization softwares like [https://www.virtualbox.org/ VirtualBox], [http://www.vmware.com/ VMware] and [http://aws.amazon.com/ AWS] or [https://docs.vagrantup.com/v2/providers/ any other provider]. &lt;br /&gt;
=== Virtualization Machine ===&lt;br /&gt;
Virtualization machine, which is created by virtualization software, is an emulation of a real computer that provides a complete operating system. In other words, a virtual machine(VM) is a computer with a complete set of hardwares and operating system which runs in your own operating system. In that way, for example, one using Windows operating system can easily install Linux operating system in the VM rather than actually installing it on local machine. Therefore, any changes or modifications in the VM will not propagate to the operating system on which it runs. &lt;br /&gt;
&lt;br /&gt;
=== Vagrant Box ===&lt;br /&gt;
'''Boxes''' are the package format for Vagrant environments. In other words, a box is a packed operating system used by Vagrant. &amp;lt;code&amp;gt;'''vagrant box'''&amp;lt;/code&amp;gt; is the utility that downloads and manages different types of boxes.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'''vagrant box add {title} {url}'''&amp;lt;/code&amp;gt; can be executed under either Windows and Unix operating system to add a new box to Vagrant. &amp;lt;code&amp;gt;'''title'''&amp;lt;/code&amp;gt; is a identifier and can be any text, and &amp;lt;code&amp;gt;'''url'''&amp;lt;/code&amp;gt; is the network location of the box. &amp;lt;br&amp;gt;&lt;br /&gt;
For example: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'''vagrant box add base hashicorp/precise64'''&amp;lt;/code&amp;gt; downloads a standard Ubuntu 12.04 LTS 64-bit box from [https://atlas.hashicorp.com/boxes/search?utm_source=vagrantcloud.com&amp;amp;vagrantcloud=1 Vagrant Cloud].&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'''vagrant box add base https://dl.dropboxusercontent.com/u/29173892/vagrant-boxes/debian7.3.0-vbox4.3.6-puppet3.4.1.box'''&amp;lt;/code&amp;gt; downloads a Debian 7.3.0 64-bit Puppet 3.4.1 box which is shared by personal user.&lt;br /&gt;
&lt;br /&gt;
=== Vagrantfile ===&lt;br /&gt;
'''Vagrantfile''' is a configuration file which exists in every single vagrant folder. It is written in Ruby, probably looks like this: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vagrant.configure(2) do |config|&lt;br /&gt;
    config.vm.box = &amp;quot;hashicorp/precise32&amp;quot;&lt;br /&gt;
    # other configuration here&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;quot;2&amp;quot; in the first line is the version of configuration object '''config'''. This number is either &amp;quot;1&amp;quot; for Vagrant 1.0.x, or &amp;quot;2&amp;quot; for Vagrant 1.1+. &amp;lt;br&amp;gt;&lt;br /&gt;
This file allows you to configure some basic settings (including shared folder location, cpu core number and etc.) of the virtual machine. For example: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.provider &amp;quot;virtualbox&amp;quot; do |vb|&lt;br /&gt;
    vb.memory = &amp;quot;1024&amp;quot;&lt;br /&gt;
    vb.cpus=&amp;quot;2&amp;quot;&lt;br /&gt;
    config.vm.network :forwarded_port, host: 8000, guest: 80&lt;br /&gt;
    config.vm.network :forwarded_port, host: 33060, guest: 33060&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This section of code specifies the memory and CPU core number of the virtual machine. Also, any network traffic on localhost:8000 and localhost:33060 will be forwarded to port 80 and 33060, respectively. &amp;lt;br&amp;gt;&lt;br /&gt;
Some more examples: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.synced_folder &amp;quot;src/&amp;quot;, &amp;quot;/srv/website&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This command is used to sync folder. The first parameter is a path to a directory on the host machine, the second parameter must be an absolute path of where to share the folder within the guest machine.&lt;br /&gt;
&lt;br /&gt;
=== Provision ===&lt;br /&gt;
Provision in Vagrant is a process of automatically install your own softwares and modify configurations during the VM booting up.&amp;lt;br&amp;gt;&lt;br /&gt;
Also, this process needs no human interaction and therefore makes it very convenient and repeatable. &amp;lt;br&amp;gt;&lt;br /&gt;
Every provisioner is configured within your Vagrantfile using the &amp;lt;code&amp;gt;config.vm.provision&amp;lt;/code&amp;gt; method call, for example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.provider &amp;quot;virtualbox&amp;quot; do |vb|&lt;br /&gt;
  config.vm.provision :shell, path: &amp;quot;bootstrap.sh&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This section of code enables &amp;lt;code&amp;gt;'''bootstrap.sh'''&amp;lt;/code&amp;gt; every time the VM is initialized or reloaded. &amp;lt;br&amp;gt;&lt;br /&gt;
Typically, provisioners are only run once, during the first &amp;lt;code&amp;gt;vagrant up&amp;lt;/code&amp;gt; since the last &amp;lt;code&amp;gt;vagrant destroy&amp;lt;/code&amp;gt;. If you want to run the provisioners on every &amp;lt;code&amp;gt;vagrant up&amp;lt;/code&amp;gt;, simply set the &amp;lt;code&amp;gt;run&amp;lt;/code&amp;gt; option to &amp;quot;always&amp;quot;, as shown below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.provider &amp;quot;virtualbox&amp;quot; do |vb|&lt;br /&gt;
  config.vm.provision :shell, path: &amp;quot;bootstrap.sh&amp;quot;&lt;br /&gt;
    run: &amp;quot;always&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How it works ==&lt;br /&gt;
=== Set up ===&lt;br /&gt;
'''Step 1: '''Install a mainstream VM software. (e.g. [https://www.virtualbox.org/wiki/Downloads VirtualBox Download Page])&amp;lt;br&amp;gt;&lt;br /&gt;
'''Step 2: '''Download [http://www.vagrantup.com/downloads Vagrant]&lt;br /&gt;
&lt;br /&gt;
=== Configure ===&lt;br /&gt;
'''Step 1: ''' &amp;lt;code&amp;gt;'''vagrant box add base hashicorp/precise32'''&amp;lt;/code&amp;gt; to add a Ubuntu 32bit base box&amp;lt;br&amp;gt;&lt;br /&gt;
The title &amp;quot;base&amp;quot; can be replaced with any text, also &amp;quot;hashicorp/precise32&amp;quot; is replaceable.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Step 2: ''' &amp;lt;code&amp;gt;'''vagrant init'''&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
If the title of the box is not &amp;quot;base&amp;quot;, then you will need to specify the title of the box. For example, &amp;lt;code&amp;gt;'''vagrant init &amp;quot;my own box&amp;quot; '''&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Work ===&lt;br /&gt;
'''Step 1: ''' &amp;lt;code&amp;gt;'''vagrant up'''&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;'''vagrant up --provision'''&amp;lt;/code&amp;gt; if you want to run the VM in provision mode.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Step 2: ''' &amp;lt;code&amp;gt;'''vagrant ssh'''&amp;lt;/code&amp;gt; to login to the virtual machine.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Reflist}}&lt;/div&gt;</summary>
		<author><name>Szhang29</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_1_DZ&amp;diff=93090</id>
		<title>CSC/ECE 517 Spring 2015/ch1a 1 DZ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015/ch1a_1_DZ&amp;diff=93090"/>
		<updated>2015-02-05T02:21:37Z</updated>

		<summary type="html">&lt;p&gt;Szhang29: /* Vagrantfile */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Vagrant&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Vagrant''' is a computer software that helps create, configure and manage virtual development or work environments. With its great portability and compatibility, team members can share a common development environment. Therefore minimize the cost of time for deployment and maximize the productivity and flexibility.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
Vagrant works with mainstream virtualization softwares like [https://www.virtualbox.org/ VirtualBox], [http://www.vmware.com/ VMware] and [http://aws.amazon.com/ AWS] or [https://docs.vagrantup.com/v2/providers/ any other provider]. &lt;br /&gt;
=== Virtualization Machine ===&lt;br /&gt;
Virtualization machine, which is created by virtualization software, is an emulation of a real computer that provides a complete operating system. In other words, a virtual machine(VM) is a computer with a complete set of hardwares and operating system which runs in your own operating system. In that way, for example, one using Windows operating system can easily install Linux operating system in the VM rather than actually installing it on local machine. Therefore, any changes or modifications in the VM will not propagate to the operating system on which it runs. &lt;br /&gt;
&lt;br /&gt;
=== Vagrant Box ===&lt;br /&gt;
'''Boxes''' are the package format for Vagrant environments. In other words, a box is a packed operating system used by Vagrant. &amp;lt;code&amp;gt;'''vagrant box'''&amp;lt;/code&amp;gt; is the utility that downloads and manages different types of boxes.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'''vagrant box add {title} {url}'''&amp;lt;/code&amp;gt; can be executed under either Windows and Unix operating system to add a new box to Vagrant. &amp;lt;code&amp;gt;'''title'''&amp;lt;/code&amp;gt; is a identifier and can be any text, and &amp;lt;code&amp;gt;'''url'''&amp;lt;/code&amp;gt; is the network location of the box. &amp;lt;br&amp;gt;&lt;br /&gt;
For example: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'''vagrant box add base hashicorp/precise64'''&amp;lt;/code&amp;gt; downloads a standard Ubuntu 12.04 LTS 64-bit box from [https://atlas.hashicorp.com/boxes/search?utm_source=vagrantcloud.com&amp;amp;vagrantcloud=1 Vagrant Cloud].&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'''vagrant box add base https://dl.dropboxusercontent.com/u/29173892/vagrant-boxes/debian7.3.0-vbox4.3.6-puppet3.4.1.box'''&amp;lt;/code&amp;gt; downloads a Debian 7.3.0 64-bit Puppet 3.4.1 box which is shared by personal user.&lt;br /&gt;
&lt;br /&gt;
=== Vagrantfile ===&lt;br /&gt;
'''Vagrantfile''' is a configuration file which exists in every single vagrant folder. It is written in Ruby, probably looks like this: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vagrant.configure(2) do |config|&lt;br /&gt;
    config.vm.box = &amp;quot;hashicorp/precise32&amp;quot;&lt;br /&gt;
    # other configuration here&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;quot;2&amp;quot; in the first line is the version of configuration object '''config'''. This number is either &amp;quot;1&amp;quot; for Vagrant 1.0.x, or &amp;quot;2&amp;quot; for Vagrant 1.1+. &amp;lt;br&amp;gt;&lt;br /&gt;
This file allows you to configure some basic settings (including shared folder location, cpu core number and etc.) of the virtual machine. For example: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.provider &amp;quot;virtualbox&amp;quot; do |vb|&lt;br /&gt;
    vb.memory = &amp;quot;1024&amp;quot;&lt;br /&gt;
    vb.cpus=&amp;quot;2&amp;quot;&lt;br /&gt;
    config.vm.network :forwarded_port, host: 8000, guest: 80&lt;br /&gt;
    config.vm.network :forwarded_port, host: 33060, guest: 33060&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This section of code specifies the memory and CPU core number of the virtual machine. Also, any network traffic on localhost:8000 and localhost:33060 will be forwarded to port 80 and 33060, respectively. &amp;lt;br&amp;gt;&lt;br /&gt;
Some more examples: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.synced_folder &amp;quot;src/&amp;quot;, &amp;quot;/srv/website&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This command is used to sync folder. The first parameter is a path to a directory on the host machine, the second parameter must be an absolute path of where to share the folder within the guest machine.&lt;br /&gt;
&lt;br /&gt;
=== Provision ===&lt;br /&gt;
Provision in Vagrant is a process of automatically install your own softwares and modify configurations during the VM booting up.&amp;lt;br&amp;gt;&lt;br /&gt;
Also, this process needs no human interaction and therefore makes it very convenient and repeatable.&lt;br /&gt;
For example,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config.vm.provider &amp;quot;virtualbox&amp;quot; do |vb|&lt;br /&gt;
    config.vm.provision :shell, path: &amp;quot;bootstrap.sh&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This section of code enables &amp;lt;code&amp;gt;'''bootstrap.sh'''&amp;lt;/code&amp;gt; every time the VM is initialized or reloaded.&lt;br /&gt;
&lt;br /&gt;
== How it works ==&lt;br /&gt;
=== Set up ===&lt;br /&gt;
'''Step 1: '''Install a mainstream VM software. (e.g. [https://www.virtualbox.org/wiki/Downloads VirtualBox Download Page])&amp;lt;br&amp;gt;&lt;br /&gt;
'''Step 2: '''Download [http://www.vagrantup.com/downloads Vagrant]&lt;br /&gt;
&lt;br /&gt;
=== Configure ===&lt;br /&gt;
'''Step 1: ''' &amp;lt;code&amp;gt;'''vagrant box add base hashicorp/precise32'''&amp;lt;/code&amp;gt; to add a Ubuntu 32bit base box&amp;lt;br&amp;gt;&lt;br /&gt;
The title &amp;quot;base&amp;quot; can be replaced with any text, also &amp;quot;hashicorp/precise32&amp;quot; is replaceable.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Step 2: ''' &amp;lt;code&amp;gt;'''vagrant init'''&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
If the title of the box is not &amp;quot;base&amp;quot;, then you will need to specify the title of the box. For example, &amp;lt;code&amp;gt;'''vagrant init &amp;quot;my own box&amp;quot; '''&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Work ===&lt;br /&gt;
'''Step 1: ''' &amp;lt;code&amp;gt;'''vagrant up'''&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;'''vagrant up --provision'''&amp;lt;/code&amp;gt; if you want to run the VM in provision mode.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Step 2: ''' &amp;lt;code&amp;gt;'''vagrant ssh'''&amp;lt;/code&amp;gt; to login to the virtual machine.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Reflist}}&lt;/div&gt;</summary>
		<author><name>Szhang29</name></author>
	</entry>
</feed>