[Unicode]   Common Locale Data Repository : Bug Tracking Home | Site Map | Search
 
Modify

CLDR Ticket #11299(new surveytool)

Opened 3 weeks ago

Last modified 36 hours ago

Distinguish two kinds of votes for inherited value in Survey Tool

Reported by: tbishop Owned by: tbishop
Component: survey Data Locale:
Phase: dsub Review:
Weeks: Data Xpath:
Xref:

Description

Survey Tool needs to support, and clearly distinguish, two kinds of votes related to inheritance: (1) vote for inheritance, with the internal value "↑↑↑"; (2) vote for the value that happens to match what would be inherited (the "Bailey value") at the time of voting.

Attachments

T11299 SmokeTest 2018-08-14 A.png (103.3 KB) - added by tbishop 5 days ago.
buggy voting A
T11299 SmokeTest 2018-08-14 B.png (110.4 KB) - added by tbishop 5 days ago.
buggy voting B
T11299 SmokeTest 2018-08-14 C.png (113.9 KB) - added by tbishop 5 days ago.
buggy voting C
T11299 SmokeTest 2018-08-14 D.png (116.1 KB) - added by tbishop 5 days ago.
buggy voting D
T11299 SmokeTest 2018-08-14 E.png (105.5 KB) - added by tbishop 5 days ago.
buggy voting E

Change History

comment:1 Changed 3 weeks ago by tbishop

Some related tickets already exist, including 10521, 10466, and 11238, concerning the browser console error message "there is no Bailey Target item". Note that the "Bailey" value may be defined as "The value that CLDR would have if the winning value were not present"; it may come from a parent, or from "sideways" inheritance (e.g., short → wide). There are multiple bugs, some already solved, some still unsolved, that lead to that error message and to the failure of the Bailey value to be displayed in the interface as one of the items that can be voted on.

This ticket is NOT about that error message. Even when that error message doesn't occur, there are problems with confusion between the two kinds of votes related to inheritance. This ticket is for fixing those problems. The user needs to be able to make either of the two kinds of vote, with an interface that makes it clear how to do so and shows clearly which kind of vote has been made. In addition, the voting resolution procedure needs to distinguish the two kinds of vote while recognizing their relationship to each other.

The terminology is still in flux. The first kind of vote may be called an "implicit" or "soft" vote for the inherited value, or a vote "for inheritance". The second kind may be called an "explicit" or "hard" vote for the "specific" value. If the user enters the value by typing it in manually (and NOT as the string "↑↑↑"), it is treated as explicit/hard/specific.

This ticket needs to identify the ways and circumstances in which the interface currently fails to support distinguishing the two kinds of vote. This ticket also needs to follow and implement Voting Design specs that the technical committee is currently working on.

comment:2 Changed 3 weeks ago by tbishop

See also 11298 "SurveyTool displays wrong inheritance markup, confusing vetters".

Last edited 3 weeks ago by tbishop (previous) (diff)

comment:3 follow-up: ↓ 6 Changed 3 weeks ago by tbishop

A simple example of failure can be demonstrated as follows. Go to:

http://localhost:8080/cldr-apps/v#/en_CA/Numbering_Systems/7b8ee7884f773afa

Start out with the value "latn" being inherited from root, displayed with red background. Add a vote for "taml"; that becomes Winning, and the inherited "latn" shows in the Others column with blue background (why not red?). So far, so good. Now add a vote for "latn" -- explicitly, by typing it in. That replaces "taml" (since I'm the same voter). Now "latn" appears in the Winning column with white background, correct since it's hard/explicit, not inherited; but nothing appears in the Others column. That's a bug. The inherited value should appear in the Others column with blue (or red?) background.

A simple solution appears to be to change this in survey.js:

//add the other vote info
for(k in theRow.items) {
  if((k === theRow.winningVhash) // skip vote for winner
    || (theRow.items[k].isVoteForBailey)) { // skip vote for ↑↑↑
    continue;

The isVoteForBailey condition does indeed cause the vote for ↑↑↑ to be skipped, but at least in this case ↑↑↑ should NOT be skipped. Removing that part of the condition causes the inherited value to appear in the Others column with blue background as it should (leaving aside, for now, the question, why blue not red), while the Winning column still displays "latn" with white background.

If I now vote for the "soft" inherited value, another bug is evident. Both the Winning and Others columns have "latn" with red background and with a blue-circle icon (ichoice-x, radx.png) indicating I have voted for them! This is correct for Winning but wrong for Others. The Others column should either be displaying the "hard" item for "latn" with white background, or displaying nothing since the hard item has no votes.

Per the Voting Design doc https://docs.google.com/document/d/1y6yDkz75N7YzIf0KI2ICDF822ymeQ5wuM1gsUs3EOXA/edit# :

"Should the Bailey value show up in the Info Panel even if it has zero votes? ... Leaning towards no." -- but that's for the Info Panel; how about the Others column?

Last edited 3 weeks ago by tbishop (previous) (diff)

comment:4 Changed 3 weeks ago by tbishop

I'm using "soft" and "hard" for votes of types "(1)" and "(2)", respectively, as we've been doing for a while.

A CandidateItem named 'inheritedValue' is constructed on the server. Its relationship to the "hard" (explicit) and "soft" (↑↑↑) items seems to be one of the sources of confusion.

inheritedValue itself is like a "hard" item, in the sense that its value is explicit like "latn", rather than "↑↑↑". On the other hand, the name "inheritedValue" and the ways it gets created and used strongly imply that it's associated with soft votes for inheritance. A hard CandidateItem, if one exists, has the same value as Bailey, but a vote for it is NOT a vote for inheritance. When both soft and hard items exist, it would make more sense for all the info about inheritance to be attached to the soft item, but currently it's attached to the hard item, at least if the hard item is inheritedValue, created in the function updateInheritedValue.

We have attributes named isBailey and isFallback. What's the difference, and what do they mean? Both generally are true for the constructed inheritedValue, and false for other items.

Last edited 3 weeks ago by tbishop (previous) (diff)

comment:5 Changed 3 weeks ago by tbishop

There's a problem here on the server:

        CandidateItem getWinningItem() {
            if (winningValue == null)
                return null;
            if (winningValue.equals(CldrUtility.INHERITANCE_MARKER)) {
                for (CandidateItem ci : items.values()) {
                    if (ci.isFallback) {
                        return ci;
        ...

When a "soft" vote for inheritance is winning, the function returns the fallback item -- that is, the "hard" item -- instead! Of course there are situations where, given a soft vote, we want to know the inherited value such as "latn" rather than "↑↑↑", but under what circumstances does it make sense to return the losing hard item when the caller is asking for the winning item, which is soft? I imagine the code was originally written when "hard" and "soft" votes weren't meant to be distinguished.

Last edited 3 weeks ago by tbishop (previous) (diff)

comment:6 in reply to: ↑ 3 ; follow-up: ↓ 8 Changed 3 weeks ago by Marcel Schneider <charupdate@…>

Replying to tbishop:

A simple example of failure can be demonstrated as follows. Go to:

http://localhost:8080/cldr-apps/v#/en_CA/Numbering_Systems/7b8ee7884f773afa

Start out with the value "latn" being inherited from root, displayed with red background.

That red background seems to be a bug. As per documentation (http://cldr.unicode.org/index/survey-tool/guide#TOC-Inheritance), sublocales are expected to inherit from their parent locale, not from root.

Add a vote for "taml"; that becomes Winning, and the inherited "latn" shows in the Others column with blue background (why not red?). So far, so good. Now add a vote for "latn" -- explicitly, by typing it in. That replaces "taml" (since I'm the same voter). Now "latn" appears in the Winning column with white background, correct since it's hard/explicit, not inherited; but nothing appears in the Others column. That's a bug. The inherited value should appear in the Others column with blue (or red?) background.

That bug seems to have occurred on the road, given the screenshot in the documentation still has inherited values in the Others column (http://cldr.unicode.org/index/survey-tool/guide#TOC-Regional-Inheritance). The same source page today (http://st.unicode.org/cldr-apps/v#/es_MX/Languages_E_J/591f8c536c00463d) has nothing in Others where hard votes are displayed.

I see the practical implication when a sublocale that has corrected data that should be corrected in the parent locale, cannot return to inheritance after the corrections have been implemented where they belong to.

comment:7 Changed 12 days ago by tbishop

About red versus blue background, I'm seeing differences I can't explain. The production site (st.unicode.org) is currently running revision [14272]. I've checked out that same revision of trunk on localhost, and I've exported the current production db and imported it on localhost. Nevertheless, I see blue background for latn here:

http://st.unicode.org/cldr-apps/v#/en_CA/Numbering_Systems

and red background for latn here:

http://localhost:8080/cldr-apps/v#/en_CA/Numbering_Systems

The info panel says "(This item is inherited.)" when the background is blue, and "(This item is inherited from the root locale.)" when the background is red. (However, in both cases, clicking on the "Jump to Original" link goes to the "root" page.)

How can the same code and data be producing different results?

comment:8 in reply to: ↑ 6 Changed 11 days ago by mark

The background shows where the data is coming from.

There is an explanation at http://cldr.unicode.org/index/survey-tool/guide#TOC-Inheritance, but we need to enhance that to provide a fuller picture. In particular, when it says "a parent locale" it does not mean only the immediate parent, but anywhere up the inheritance chain. So we need to make that clearer. Here is background:

Rephrasing in XML terms, and using the term 'ancestor' to make it clear that the parent relation is treated recursively:

  • Lighter - the data is coming from the same locale, but different path
  • Red - the data is coming from root (maybe same path, maybe different path)
  • Darker - the data is coming from an ancestor locale other than root (maybe same path, maybe different path)

So looking at this locale, here is the inheritance chain: en_CA => en_001 => en => root. If inherited data is not found in en_001, then en is checked, and so on.

  • Lighter: en_CA
  • Darker: en_CA or en_001 or en
  • Red: root

Take the term for kilometers, and click through on the inherited items.

  1. http://st.unicode.org/cldr-apps/v#/en_CA/Length/2657c6d866524f70
  2. Following the [Jump to Original ⇒] gets you to http://st.unicode.org/cldr-apps/v#/en_001//2657c6d866524f70 (en_001)
  3. Following the [Jump to Original ⇒] gets you to http://st.unicode.org/cldr-apps/v#/en/Length/2657c6d866524f70 (en)
  4. It then goes Lighter, indicating a different path
  5. Following the [Jump to Original ⇒] gets you to the short display name at http://st.unicode.org/cldr-apps/v#/en/Length/7d1934c6c969f185

That one happens to be the same as root, but since it is explicit you don't see 'root'.

If you go back to en_CA and got to

  1. http://st.unicode.org/cldr-apps/v#/en_CA/Length/7d1934c6c969f185
  2. Following the [Jump to Original ⇒] gets you to http://st.unicode.org/cldr-apps/v#/en/Length/7d1934c6c969f185 (en)

So you skipped en_001, and went right to en. If there hadn't been anything in en, you would have gone to root (and the item would have been Red instead of Darker)

Replying to Marcel Schneider <charupdate@…>:

Replying to tbishop:

A simple example of failure can be demonstrated as follows. Go to:

http://localhost:8080/cldr-apps/v#/en_CA/Numbering_Systems/7b8ee7884f773afa

Start out with the value "latn" being inherited from root, displayed with red background.

That red background seems to be a bug. As per documentation (http://cldr.unicode.org/index/survey-tool/guide#TOC-Inheritance), sublocales are expected to inherit from their parent locale, not from root.

Add a vote for "taml"; that becomes Winning, and the inherited "latn" shows in the Others column with blue background (why not red?). So far, so good. Now add a vote for "latn" -- explicitly, by typing it in. That replaces "taml" (since I'm the same voter). Now "latn" appears in the Winning column with white background, correct since it's hard/explicit, not inherited; but nothing appears in the Others column. That's a bug. The inherited value should appear in the Others column with blue (or red?) background.

That bug seems to have occurred on the road, given the screenshot in the documentation still has inherited values in the Others column (http://cldr.unicode.org/index/survey-tool/guide#TOC-Regional-Inheritance). The same source page today (http://st.unicode.org/cldr-apps/v#/es_MX/Languages_E_J/591f8c536c00463d) has nothing in Others where hard votes are displayed.

I see the practical implication when a sublocale that has corrected data that should be corrected in the parent locale, cannot return to inheritance after the corrections have been implemented where they belong to.

comment:9 Changed 11 days ago by mark

The only reason that root has a distinctive color is that it usually should be overridden.

comment:10 Changed 11 days ago by tbishop

Thanks for the explanations! Ideally the info panel should show the full path of inheritance, with links like the current "Jump to Original" for each level.

I've found what looks like a major bug affecting this ticket. In survey.js this block is intended to set winningVhash appropriately when it has been left empty by the server:

	if(theRow.items && theRow.winningVhash == "") {
		// find the fallback value
		var theFallbackValue = null;
		for(var k in theRow.items) {
			if(theRow.items[k].isFallback || theRow.winningValue == "") {
				theFallbackValue = k;
			}
		}
		if(theFallbackValue !== null) {
			theRow.winningVhash = theFallbackValue;
		}
	}

When both winningVhash and winningValue are empty, then regardless of whether isFallback is true or false, theFallbackValue gets set to the LAST element of theRow.items ... and which element is the LAST is effectively random or browser-dependent. Randomness of the last item is evident in these two examples (from browser console with some extra debugging code added, url <http://localhost:8080/cldr-apps/v#/gsw_FR/Languages_A_D/>, corresponding to <https://st.unicode.org/cldr-apps/v#/gsw_FR/Languages_A_D/> on the production server):

Example A:
DEBUG: both winningVhash and winningValue are empty
DEBUG: k = [4oaR4oaR4oaR], value = [agq], isFallback = false
DEBUG: k = [YWdx], value = [agq], isFallback = true
DEBUG: changing winningVhash to theFallbackValue = [YWdx]

Example B:
DEBUG: both winningVhash and winningValue are empty
DEBUG: k = [YXo,], value = [az], isFallback = true
DEBUG: k = [4oaR4oaR4oaR], value = [az], isFallback = false
DEBUG: changing winningVhash to theFallbackValue = [4oaR4oaR4oaR]

In example A, the last of two items has isFallback = true and gets used for the fallback.

In example B, the last of two items has isFallback = false and gets used for the fallback.

In both examples, the key 4oaR4oaR4oaR is for "↑↑↑" ("soft") while the other key is for the (explicit) Bailey value ("hard"). (isFallback is false for "soft", true for "hard"; that's apparently how it's always been, though it seems backwards; we may eventually switch the mapping or get rid of the isFallback boolean.)

There are also cases in which winningVhash is empty but winningValue is nonempty, such as:

Example C:
DEBUG: one empty, one not: winningVhash = [], winningValue = [Veräifachts Chineesisch]
DEBUG: k = [4oaR4oaR4oaR], value = [Veräifachts Chineesisch], isFallback = false
DEBUG: k = [Q2hpbmVlc2lzY2ggKFZlcsOkaWZhY2h0aSBDaGluZWVzaXNjaGkgU2NocmlmdCk,], value = [Veräifachts Chineesisch], isFallback = true
DEBUG: changing winningVhash to theFallbackValue = [Q2hpbmVlc2lzY2ggKFZlcsOkaWZhY2h0aSBDaGluZWVzaXNjaGkgU2NocmlmdCk,]

I'm studying why the server sets winningValue but not winningVhash here. Maybe it would be best for the server always to resolve the winner (if any), rather than leave any of that decision-making to the client.

Strangely, what's actually displayed is "Chineesisch (Veräifachti Chineesischi Schrift)" (with blue inheritance color) -- that's in the Winning column. Nothing in the Others column for that row, and "Veräifachts Chineesisch" isn't displayed at all!

URL for that item is: http://localhost:8080/cldr-apps/v#/gsw_FR/Languages_A_D/3f16ed8804cebb7d

Clicking on "Jump to Original" stays on the same page, exact same url!

Same for production site: https://st.unicode.org/cldr-apps/v#/gsw_FR/Languages_A_D/3f16ed8804cebb7d

This is for codeStr = zh_Hans
vr.lastReleaseValue = "Veräifachts Chineesisch"

Sequence of events on server (for example C):

  • resolver.getWinningValue is called first and returns "Veräifachts Chineesisch", when the items array is still empty, now winningValue = "Veräifachts Chineesisch"
  • populateFrom calls addItem(CldrUtility.INHERITANCE_MARKER), then updateInheritedValue, which calls addItem with value = "Chineesisch (Veräifachti Chineesischi Schrift)"; now the items array only contains the two items
  • getWinningItem is called and returns null since the items array doesn't contain an item with value = winningValue = "Veräifachts Chineesisch"

Example C seems to illustrate a different bug from examples A and B; not clear how widespread it is; maybe it should get its own ticket. A solution might involve this section of code:

           if (p.oldValue != null && !p.oldValue.equals(value) && (v == null || !v.contains(p.oldValue))) {
                // if "oldValue" isn't already represented as an item, add it.
                CandidateItem oldItem = p.addItem(p.oldValue);
                oldItem.isOldValue = true;
            }

Even if p.oldValue.equals(value), if !items.contains(value) && !v.contains(p.oldValue) then addItem should still be called? But normally it would be called further below:

                myItem = p.addItem(value);

The reason that doesn't happen here is:

            // ** IF it is inherited, do NOT add any Items.
            if (isInherited && !isExtraPath) {
                ...
                continue;
            }

In this case isInherited is true...

The major bug illustrated by examples A and B might be fixed, as far as the randomness is concerned, by deleting || theRow.winningValue == "" from the second if. However, that part of the condition was added about 2 years ago in changeset [12701] for 9547...

Last edited 10 days ago by tbishop (previous) (diff)

comment:11 Changed 9 days ago by tbishop

  1. JSON sent from server to client must be COMPLETE and CONSISTENT
    1. Implement automated tests for complete and consistent JSON describing each DataRow
    2. Neither winningValue nor winningVHash can be empty
    3. There must be an item that corresponds to the winningValue
    4. Avoid pointless naming differences like server "inheritFrom" = client "inheritedLocale"
  1. Server, not client, is responsible for data and for voting method logic
    1. Client shouldn't change winningVhash or other data received from server
    2. Client probably shouldn't do the block with comment "Move those votes over to the actual target"
  1. Always include a "soft" CandidateItem with value=INHERITANCE_MARKER ↑↑↑
    1. Currently it's not added unless it has votes or locale.getCountry() != null ("fr_CA" but not "fr")
    2. Info that describes a whole row (e.g., inheritFrom) belongs in DataRow not in CandidateItem
  1. Don't add a "hard" CandidateItem with value=Bailey unless a user manually entered it
    1. Currently updateInheritedValue adds isBailey item that looks "hard" but contains essential inheritance info
    2. That inheritance info belongs in the "soft" item or, better, in the DataRow instead of any CandidateItem
    3. A hard item for Bailey should be like any other non-inheritance item
    4. Voting resolution: if combination (hard + soft) is winning, winner is (hard > soft) ? hard : soft

comment:12 Changed 5 days ago by tbishop

I merged from branches/tbishop/t11299_two_kinds into trunk with changeset [14320]: extensive comments, clean-up, renaming, new subroutines; no intended change to functionality yet (except skipping a couple of log messages per ticket 10295).

I'll test on smoketest, expecting no changes, just the same old bugs.

Changed 5 days ago by tbishop

buggy voting A

Changed 5 days ago by tbishop

buggy voting B

Changed 5 days ago by tbishop

buggy voting C

Changed 5 days ago by tbishop

buggy voting D

Changed 5 days ago by tbishop

buggy voting E

comment:13 Changed 5 days ago by tbishop

I added five attachments showing a sequence of events on smoketest, illustrating buggy voting.

A: The item starts with only value "latn" inherited from root, in winning column, red background.

B: Add a new value "taml".

C: After adding "taml", it is winning, and the Others column has "latn", now blue background, change from red to blue being mysterious.

D: Vote for "latn" by clicking on it in the Others column; this should produce a winning vote for "soft" inheritance.

E: Instead we see what looks like a "hard" vote, with white background, and all inheritance info has disappeared from the info panel.

comment:14 Changed 4 days ago by tbishop

A widespread pattern in the code is replacement of a "soft" item with a "hard" item. There is one place where that makes perfect sense: in the user interface. We never display "↑↑↑", instead we display the corresponding inherited value, with a colored background to distinguish it from a "hard" item. Everywhere else, the pattern seems to have resulted in chaos. Not only is the string "↑↑↑" replaced, but various objects are replaced, with all their additional fields. When all the information associated with a "soft" item gets replaced by all the information associated with a "hard" item, or vice-versa, that replacement is essentially destroying the ability to make the clear distinction which is the subject of this ticket.

Therefore a key strategy is to eliminate that kind of replacement, except where absolutely necessary, as when we avoid displaying "↑↑↑" in the UI.

For voting resolution, replacement should not be necessary. Instead we need to implement the rule: if combination (hard + soft) is winning, winner is (hard > soft) ? hard : soft.

comment:15 Changed 36 hours ago by tbishop

About "example C" above, with the current code in branches/tbishop/t11299_two_kinds the items "Veräifachts Chineesisch" and "Chineesisch (Veräifachti Chineesischi Schrift)" are both displayed, which is an improvement. Clicking on "Chineesisch (Veräifachti Chineesischi Schrift)" in the Others cell causes the info panel to display "This item is inherited." That's good, however, there is no link in the info panel for "Jump to Original". It's missing since here in survey.js

if ( isInherited && (theRow.inheritedLocale || theRow.inheritedXpid )) {
	var clickyLink = createChunk(stui.str('followAlias'), "a", 'followAlias');
	clickyLink.href = '#/'+ ( theRow.inheritedLocale || surveyCurrentLocale )+
		'//'+ ( theRow.inheritedXpid || theRow.xpstrid ); //linkToLocale(subLoc);
	h3.appendChild(clickyLink);
}

isInherited is true, but theRow.inheritedLocale and theRow.inheritedXpid are both undefined.

They should have been set on the server in DataSection.java which has in DataRow.toJSONString:

jo.put("inheritedXpid", pathWhereFound != null ? XPathTable.getStringIDString(pathWhereFound) : null);
jo.put("inheritedLocale", inheritedLocale);
View

Add a comment

Modify Ticket

Action
as new
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.