Developing for Makahiki – Part 1

Task 1: Hello World

This weeks’ class exercise in developing new widgets for Makahiki began as everything does in software engineering: with "Hello World.”" This tutorial breaks down the process of designing a new widget for Makahiki into a few basic steps:

  1. Initialize the new widget
  2. Edit its views.py file to determine what output it will return
  3. Edit its templates/index.html; this is the page section to display the values returned by its views.py file
  4. Add the widget to the list of widgets in Makahiki’s settings.py file
  5. In Makahiki’s challenge design configuration menus, add the new widget to a page
  6. Add a help topic for the widget
  7. Add the widget to fixtures/base_pages.json and fixtures/base_help.json to make it permanent (optional)
  8. Push changes to Github or Heroku as applicable.

I finished this without problems and got hello_world working locally.

The hello_world demo widget.

Above: The hello_world demo widget running locally.

The hello_world widget by itself, however, does not do much. The next set of tasks, after modifying score_mgr to support collecting data on user groups, involved adding more widgets to support data collection from player groups, which do not come with Makahiki by default.

Task 2: Add Group Widgets

Update score_mgr to Support Groups

My initial approach was one in which I attempted to add group support to score_mgr by creating new versions of its team data functions by replacing references to “team” with references to “group.” This was based on the assumption, based on models.py, that a Group could be accessed as a field of a Team (which is itself a field of a user_profile). This assumption was partially correct; the problem lay in the way I was processing the dictionary value returned from the widget’s views.py file, which was itself accessing profile__team__group__name to get the list of all groups.

Create a Group Scoreboard Widget

It was in attempting to create the group_scoreboard widget that I discovered that I was attempting to access the group value incorrectly. Initially, I thought that the error messages I experienced were due either to problems in the new functions I had added to start_mgr or the use of the admin account’s profile when the admin account was not linked to a group. Instead it was the result of another standard computer science problem, accessing a variable which did not exist.

A Django field error.

This problem turned out to be caused by a mistaken attempt to check for profile__team__group__isnull. “group” is not a property of profile__team.

As it turned out, the NoneType errors were caused by my views.py file. Originally, it returned the dictionary of group scores as follows:

return group_score

The code block Django uses to return named parameters is actually:

return {
    "group_score": group_score
}

which I had altered for some reason. Without this, views.py would always return null when Django processed index.html and attempted to access “group_score.”

There was another problem after this in which the widget displayed correctly but showed the text “last” and “points” instead of actual team names. The group_points_leaders function I created in score_mgr, modified from team_points_leader, has this block of code:

entries = ScoreboardEntry.objects.filter(
    round_name = round_name, profile__team__isnull=False).values(
    "profile__team__group__name").annotate(
    points=Sum("points"),
    last=Max("last_awarded_submission")).order_by("-points", "-last")

The entries variable is initialized to a dictionary and passed to views.py. I knew the problem was probably in my Django loop code in index.html, which tried to process the dictionary by looping through keys and values. The better way of accessing the dictionary in this case is to access individual, named parameters from each dictionary element:

{% for f in view_objects.group_scoreboard.group_score %}
   <!-- Some HTML formatting eliminated for clarity -->
   <tr>
   <td>{{ f.profile__team__group__name }}</td>
   <td>{{ f.points }}</td>
   </tr>
{% endfor %}

The group_scoreboard widget, showing the test group.

This section updated April 8, 2013.

Create a Group Resource Widget

I will update this section if I complete it.

Create a Group Prize Widget

I will update this section if I complete it.

Create Two Group Statistics Widgets

I will update this section if I complete it.

Suggestions for Makahiki Documentation Improvement

It is hard to say in this case if my problems are due to any issues in the Makahiki documentation, as they could just as easily result from my fixating on trying to salvage an unusable method of extending start_mgr to support groups. As far as I know, no one else had any problems with this step, so I am inclined to attribute my problems to configuration or coding errors on my end rather than problems with the documentation. Nevertheless, adding a type hierarchy diagram (manually created or automatically generated) to the documentation might be helpful. Though the widget system and user/group/team system is conceptually simple, it was not very clear to me which types had access to which other types.

This post will be updated if the score_mgr problems are resolved.

Advertisements