gdoteof / election

drupal election module
3 stars 1 forks source link

Provide Links to Ballot Item Results #3

Closed bradley-holt closed 12 years ago

bradley-holt commented 12 years ago

Description

Please provide a link to individual ballot item results when these results are aggregated.

Steps to Reproduce

curl 'https://example.org/town-meeting-season-2011/town-meeting-day-2011/city-of-burlington' \
-H 'Accept: application/json'

Actual Results

{
   "title":"City of Burlington",
   …
   "ballot_item_results":{
      …
      "113838":{
         "text":"Approval of Increase in Maximum Tax Rate for…",
         "results":{
            "Yes":1849,
            "No":4047
         }
      },
      …
   }
   …
}

Expected Results

{
   "title":"City of Burlington",
   …
   "ballot_item_results":{
      …
      "113838":{
         "text":"Approval of Increase in Maximum Tax Rate for…",
         "link":"/town-meeting-season-2011/town-meeting-day-2011/city-of-burlington/tax-rate",
         "results":{
            "Yes":1849,
            "No":4047
         }
      },
      …
   }
   …
}

Additional Comments

Is the ID number (e.g. 113838) necessary? I can't think of any scenario under which I would need that data. Is this ever used for anything user-facing (e.g. part of a URL)? If not, could ballot_item_results just be an array?

acrawford commented 12 years ago

That integer is the Drupal node id (nid) and is the unique key of that piece of content. You can visit the page with that content rendered by entering a URI of the form node/113838 eg. this content . I imagine it is there as a byproduct of some of the recursion code, as it is very common to iterate over a list of nids to get the content out of the database. It could be useful, but it does add complexity to the data structure.

gdoteof commented 12 years ago

We can remove the nid and have it be part of the array.

This part of the data structure wasn't called for in the spec; and actually provides the sum of the results (recursively through sub districts); so we cannot link to something; as it could be the results for multiple districts combined.

We can remove it from the data structure. The NID points to the actual ballot item as a drupal node; whereas within the module; ballot items only make sense in relation to districts.

bradley-holt commented 12 years ago

I was just bringing up the nid as it seemed like extra data—but that's not a big deal. Whatever you want to do with that is fine with me (keep it as-is, or turn it into an array). The main point was about being able to get at the URL for a specific ballot item results. I understand that these are aggregate results, but shouldn't the aggregate still have its own URL? There is an example of this in the CCTV Election Module API Requirements under Ballot Item Results:

{
   "title":"Chittenden State Senate",
   "link":"/e/fall-2010/general/burlington/chittenden-state-senate",
   "election_season":{
      "title":"Fall 2010",
      "link":"/e/fall-2010"
   },
   "election_event":{
      "title":"General Election",
      "link":"/e/fall-2010/general"
   },
   "district":{
      "title":"Burlington",
      "link":"/e/fall-2010/general/burlington",
      "tags":[
         "municipality"
      ],
   },
   "tags":[
      "election"
   ],
   "results":{
      "Virginia Lyons":7173,
      "Sally Fox":7079,
      "Diane B. Snelling":4244,
      …
   }
}

In the CCTV Election Module Scenarios document under General Election, Election for Chittenden Senate Seats it indicates that this district is comprised of twenty-nine polling places. Admittedly, this probably could have been clearer that I would have expected to have a URL for each ballot item results (even aggregates).

The current prototype for JavaScript updates at the ballot item results level so expects a URL for each ballot item results. This is ideal because the JavaScript can just scan any HTML page for ballot item results, find the appropriate URL for each ballot item results, and start polling for updates for each of these ballot item results (don't worry about the selectors, these will likely change):

function updateBallotItemArticles(cache) {
    $("article.ballot-item-results").each(function(index, element) {
        var uri = $(element).find('h1 a').first().attr("href");
        if (!(uri in timeouts)) {
            timeouts[uri] = {};
        }
        //TODO: Default refresh time?
        updateBallotItemArticle(uri, $(element), 60000, cache);
    });
}
gdoteof commented 12 years ago

You can get at the results for a specific ballot item; that appears to be working correctly.. there are links to the differnent ballot items.

I don't think it makes so much sense to create a new page to get the results; perhaps I should just remove it from the data structure completely...

It might look something like: e/town-meeting-season/town-meeting-day/burlington/results ?

It just seems redundant to me; but if it is not going to be used at all, probably the right thing to do is just remove it from the datastructure completely.

bradley-holt commented 12 years ago

I think I see what you mean by that data being redundant. Perhaps I should re-open this as another ticket, but I now realize what I'm really getting at is the empty ballot_items array for town-meeting-season-2011/town-meeting-day-2011/city-of-burlington:

   …
   "ballot_items":[

   ],
   …

I would expect the ballot_items array for town-meeting-season-2011/town-meeting-day-2011/city-of-burlington to contain the ballot items that are relevant to the City of Burlington (just like town-meeting-season-2011/town-meeting-day-2011/ward-1 includes the ballot items that are relevant to Ward 1). For example, this is what I might expect to see:

  …
  "ballot_items":[
      "elections":[
         {
            "title":"Ward 1 City Council",
            "link":"/cctv.org/e/town-meeting-season-2011/town-meeting-day-2011/city-of-burlington/ward-1-city-council"
         },
         {
            "title":"Ward 1 School Board",
            "link":"/cctv.org/e/town-meeting-season-2011/town-meeting-day-2011/city-of-burlington/ward-1-school-board"
         },
         …
      ],
      "referendums":[
         {
            "title":"Burlington School Budget",
            "link":"/cctv.org/e/town-meeting-season-2011/town-meeting-day-2011/city-of-burlington/burlington-school-budget"
         },
         {
            "title":"Burlington Ballot Item 2 Tax Rate Increase",
            "link":"/cctv.org/e/town-meeting-season-2011/town-meeting-day-2011/city-of-burlington/burlington-ballot-item-2-tax-rate-increase"
         },
         {
            "title":"Burlington Ballot Item 3 BED Smart Grid Bond",
            "link":"/cctv.org/e/town-meeting-season-2011/town-meeting-day-2011/city-of-burlington/burlington-ballot-item-3-bed-smart-grid-bond"
         },
         {
            "title":"Burlington Ballot Item 4 BED VT-Transco Bond",
            "link":"/cctv.org/e/town-meeting-season-2011/town-meeting-day-2011/city-of-burlington/burlington-ballot-item-4-bed-vt-transco-bond"
         },
         {
            "title":"Burlington Ballot Item 5 Charter Change",
            "link":"/cctv.org/e/town-meeting-season-2011/town-meeting-day-2011/city-of-burlington/burlington-ballot-item-5-charter-change"
         },
         {
            "title":"Burlington Ballot Item 6 City Council Rules Valid Majority",
            "link":"/cctv.org/e/town-meeting-season-2011/town-meeting-day-2011/city-of-burlington/burlington-ballot-item-6-city-council-rules-valid-majority"
         },
         {
            "title":"Burlington Ballot Item 7 Finance Board",
            "link":"/cctv.org/e/town-meeting-season-2011/town-meeting-day-2011/city-of-burlington/burlington-ballot-item-7-finance-board"
         },
         {
            "title":"Burlington Ballot Item 8 Housing Advisory",
            "link":"/cctv.org/e/town-meeting-season-2011/town-meeting-day-2011/city-of-burlington/burlington-ballot-item-8-housing-advisory"
         }
      ]
   ],
   …
acrawford commented 12 years ago

The reason the ballot items section is empty is due to the fact that I only associated ballot items with the Districts at the lowest level (where we are doing the result data entry). All other Districts are just empty shells that provide different ways of recursively aggregating those lower level Districts for results display. The thought behind this was directed at preventing someone from mistakenly entering results at a higher/different District level when we aren't actually getting results at that granularity. Worse, if someone were to enter results for the whole city on a citywide ballot item at the city District level, I believe it would be added to the results at the lower District levels (Wards for example), potentially resulting in double counting of votes where data was entered for the same ballot item at Ward and City levels.

acrawford commented 12 years ago

If I associate the ballot items with a District (city-of-burlington) where we don't enter data at that granularity: note that no results are returned even though there are results for the ballot item in individual wards (sub-districts).

{
    "title": "Burlington School Budget",
    "link": "/cctv.org/e/town-meeting-season-2011/town-meeting-day-2011/city-of-burlington/burlington-school-budget",
    "election_event": {
        "title": "Town Meeting Day 2011",
        "link": "/cctv.org/e/town-meeting-season-2011/town-meeting-day-2011"
    },
    "election_season": {
        "title": "Town Meeting Season 2011",
        "link": "/cctv.org/e/town-meeting-season-2011"
    },
    "district": {
        "title": "City of Burlington",
        "link": "/cctv.org/e/town-meeting-season-2011/town-meeting-day-2011/city-of-burlington",
        "tags": ["Municipality"]
    },
    "tags": ["Referendum"],
    "results": []
}

However, I can enter results at the higher district level (city-of-burlington) for this referendum and this is what I get.

{
    "title": "Burlington School Budget",
    "link": "/cctv.org/e/town-meeting-season-2011/town-meeting-day-2011/city-of-burlington/burlington-school-budget",
    "election_event": {
        "title": "Town Meeting Day 2011",
        "link": "/cctv.org/e/town-meeting-season-2011/town-meeting-day-2011"
    },
    "election_season": {
        "title": "Town Meeting Season 2011",
        "link": "/cctv.org/e/town-meeting-season-2011"
    },
    "district": {
        "title": "City of Burlington",
        "link": "/cctv.org/e/town-meeting-season-2011/town-meeting-day-2011/city-of-burlington",
        "tags": ["Municipality"]
    },
    "tags": ["Referendum"],
    "results": {
        "Yes": "3000",
        "No": "2000"
    }
}

It does not add the numbers above I entered recurseively when loooking only at the city-of-burlington/burlington-school-budget URI.

However, when the recursive sum for the district takes place by visiting city-of-burlington URI you can see the incorrect results, which is the sum of all wards and the numbers entered at the City Level.

...
      "113839": {
            "text": "School Budget 2011",
            "results": {
                "Yes": 5725,
                "No": 4597
            }
}...

This above behavior is the reason we don't associate ballot items except in the lowest level District (plus it is less confusing during data entry)

bradley-holt commented 12 years ago

Seeing as the ballot item results are a tree structure, I would expect it to follow some variation of the composite pattern in that every node (not necessarily a Drupal "node") would share a common interface (e.g. able to be accessed as a ballot item result with its own URL) but there would be a distinction between leaf nodes and composite nodes. Leaf nodes would allow data entry (as all nodes do now). Composite nodes would not allow data entry, but instead just aggregate the results from their child nodes. @gdoteof, is there a way that we can distinguish between leaf and composite nodes so that @acrawford can associate the ballot item with a parent district (e.g. City of Burlington) but not allow data entry at that level of granularity and instead just show the aggregate results?

gdoteof commented 12 years ago

I see now what bradley is talking about. I am reopening; sorry for the confusion.

Unless this is absolutely necessary I am going to ask that we table it for now.

bradley-holt commented 12 years ago

I think this is necessary. For example, how is one supposed to determine the results of the Burlington School Budget at the City of Burlington level? In the HTML context, the user would need to click through to each Ward, click through to each Burlington School Budget, and manually add up the results rather than being able to retrieve the aggregate results from one place. These results should either be aggregated on the City of Burlington page or, preferably, a link provided to each aggregate results from the City of Burlington page. The situation in JSON context is a bit better as one can iterate through the ballot_item_results object to find each aggregate results. However, updates would be much more streamlined if we could update on a ballot item results level rather than needing to iterate through at the district level. I worry that the approach we would need to take for JavaScript updates with the current setup would be rather clunky.

gdoteof commented 12 years ago

Hrm; I agree that this is necessary information; which is why I added the ballot_item_results to the internal datastructure in the first place despite its absence from the spec.

If I am thinking about this correctly; one oughtn't need to iterate through the ballot_item_results to get the aggregate results; as it should be the aggregate results itself.

In this vein, it makes sense to me to display the aggregated results on the HTML at the district level. This would simply entail printing the results that are already there; and would be identical to the JSON.

acrawford commented 12 years ago

That sounds like a great plan.

gdoteof commented 12 years ago

@bradley-holt what do you think? in addition; we will add the completeness and winner flags to this aggregate and call it day?

bradley-holt commented 12 years ago

Let me take a look at this and give it some thought. I'm headed out of the office and won't be back until at least late morning tomorrow, if not later.

gdoteof commented 12 years ago

Ok; don't think too hard. I am going to implement this as it was originally requested.

gdoteof commented 12 years ago

ok this is added with 021ed1c

acrawford commented 12 years ago

Awesome. It is up on dev now as well. looks good in JSON and HTML

bradley-holt commented 12 years ago

Awesome, thanks! Would it make sense to also list these links under ballot_items?