MarkUs Blog

MarkUs Developers Blog About Their Project

Archive for the ‘Missing Features’ Category

Resources for bug tracking in MarkUs

with 4 comments

The developers of MarkUs use GitHub’s issue tracking system to handle all the bugs floating around our application. It is a very useful system for maintaining current and old bugs, requests for new features and represents the overall state and goals of MarkUs.

Unfortunately, our users do not have the chance to see this unless they try hunting it down themselves. I’m currently working on a feature to point our users to our bug tracker, providing them with easy access to the ability to view and report bugs at their convenience. Here is some sample UI that I’m brainstorming. I’ve come up with some rough drafts of UI that I will most likely use.

The Header

I’d like to add an icon that is placed in the header, providing users with access to it no matter which page they are viewing.

Bug Icon located in the header

The Popup

Once the icon is clicked, a modal dialog will open, disabling the rest of the webpage. The user will see the following options.

Bug modal dialog prompt

View current issues will point to the bug tracker. Reporting a new issue will point them to a blank issue form and requesting a new feature/enhancement will point to the same form but with the RFE label set already. All of these links will open new tabs and redirect to our tracker accordingly.

Drawbacks

In order to file issues, you will need to have a GitHub account. Users might not be bothered to sign up (or even sign in), making this feature practically useless to them. Unfortunately, there is not much we can do with our given resources. Forcing them to use our tracker will help keep things centralized and in one place, rather than setting up some kind of form that sends out emails to mailing lists with the given bugs. Fortunately, the links redirect to logging in or creating a new account and then redirect back once done. If the user is willing to follow through, the login process is just a small, extra step and places the user back on track.

Another issue is the potential increase in duplicate bugs. Some people do not have time to read through our current issues and may just jump straight to reporting one. This is not too disruptive but adds to a teadious process for developers now having to close duplicate issues. I am hoping that the “View current issues” link will nudge users in that direction first but that will not always happen.

Finally, some issues are not in the application but in the way it was setup. These need to be directed to the course admin rather than to us. However, this is not always obvious so adding this feature might also cause an overflow of unnecessary bugs. This can be avoided by only displaying the links in the dialog when the user is an admin. When a grader or student is logged in, perhaps a simple message telling them to contact their course administrator/instructor might suffice.

 

This is what I have come up with but I am open to suggestions, please nitpick, modify and comment away!

Written by Danesh

February 26th, 2012 at 8:22 pm

Posted in Uncategorized

Repository Names Generated by MarkUs

with 2 comments

I have been working on ticket #537 again. There is still this old review request this sitting around (see http://review.markusproject.org/r/327/). The idea was that MarkUs should use a student’s username as the name of the Subversion repository created. This makes remembering student’s repository names easier. As simple as it sounded initially, there are some delicate corner cases to deal with.

  1. MarkUs allows instructors to reuse groups from previous assignments. Motivation for this feature was as follows. Students work on assignments alone throughout the term. In this case there is no need for students to form groups for each assignment. Students work alone anyway and once they’ve logged in a repository will be created for them (alternatively, an instructor has groups already set up so that students have repositories right away). The idea is to have students commit their code into these repositories created by MarkUs. It would be overkill, though, to create a brand new repository (and groups) for each assignment. So there is the possibility for instructors to set things up in a way that repositories are created once. But since the repositories already exist for later assignments we need a way to link those existing repositories with new groups for a new assignment. So one way is to use the “Use another assignment’s groups” feature. So far so good. But what if an instructor wants to have single student groups for A1 (allowing Subversion command line commits only) but wants to allow students to submit via MarkUs web interface for a small lab exercise? Assume for the lab exercise they would be allowed to form groups of two. Problem: If we would allow cloning groups forward for assignments for which web submissions are allowed, MarkUs could potentially link to the repository of A1. So things could end up in a repository called “c5anthei” and student c5bloche and c5anthei would be able to submit to it via the web interface. This seems a bit awkward, since the idea is to have repositories named after the student’s username only when it’s a single student assignment and it’s a command line commit only assignment. Solution: Cloning groupings forward for assignments won’t be allowed for assignments which enable MarkUs’ web submission interface.
  2. Using student’s usernames as the repository name opens up the possibility of repository collisions. I.e. MarkUs could end up trying to create a repository twice with the very same name (just imagine an instructor uploading the very same CSV groups file twice). Solution: This will happen for single student and non-web-submit assignments only. If a collision occurs the repository already exists, but that’s everything the CSV upload tries to achieve (apart from creating the groupings in MarkUs). But since MarkUs won’t create a repository if it already exists, this is a minor concern. This cannot happen for web submit assignments, because in this case a unique name for the repository will be generated. If a repository collision happens during a CSV upload, MarkUs will notify the instructor about it.
  3. MarkUs “recycles” groups. MarkUs internally knows about groupings and groups. A grouping is basically a snapshot of students and their memberships in groups for a particular assignment. In fact, when you create a “Group” (in the usual sense) using MarkUs’ web interface a grouping will be created. If a group object does not exist yet, it will be created too. This behaviour might be different for the next grouping, because a group object with the required name might already exist in the database. I.e. if a group with a particular name already exists, MarkUs will try to reuse it. Thus, it’s theoretically possible to create a group “Beta 10” for assignment 1 (say for A1 students work alone and have to commit via command line client). Then for A2, say, the instructor wants to create group “Beta 10” again, now allowing web interface submits and groups > 1 members. In that case MarkUs will find group “Beta 10” in the database and will try to use this group instead of creating a brand new object. This is a problem if an instructor would pick a group name which is equal to a student’s username. We’d end up in a similar situation as described in (1). Solution: I think, the most clean solution is to require instructors to use the user’s username as the group name (and those groups can have one group member at most). Otherwise, an autogenerated repository name will be used.

Those three corner cases are the ones I could think of so far. I’m not sure if we are still missing some. Let me know if there is a problem with my reasoning or if there are other cases I haven’t thought of, yet. Thanks! I’ll post an updated review shortly.

Edit: Considering that the repository name will be set in this special way for one member only groups, some of those cases might occur very rarely (if at all). Solution to (3) also means that it should be impossible to produce repository collisions. What do you think?

Written by Severin

May 1st, 2010 at 8:06 pm

Posted in Uncategorized

New Notables

without comments

The other evening I worked on the New Notes page.

The current one (left) deals only with Groupings. First you select the assignment, and then you select the grouping that you want to write the note about. It dynamically updates the Groupings drop down with the associated group names when you select an Assignment.

This is very good behaviour!

The task I set for myself was to extend this type of thing to our new noteables, Assignments and Students.

One way about it would be to have a separate form link for each type, before getting to the proper form. That has the downside of requiring additional page loads and then you need to start back at the hub page if you change your mind about what you want to write notes about.

The approach that I’m taking is to have an additional drop box where you first select the Notable type, and the rest of the form changes as required to select the exact object you want to create the note on. This way, less page loads, and hopefully, less work for me, as I don’t wish to refactor the entire notes system for a minor bit of convenience.

What convenience and I talking about? Well, it’s entirely possible to write a completely general system that automatically creates the form I want whenever we add the notable property to a model. However, that would take me longer than I have left in the term to do properly, and further isn’t really necessary. Such a solution would be the epitome of the Rails DRY philosophy.

It’s not a good idea though. When adhering to a philosophy involves more work than the less elegant but simpler solution, it’s not the solution you want to implement.

So my approach will be thus: have a static list of notable types and partials forms we want to render. We have one partial form for each, and whenever we observe the Notables box changing, we use a little bit of AJAX magic to render the new part of the form.

With that said, let’s see what we have now:


<div id="title_bar"><h1><%=I18n.t('notes.new.title')%></h1></div>
<div>
<% form_for :note, :url => {:action => 'create'} do |f| %>
<%= f.error_messages %>
<fieldset>
<p>
<%= f.label :assignment_id %>
<%= select_tag "assignment_id", options_from_collection_for_select(@assignments, :id, :short_identifier),
\:onchange => remote_function(:url => { :action => 'new_update_groupings' },
:with => 'Form.Element.serialize(this)',
:before => "Element.show('loading_groupings')",
:success => "Element.hide('loading_groupings')") %>
</p>
<p>
<%= f.label :noteable_id, "Grouping" %>
<%= f.select :noteable_id, @groupings.collect {|p| [p.group_name_with_student_user_names,p.id]} %>
<span id="loading_groupings" style="display:none">
<%=image_tag('spinner.gif')%> <%=I18n.t('notes.new.loading_groupings')%>
</span>
</p>
<p>
<%= f.label :notes_message %>
<%= f.text_area :notes_message, :rows => 10 %>
</p>
</fieldset>
<%= f.submit I18n.t('save') %>
<% end %>
</div>

The basic structure is what you’d expect. It creates a form object, and then builds the form in the way you want it to later display. The user can select things, type up a note, and get the end result no problem. Heck, the user can even start writing a note, change the assignment and grouping it’s onand not have to start writing their note over again! That’s slick!

What I want to do is extract out the mechanism to select the noteable object from the form. This isn’t too hard. The selection boxes are what’s the same so I just need to put  those first two things into a file I called _grouping.html.erb . Here’s what it looks like:


<p>
<%= f.label :assignment_id %>
<%= select_tag "assignment_id", options_from_collection_for_select(@assignments, :id, :short_identifier),
\:onchange => remote_function(:url => { :action => 'new_update_groupings' },
:with => 'Form.Element.serialize(this)',
:before => "Element.show('loading_groupings')",
:success => "Element.hide('loading_groupings')") %>
</p>
<p>
<%= f.label :noteable_id, "Grouping" %>
<%= f.select :noteable_id, @groupings.collect {|p| [p.group_name_with_student_user_names,p.id]} %>
<span id="loading_groupings" style="display:none">
<%=image_tag('spinner.gif')%> <%=I18n.t('notes.new.loading_groupings')%>
</span>
</p>

Note that nothing is different from when those lines were in the original file. Then I add one bit of rails magic to replace the lines I removed:


<%= render :partial => 'grouping', :locals => {:f => f} -%>

This line of code does two things. First: it retrieves the partial file I just created, in this case for the Groupings. Second: it passes in the form object we created. That part is important since it allows us to modify the form in the partial, as we need to.

Visually, this produces nothing different. It’s identical to what we saw before. Now for the tricky bit.

A few hours of writing, experimenting and testing later, having gone so far as having it generate Javascript that would be treated as values in the dropdown and then a generic function that dealt with each case, then to the final result here…

You can now select the type of notable!The tricky bit is getting it so we can select the kind noteable we want to write a Note for, and be able to retrieve the right partial, while getting the parts of the form in the partial to work properly. Getting behaviour like this isn’t too hard, but getting it to be reasonably generic and easy to extend is.

The noteables we have right now are fairly straight forward and the two we are adding require only one drop down for selection. We could just replace the list in the dropdown with some RJS magic, and hide the assignment selector when we aren’t selecting a Group.

The problem with that approach is we have separate sets of cases to deal with, and we have to ensure they all work when testing and adding new ones. Also, we have more things to look out for if we want to change how we are selecting the object (ie. filtering Students by Section, rather than a single list of Students). By dealing with all cases uniformly, we reduce the opportunity for error.

The end result for the business bits of the new note form is as follows:


<p>
<%= f.label :noteable_type, I18n.t('notes.noteable')%>
<%= select_tag "noteable_type", options_for_select(Note::NOTEABLES) %>
<%= observe_field :noteable_type, \:on => 'onchange',:url => {:action => :noteable_object_selector},
:with => "noteable_type",
:before => "Element.show('loading_selector')",
:success => "Element.hide('loading_selector')" %>
<span id="loading_selector" style="display:none">
<%=image_tag('spinner.gif')%> <%=I18n.t('notes.new.loading_selector')%>
</span>
</p>
<div id="noteable_selector">
<%= render :partial => 'grouping' %>
</div>

A few things have changed.  We now have a selector that choses between a list of Noteables that I put in the Notes model. Whenever the user changes the selected value, I call this ‘noteable_object_selector’ function in the controller, and flash this little loading box so the user knows that something is reacting to their selection. There is also that “noteable_selector” div towards the bottom that renders the partial for Groupings as default.

The ‘noteable_object_selector’ is actually an RJS call. RJS is a handy mechanism Rails provides to return snippets of Javascript that get executed by the browser immediately when received, usually to do a bit of DOM manipulation, but generally anything that you can get Javascript to do. Here’s what it looks like.



page.replace_html 'noteable_selector', :partial => params[:noteable_type].downcase


It’s sheer elegance in its simplicity! All it does is generate Javascript that replaces the contents of our “noteable_selector” div with the contents of the desired partial. There’s a little bit before that gets the required entries from the DB in the controller, but that’s so we have something to display in the dropdowns in the partials, rather than being magic to explain.

The astute reader will have noticed that I don’t have that “:locals => {:f => f}” bit at the end of the line like I had in the first step. How did I get around not having the form object anymore? The answer is simple. Rails provides exactly a mechanism to get around that. Here’s the partial for selecting Students to demonstrate. The partial for Assignments and Groupings are similar.


<% fields_for :note, :url => {:action => 'create'} do |f| %>
<p>
<%= f.label :noteable_id, "Student" %>
<%= f.select :noteable_id, @students.collect {|p| [p.user_name,p.id]} %>
</p>
<% end %>

The fields_for function does exactly the same thing as form_for except that it doesn’t generate the <form> tags, permitting exactly the behaviour I was aiming for with the locals parameter. We just wrap whatever partial we might want to use as parts of the form in a fields_for and it will generate form elements compatible with the form that we set it up for. Very handy!

Now we have a solution that is relatively simple to extend to new noteables as well as change how noteable objects are selected if we like. Everything is dealt with equally, which is important for testing since we don’t have special cases to deal with.

Written by Robert B

March 16th, 2010 at 11:35 pm

Posted in Uncategorized

The Plan for Notes

with 2 comments

For the past few hours I’ve been diving deep into the Notes system to find out exactly what needs to be changed in order to be able to add notes to all of Groupings (status quo), Assignments, and individual Students.

From the previous post on the subject:

We have completed the first three steps, including unit and functional tests. Thanks to the polymorphic, “noteable” idea that we used for the relationship between a note and a grouping, the only work necessary to have notes on a different object type is to:

  • add a “display_for_note” method to the model, like we did for groupings – this allows us to display these notes
  • modify the create a note form in the Notes tab to allow for other types of noteable objects than just groupings
  • add a link to the modal dialog in an appropriate location for the object type

For now, I can’t see the best place to place a link to a modal dialog to create a note associated to an assignment or to a student, so I would recommend just adding that functionality to the Notes tab.

This leads me to believe that most of the work is cut out for me. Which as near as I can tell, it is!

I’ll endeavour to break up my changes as mentioned above, described below:

  1. Low Hanging Fruit – a simple isolated change to add the display_for_note functionality, and associated tests, to the models of Assignments, and Groupings. Also, the notes main page will need to be updated to not have the add_new when there are no ‘noteable’ objects in the DB at all, rather than simply groupings, as it is now.
  2. Refactor Note Creation page – Once the other objects are able to be “noted” the next place to change is the main notes creation page. Currently it’s designed to look solely for Groupings that we can apply notes to. It will need to be updated with a drop down of the types, and then dynamically update a subsequent drop box with those types. This will be much clearer than simply putting all notable objects into a single drop box, even though it adds another pair of clicks to creating a note from scratch.
  3. Adding Modal Dialog links to Assignments and Student pages – These will be put in sensible locations, probably adjacent to the edit link in the student table, and on both the Assignment main table page, and the assignment configuration page. We don’t want to confuse people by having ambiguous Notes links without being clear what the noteable object is.

For 3 I’ll need to consult with Victoria for best placement of the links, as this is a usability issue, first and foremost.

Change 2 is also a usability issue somewhat, but I can’t think of a simpler solution interface wise than two drop downs in the create note page.

One issue that should be interesting to deal with is the case of Single student groups. Do we apply the note to the grouping as we do now? Or would it be better to apply it to the student in that group? The obvious solution is to do nothing, and use locality to decide. Whenever a note is being created in marking an assignment of a single student, the most likely intention of the user is to make a note on the grouping, as it’s related to the assignment. Otherwise, they would seek to make a note on the student specifically either in the table of students, or in the Note creation form in the Notes tab.

Input on this plan would be much appreciated, though I won’t be able to answer detailed technical questions until I’m arm deep into the code.

Written by Robert B

February 16th, 2010 at 2:56 pm

Posted in Uncategorized

Notes system: what’s left to do

with one comment

This post was originally written at the beginning of December 2009 and I just found it now, so I’m publishing it 🙂

Our original steps for the Notes system implementation went as follows:

  1. Design the model.
  2. Create mock-ups of the user interface.
  3. In parallel, design the Notes tab and the modal dialog interfaces (for groupings).
  4. Extend this functionality to assignments and to students once the notes system is solid for groupings.

We have completed the first three steps, including unit and functional tests. Thanks to the polymorphic, “noteable” idea that we used for the relationship between a note and a grouping, the only work necessary to have notes on a different object type is to:

  • add a “display_for_note” method to the model, like we did for groupings – this allows us to display these notes
  • modify the create a note form in the Notes tab to allow for other types of noteable objects than just groupings
  • add a link to the modal dialog in an appropriate location for the object type

For now, I can’t see the best place to place a link to a modal dialog to create a note associated to an assignment or to a student, so I would recommend just adding that functionality to the Notes tab.

Written by Tara Clark

January 26th, 2010 at 5:41 am

Posted in Uncategorized

Simple Grade Entry: Table view performance issues

with 4 comments

As I’ve been working on the table view for grade entry last week and this week (there are still some kinks to sort out, more on that in my next post), I’ve been noticing some performance issues that I think we might want to deal with before we let instructors use this table. One thing that I needed to decide was whether or not each table cell should be saved right as the instructor enters the mark or if the instructor should enter a bunch of marks and then hit a “Save” button. I decided to go with the “Save” button option. My initial plan was to display the entire table on a single page. However, I’m finding that:

  1. It’s difficult to navigate
  2. This page can take a long time to load or save

Severin had suggested earlier that we could implement some sort of pagination. I really like this idea. Here’s what I’m thinking:

  • Maybe we could implement pagination alphabetically, by last name (eg. At the bottom of the table, we could have links like “A-D”, “E-J”, etc.). This would help to reduce the number of rows that get displayed on the page at a time. We probably wouldn’t want to implement pagination using numbers because if an instructor wanted to enter grades for a particular student, he/she would have a hard time figuring out which page contains the desired student.

Any thoughts about this?

Written by Farah Juma

December 3rd, 2009 at 12:39 am

Posted in Uncategorized

Notes Modal dialog

with 3 comments

This is the modal dialog for the notes system. I stole the idea from review board and just change it a little bit.

One thing that i am planning to do but I couldn’t right now was to put the username in bold.

This dialog is going to be available in the assignment-> groups & graders view and in the submission view of the graders

notes view1

Written by fgarces

November 11th, 2009 at 2:57 pm

Posted in Uncategorized

Notes model

with 8 comments

This is the model that we are planning to use for the notes system.

We are going to relate the notes to the users that created them and for the groupings that they are assigned to.

Since we are focusing first on doing notes only for groupings the type column won’t be used, but if time permits we will use it to be able to add notes on submissions or assignments.

Depending on what we decide on foreign keys, we will have to add indexes for user_id and groupings_id to increase performance.

Notes DB

Written by fgarces

November 4th, 2009 at 3:23 pm

Posted in Uncategorized

Notes system mock-ups

with 3 comments

I am proposing a possible aggregate view of all notes to be placed on a new tab called “Notes”, displayed to the right of the existing tabs in the list. This tab would only be visible to graders and to admins.

Next to the header on the page, we would put an icon allowing the user to add a new note, which would bring up a modal dialog similar to the ones that Fernando is going to mock up. I picked this location because on the Users pages, there is an “Add New” link in small text next to the title.

The main attraction is the table with the notes in it. After playing around with a couple of more table-like looks, I settled on this one that looks more like messages. There are three columns in each row. The first indicates data in the following format:

[username] on <b>[assignment short identifier]:  [comma-separated student usernames]</b>

<small>[full date] at [time]</b>

The second column shows the full text of the note and the third column shows edit and delete icons, if the current user has the privilege of doing so. (Admins can edit/delete all notes and graders can edit/delete notes that they created themselves.)

Each row will be highlighted in grey when hovered over.

Using the “on” method of indicating the object the note is for makes this view much more flexible when we add further objects that we can note on other than just groupings. For a grouping, we would show the assignment short identifier and all of the student memberships. But for an assignment, we would simply show its short identifier or for a student, its username.

Notes tab

Written by Tara Clark

November 4th, 2009 at 3:17 pm

Posted in Uncategorized

Grade Entry Form: Database Schema

with 4 comments

Yesterday’s meeting got me thinking more about the database schema for the grade entry feature. Here’s what I originally had in mind: Original Grade Entry Database Schema

I had originally considered a separate Grades table, as shown in the diagram. However, it would probably be better if we could combine the Grades table and the Marks table. There are two fields in the Marks table from Scenario 4 for the new marking scheme that do not really apply to simple grade entry: criterion_id and result_id. In addition, a table which stores grades for simple grade entry would require two fields which the existing Marks table does not need: grade_entry_item_id and grade_entry_student_id. The fields both tables have in common are: grade/mark, created_at, and updated_at. Any thoughts on how we could go about combining these tables?

Written by Farah Juma

October 24th, 2009 at 5:21 pm

Posted in Uncategorized