Jump to content

Module talk:European and national party data/Archive 1

Page contents not supported in other languages.
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Julius Schwarz (talk | contribs) at 08:23, 10 April 2025 (Moved from Template talk:EUPP seats/Archive 1). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

Questions

Is there a way to made a testcases page for ModuleEUPPs/sandbox to test the impact of the proposed code?

Note: "for the 'share' outputs, should the output have a '%' suffix?" -> I would say no, as my idea was to use this for charts that need a percentage value (as a number, not a string). Julius Schwarz (talk) 08:03, 25 March 2025 (UTC)[reply]

I've copied the tests from User:Julius Schwarz/sandbox into {{test case}} templates at Template:SeatsEUPPs/testcases. I have also changed {{SeatsEUPPs/sandbox}} to use Module:SeatsEUPPs/sandbox. From the ~/testcases results, you can see that the live template rarely agrees with Module:SeatsEUPPs/sandbox. At a glance, testing the live module against the live template in ~/testcases gives similar results. No doubt, the live template uses it parameters differently from the modules.
To change the live template so that it uses the live module, copy the contents of the {{SeatsEUPPs/sandbox}} to {{SeatsEUPPs}}. In {{SeatsEUPPs}}, change the invoke to {{#invoke:SeatsEUPPs|main}}. Save.
Look at ~/testcases again. All tests should produce similar results; the flagged tests should be the result of different error message formatting.
Trappist the monk (talk) 16:14, 25 March 2025 (UTC)[reply]
How would one go about adding that "%"? Julius Schwarz (talk) 22:18, 25 March 2025 (UTC)[reply]
With the concatenation operator: ..'%'
Trappist the monk (talk) 23:39, 25 March 2025 (UTC)[reply]

Use of template

@Trappist the monk as you can tell, I am rather new to modules. My idea was that, by creating the module, we would use it directly in relevant pages. But from your last comment about the way forward, I have a sense that we will keep using the template. Does this mean that we should rewrite the template to call the module? For instance, the revised template would be {{SeatsEUPPs|EP|EPP}} and this would actually call {{#invoke:SeatsEUPPs|main|EP|EPP}}? Is it just for writing convenience, then? Julius Schwarz (talk) 08:09, 25 March 2025 (UTC)[reply]

I have no problem with using module invokes in article text... But, not all editors are sufficiently technically minded to do that. The template hides the function call (main) from editors.
The nice thing about Module:Arguments is that it automatically fetches arguments from the both the frame and the parent frame. Writing {{#invoke:SeatsEUPPs|main}} in the template will hand the parent frame parameters (from the template call in article wikitext) to the module. You can see this working in {{SeatsEUPPs/sandbox}}:
{{SeatsEUPPs/sandbox|EP|EPP}}Template:SeatsEUPPs/sandbox
Trappist the monk (talk) 16:14, 25 March 2025 (UTC)[reply]
Yeah, I have to admit that's neater this way. Thanks, it's all looking really clear. Julius Schwarz (talk) 21:35, 25 March 2025 (UTC)[reply]

Continuation

Hi @Trappist the monk, before you bow out, allow me to ask one more thing. I started replacing raw calls to wikidata with the module and it hit me that, in most cases, this is being used as part of a composition bar. Not always, but super often.

And all of a sudden, it became a bit irresistible to make another module, based on Module:SeatsEUPPs that would spit out the composition bar :D Now, I got the gist of most of the process, but I could use a quick hand to write the part that actually writes the composition bar using our module. Would you mind having a look? It's at Module:Sandbox/Julius Schwarz/CompositionBarEUPPs Julius Schwarz (talk) 21:43, 25 March 2025 (UTC)[reply]

Forking is a bad idea. Instead, add a new exported function to Module:SeatsEUPPs/sandbox that calls the necessary local functions to produce the output that you want. I've started a function composition_bar() at the bottom of ~/sandbox, added some comments and questions there. Improve on that.
{{#invoke:SeatsEUPPs/sandbox|composition_bar|EC|EPP}}Script error: No such module "SeatsEUPPs/sandbox".
Trappist the monk (talk) 22:50, 25 March 2025 (UTC)[reply]
Well noted. I started having a look at the comment you made. For line 346, indeed, share has no place here. That was in case "%" or "share" ended up as the party argument. Not happening here. And I will introduce data validation for width and percentage. However, I hit the same issue three times: 1) width should be a percentage and not a number should we can input it as a number but we have attach a "%" sign; 2) I have to attach a "#" sign to the hex code; and 3) I might attach a "%" for seats_share. In all three cases, I am not sure how to concatenate text. Julius Schwarz (talk) 23:57, 25 March 2025 (UTC)[reply]
According to the {{Composition bar}} documentation, width specified as without units assumes px. The documentation also says that the template will also accept % and em units. I've added a snippet of code to validate the width value. Should probably be a separate function. Also added '#' to the color.
Trappist the monk (talk) 00:45, 26 March 2025 (UTC)[reply]
Thanks and now indeed the colour displays properly. I did a similar operation to add "%" to the share_fc function, but reverted it as bar charts may need to do some calculation on the percentage, so better to leave it out until I create a separate function for this :) Julius Schwarz (talk) 08:05, 26 March 2025 (UTC)[reply]
Thanks for the help @Trappist the monk. I think we are nearing completion. I updated the roadmap above and I think when these items are done this can be considered completed for the time being and I will start using it on all relevant pages. Julius Schwarz (talk) 11:02, 27 March 2025 (UTC)[reply]
If {{CompositionBarEUPPs}} is going to mimic {{composition bar}}, it seems to me that {{CompositionBarEUPPs}} should use the same parameter names for the options:
  • |background-color=
  • |border=
  • |width=
  • |per=
  • |ref=
That means no {{{3}}}, {{{4}}}, {{{5}}}.
To override the wikidata-supplied bar color we might reinstate {{{3}}} for use as {{composition bar}} uses it, or create a new option parameter |bar-color=. This latter would be my preference. Of course, I would also spell-out |percent= and |reference= (and also rename {{CompositionBarEUPPs}} to {{Composition bar EUPPs}} or better, {{EUPP composition bar}} because English is written with space characters between words; I might even suggest {{EUPP seats}} as a better name).
Trappist the monk (talk) 14:35, 27 March 2025 (UTC)[reply]
That seems all very sensible. For the colour element, I think it is nice to have it, but it should just be the exception; by default, we just take the registered party colour. And I am happy to rename the modules and templates. As for the arguments, like I wrote in the table, I was unfortunately stuck when I tried to use something else than 'yes' for percentage or reference, for instance. Julius Schwarz (talk) 14:58, 27 March 2025 (UTC)[reply]
I've added a 'thisparty' test to validate_institution_party(). Seems to work, you might want to test it further.
Trappist the monk (talk) 15:27, 27 March 2025 (UTC)[reply]
Added support for |width= ({{{3}}}), |pc= ({{{4}}}), and |ref= ({{{5}}}). Still to do is to remove support for those positional parameters.
Trappist the monk (talk) 16:16, 27 March 2025 (UTC)[reply]
Rewrote get_colour(). The hash prefix is added there because it should be possible to use named colors in |bar-color= (which overrides the wikidata color). Other color parameters also appear to be working:
{{EUPP composition bar/sandbox|EC|EPP|bar-color=blue|border=red|background-color=#3a3}}Template:EUPP composition bar/sandbox
|percent= and |ref= are now case-insensitive. Positional parameters {{{3}}}, {{{4}}}, and {{{5}}} are now ignored.
Trappist the monk (talk) 00:31, 28 March 2025 (UTC)[reply]
Thanks for this, @Trappist the monk; this is now all reflected in the testcases and it is all working correctly. I will therefore move the code to the main module and update the documentation accordingly. Julius Schwarz (talk) 09:08, 28 March 2025 (UTC)[reply]
In the module sandbox, I have streamlined seats() and seats_share(). Template:EUPP seats/testcases seems to show that I did not break anything. If you agree then the live module should be updated from the sandbox.
Trappist the monk (talk) 15:42, 28 March 2025 (UTC)[reply]
The changes are deployed and I confirm that nothing is broken! However, I started having a look at translation and it won't be as easy as planned since the Wikidata templates are not the same on all wikis. I think I can handle it, though. Julius Schwarz (talk) 15:52, 28 March 2025 (UTC)[reply]

Massive thanks!

Just wanted to massively thank @Trappist the monk for their help on this. Given my own knowledge of Lua (or lack thereof), none of this would have been possible without them, and the code in the articles look much much neater now! I also learned a whole lot, which feels great. Admittedly, this does not impact too many pages per wiki, but it is directly applicable to many other wikis, so I look forward to working on translating it and replicating it! Julius Schwarz (talk) 14:38, 28 March 2025 (UTC)[reply]

Discussion

@Trappist the monk, wanna have some more Lua, party-related fun? ;) Julius Schwarz (talk) 21:03, 29 March 2025 (UTC)[reply]
Perhaps. The above isn't sufficiently clear to give me an understanding of what needs to be done. In our last venture there was a template that served as an armature upon which a module could be hung. That doesn't appear to be the case this go round.
Trappist the monk (talk) 22:03, 29 March 2025 (UTC)[reply]
I see what you mean. Obviously only points 1 and 7 need some Lua, and I think I can do most of point 1 by myself. As for point 7, it's actually just a simplified version of the EUPP seats module, except we do not need to indicate the party (it should be always use the party from which page it is called -- except for testing purposes, of course, and in this case we can give the qID of a specific national party) and we just use lower house or upper house for the institution (and the table in point 6 will make the link between the party's country and the qID of the lower or upper house). The way I see it, it's mostly a trimmed-down version of our previous module. Julius Schwarz (talk) 07:46, 30 March 2025 (UTC)[reply]
Do these templates/module in point 7 have a name? Point 7 mention a table from point 6. Is the table in point 6 something that exists on commons (Data:Seats_of_EU_national_parties_in_lower_and_upper_houses.tab or some other) or is the table something that is maintained in a lua ~/config module? Is such table necessary for the purposes of point 7?
I futzed about and hacked Module:Sandbox/Trappist the monk/party which seems to be a way to get all of the (so far) required data. Using the NEOS qid (NEOS – The New Austria (Q13564543)) for an example:
{{#invoke:Sandbox/Trappist the monk/party|main|Q13564543}}
The only thing that is obviously missing is a way to distinguish 'upper' from 'lower'.
Trappist the monk (talk) 16:56, 30 March 2025 (UTC)[reply]
That's a really good point, @Trappist the monk. My idea, since I am already using a Wikimedia Commons table for the module in point 1, was to also use a similar table that would just have six columns: country name, country_qid, lower house name, lower house qid, upper house name, upper house qid. Admittedly, only the qid are relevant, but that would make the table more readable to humans. As you indicate, that could probably also be in a config file. I guess the commons table might make it easier to amend if need be, but these are hardly things that are likely to change often. Come to think about it, we could even do without an extra table, as that information could be extracted from the commons table created for the module of point 1, which already links the qid of a national party with the qids of its lower and upper houses. The only issue with this is if someone tries to use the module (or its subsequent template) for a national party that is not a member of a European party; then it would not be included in the table made for the module of point 1 and the module/template would not work. By contrast, assume the party has a Wikidata page, this would most likely tie it to a jurisdiction and then we could tie it to a lower/upper house via either the commons table or the config file.
As for your code, that is really useful. The way that I see it, a normal call would be invoke: nameofmodule | main | house=lower-house or something similar. A qid would only be added for testing purposes and, in the absence of one, it would just take the one from the page in question (as when we used "thisparty" before). And then invoke: nameofmodule | composition_bar | house=lower-house would give the related composition bar. The related template would be "name of template | house=lower-house" and "name of template for composition bar | house=upper-house". Julius Schwarz (talk) 18:03, 30 March 2025 (UTC)[reply]
Here is the table I had in mind for point 6: https://commons.wikimedia.org/wiki/Data:Lower_and_upper_houses_of_eu_member_states.tab Julius Schwarz (talk) 18:45, 30 March 2025 (UTC)[reply]
In real life, are you a politician? You just spent a lot of words in saying relatively little. So let me ask specific questions:
If there is no wikidata mechanism to determine which house is upper and which house is lower, choose one of these:
  1. we require |house=<house name>
    + this method does not require a separate tabular data file
    − we must error check against the house names that wikidata knows about
  2. we fetch upper/lower qids from Data:Seats_of_EU_national_parties_in_lower_and_upper_houses.tab
    + if that table is required elsewhere, no need to error check
    − if that commons .tab file is not required elsewhere, it now becomes required here
It seems to me that these modules should not rely on multiple data sources if at all possible. So, if point 7 can be satisfied by fetching its data from wikidata and requiring |house=<house name>, that would be best.
You assiduously avoided the Do these templates/module in point 7 have a name? question. What is the answer to that question?
You haven't actually said: for the composition bar, is it the number of party seats against the number of house seats?
Is the table in point 6 complete? Are there countries that have only one house? How do we distinguish between a unicameral country and missing data?
Trappist the monk (talk) 19:13, 30 March 2025 (UTC)[reply]
Argh! On the other hand... a commons table like Data:Seats_of_EU_national_parties_in_lower_and_upper_houses.tab that holds all of the necessary data avoids the issue of inconsistency at wikidata. For example, Independent Democratic Serb Party (Q1261401) doesn't have color (P462) but instead has sRGB color hex triplet (P465). No doubt there are other inconsistencies. Like Denmark Democrats - Inger Støjberg (Q112677506) which lists two hex colors... Which of those do we use?
Given that, I'm thinking that I might change my position to: both the point 1 and point 7 modules shall require the commons tabular data file that shall hold verified qids for those items that should be held in wikidata: seats occupied, number of seats in the party, etc – the periodically changing stuff. House names, party color, etc, stuff that rarely changes can be held in the tabular data file so that wikidata inconsistencies are avoided.
Trappist the monk (talk) 19:49, 30 March 2025 (UTC)[reply]
Hmm, I am reluctant to put too much in tabular data file, specifically to avoid things changing that would then need to be updated in that table, and I keep all that information updated: what if a party changes its colour? what if the name of a house changes? What I want to keep in that table (and what I can keep updated) is what national parties belongs to which European party (and locally, I have an easy was to assign the lower/upper house and their qid based on the country in question).
As to having a way to determine which house is lower and which is upper, I am sure I understand what this is for. Say you have the template in the infobox of a party; you call that template saying "lower-house". From the page of the party, you derive the party's qid, from that qid you vlookup the table to find the qid of the lower house in the tabular data, then you can place a call to wikidata to get the number of seats of that party in the lower house, and to get the total number of seats of that house. I am actively avoiding needing to add arguments in order to make the template copy-pastable, and I am not sure we can directly derive the lower house and the upper house just from the wikidata page of a country (as some will directly list upper/house, while other will point to the name of the bicameral parliament, which in turn will point to both houses).
Inconsistencies? I will go through all relevant parties, as indicated in point 5 (had not thought of missing P465, but I can make sure they exist) for all relevant parties. Likewise, I made the table of upper/lower houses and made sure it is complete and accurate; where this is no upper house, the legislative is unicameral.
Names of the modules in point 7 and 8? I don't know. Module: "Seats of EU national parties", something to that affect? Julius Schwarz (talk) 20:52, 30 March 2025 (UTC)[reply]

There may be a way to distinguish upper from lower in wikidata if the descriptions can be more-or-less normalized. Here is a list taken from the point 6 tabular data file. You can see that there is rather a large amount of variation amongst these descriptions – more of what I was saying about wikidata inconsistency. Of course these could all be normalized to some degree and then along comes Joe Editor who tweaks his country's description and the whole mess falls apart.

description from wikidata

I have, I think noodled out how to get colors. Some parties list both color (P462) and sRGB color hex triplet (P465) so when that occurs, I have elected to use the P465 triplet because that seems more 'precise'?

Trappist the monk (talk) 00:59, 31 March 2025 (UTC)[reply]

I would agree with your assessment, whenever P465 is there, that's the better choice. As I said, I will try and ensure that it is there wherever possible.
As for the upper/lower house distinction from Wikidata, I am still unsure as to why you think you need this. Take Christian Social Union in Bavaria, for instance. Currently, the infobox contains reads, for the Bundestag, currently, the infobox, for the Bundestag seats, reads as follows: {{composition bar|44|100|hex={{party color|Christian Social Union of Bavaria}}|border=silver}}. I am suggesting to replace this with {{Seats of EU national parties|house=lower-house}}. The template would grab the CSU's qID, look up its jurisdiction, and then, from the tabular data from point 6 or from the config file, would derive the qID of the Bundestag and give out the composition bar. I understand your point of limiting the use of multiple data sources, but as you point out Wikidata is not consistent in its descriptions. And, at any rate, we would still need the template to be told whether we need upper or lower house seats, so I am unsure why you are trying to grab that information from Wikidata when we have an easy way to get the house's qid easily. Julius Schwarz (talk) 07:13, 31 March 2025 (UTC)[reply]
To limit the number of data sources. Since it is necessary to fetch total number of seats in a house and the numbers of seats occupied by the various parties from wikidata, it seems to me that we should fetch as much data as possible from wikidata rather than have two separate sources. Other editors are going to maintain the wikidata data but who will maintain the commons tabular data? You? What happens when you open your door, step out, and are suddenly flattened by a steamroller?
Currently there are four sources of data for Module:Sandbox/Julius Schwarz/EU party seats lower upper houses: wikidata, the wide tab file, the narrow tab file, and ~/config. Are all four really required? Numbers of seat and the numbers of the various occupants will periodically change so wikidata is required. Do we really need both the wide and the narrow tab files? It seems that all of the data in the narrow tab file is or in a future incarnation will exist in the wide tab file, so if a tab file is required, only one will be needed. Because data for these modules will be sourced from wikidata and perhaps a tab file, ~/config should not hold anything more than whatever is required for i18n.
Looking at what the point 1 module already does, tell me again what it is the the point 7 module will do differently?
Trappist the monk (talk) 17:20, 31 March 2025 (UTC)[reply]
In the meantime, I managed to make substantial progress on the module of point 1. I can now get the number of seats of European parties' member parties, both for an actual party and using "all" -- at least based on this small test table.
However, the composition_bar function, which used to work when only grabbing the data from the test table, no longer works when trying to get the total number of seats of all lower houses (for instance) using the table made in point 6. Somehow get_house_seats returns a string, but I cannot see why.
Looking forward, I am not quite sure how to grab the qID of the relevant European party when the module is called with "this party" instead of a party name.
Any ideas? Julius Schwarz (talk) 12:09, 31 March 2025 (UTC)[reply]
The call to sum_house_seats() looked like this:
local sum_house_seats = sum_house_seats(frame, european_party_name, house_type);
but the function definition looked like this:
local function sum_house_seats(frame, house_type)
house_type was getting its value from european_party_name so the code to get house_qid was bypassed. The default state of house_qid was empty string. When given an empty-string qid, {{wikidata}} returns an empty string; you can't add an empty string to a number.
The third entry in c:Data:Lower and upper houses of eu member states.tab does not have an upper house so the code at lines 126–131 returns a nil value for house_qid. When given a nil qid, {{wikidata}} returns an empty string; you can't add an empty string to a number.
I changed that function so that any nil house_qid skips the call to {{wikidata}} and the function returns the number zero.
To get the qid for the current page:
local this_page_qid = mw.wikibase.getEntityIdForCurrentPage();
Trappist the monk (talk) 17:20, 31 March 2025 (UTC)[reply]
Aaaaahhhhh, thanks, I had missed that. Made some changes and I must have forgotten to remove that argument. And thanks for the qID of the current page, I will try and add that tomorrow and then work on some test cases and validation. Julius Schwarz (talk) 20:11, 31 March 2025 (UTC)[reply]
Aaaand once again, made progress, even added support for "thisparty" which works when called from page of a European party, but I get an error in the test cases and I am not finding it... Julius Schwarz (talk) 14:16, 1 April 2025 (UTC)[reply]
Aaand I just broke it even further before having to stop working... Julius Schwarz (talk) 16:29, 1 April 2025 (UTC)[reply]
(edit conflict)
You've changed the module (and this page) since I began writing this response.
This is the first failure that I see saw listed under Module talk:Sandbox/Julius Schwarz/EU party seats lower upper houses/testcases § test main:
{{#invoke:Sandbox/Julius Schwarz/EU party seats lower upper houses|main|ALL|lower-house}}Script error: No such module "Sandbox/Julius Schwarz/EU party seats lower upper houses".
Clearly, that works worked (it returned 406). There are four of these tests that differ only in the casing of the ALL, All, all (2×). At the bottom of ~/testcases is the hidden category Category:Pages with too many expensive parser function calls. When the expensive error counter exceeds the limit (500), get_party_seats() returns this error message (a string) instead of a numeric value:
Lua error in Module:Sandbox/Julius_Schwarz/EU_party_seats_lower_upper_ho at line 185: <strong class="error"><span class="scribunto-error mw-scribunto-error-449e5552">Lua error: too many expensive function calls.</span></strong>
The simple fix then ought to be the removal of test cases that are substantially the same.
Trappist the monk (talk) 17:00, 1 April 2025 (UTC)[reply]
Thanks and, indeed, it used to work. However, I removed a whole bunch of test cases (had not considered the load, and actually maybe we can remove the option to quiz all, that might just be too much when the table is complete). However, the error is still there, it would seem. The last thing I did was to introduce to that "error house name" to try and figure out where things broke, but did not find the solution. Julius Schwarz (talk) 21:02, 1 April 2025 (UTC)[reply]
Preview ~/testcases with this version of the module. The expensive parser function count no longer exceeds the limit (371/500).
Are ms-lower-house and ms-upper-house accepted parameter values but lower-house and upper-house are not? You are not checking for those so the tests that set the 'house' parameter to either of those values fail with 'error house name'. If the test for house_type is supposed to be the same for both main() and composition_bar(), you should probably make that test a simple function.
Trappist the monk (talk) 22:04, 1 April 2025 (UTC)[reply]
The idea was as follows: since the testing on whether the house type is lower or upper house is always done with "lower-house" or "upper-house", I would not touch them and instead just to rename house_type to, for instance, "lower-house" if "lower" or "ms-lower-house" was entered. This way all three values would be accepted. I am actually not sure I understand what does not work with the present code (just like I don't really get why it impact main and not composition_bar even though it's the same code in both), but I try and make this a separate function indeed. Julius Schwarz (talk) 06:23, 2 April 2025 (UTC)[reply]
Seems fixed. I guess the issue was not to have an "else". Julius Schwarz (talk) 07:53, 2 April 2025 (UTC)[reply]
Important note, the module is now integrated into Module:EUPP seats/sandbox, which is were further changes should be made.
@Trappist the monk, I will add missing comments in the code. Could you kindly have a look to see whether things are well done and/or whether anything can make the code more efficient? Julius Schwarz (talk) 12:12, 2 April 2025 (UTC)[reply]
I have done some rewriting:
  • Module:Tabular data no longer used in favor of fetching data directly from tab_data_t and ms_data_t. Those sequences were previously used only as loop counters. See get_house_seats(), get_national_party_seats(), and sum_national_party_seats().
  • to support direct access of data in tab_data_t and ms_data_t, I created a function build_tab_data() in Module:EUPP_seats/config. This function creates a sequence of associative arrays where the appropriate column name indexes the row's data field.
  • I deleted the function table.find(). Its functionality is replaced by invert_party_qid_map() in Module:EUPP_seats/config. This avoids repeatedly looping through cfg.parties_t looking for 'this whatever's qid'. See validate_party_house_type() and sum_national_party_seats().
Trappist the monk (talk) 20:03, 2 April 2025 (UTC)[reply]
Fantastic! I was really glad it worked, but I did have a hunch things could be done better :) Thank you! Julius Schwarz (talk) 20:17, 2 April 2025 (UTC)[reply]

Point 3 (ex-point 7)

I see that the discussion on the second module got lost in the error corrections of the first module. Now that the first module is nearing completion (and is integrated in Module:EUPP seats/sandbox), I would be happy to re-open this discussion, @Trappist the monk.

One of your last question (that I left unanswered) was what the second module (now point 3.1) would do differently from the first. Both actually have a different focus:

  • the first module aims at being called from the page of a European political party and to sum the members on lower/upper houses of its national member parties; since the calculation is different from our previous Module:EUPP seats, I thought of keeping both separate, but then I figured it might make more sense to merge them;
  • the second module aims at being called from the page of a national political parties and just grab its number of seats on lower/upper houses from Wikidata (a bit what Module:EUPP seats initially did for European parties, but at the national level); to me the idea of this is to try and move as much data to Wikidata and to encourage anyone seeking to update data on Wikipedia to actually do so on Wikidata instead.

Is that clearer like this?

PS: I added a function in the roadmap -- sometimes it would be useful to override the total number of seats in the composition bar (for cases where we would want to give out the number of seats of sub-group of the house, instead of the whole house). Julius Schwarz (talk) 14:01, 2 April 2025 (UTC)[reply]

Also, @Trappist the monk do you confirm that you wish to discontinue the use of the "narrow" tab file and only extract data from the "wide" tab file? I can see how this limits the number of files we use, but is that efficient? It's a genuine question. The narrow one makes it straightfoward to count the total number of seats on lower or upper houses (without counting anything twice). If there is a way to make it as efficient (or nearly) with one file, that is of course fine by me. And, indeed, it is likely that the information from the narrow one will be in the wide one -- this would not be the case if, for instance, a member state had none of its national parties that a is a member of a European party; it could happen, but in practice it doesn't. Julius Schwarz (talk) 07:40, 3 April 2025 (UTC)[reply]
The narrow commons file is no longer required. I have added a function to Module:EUPP seats/config, extract_ms_data(), that extracts the necessary data from the data extracted from the wide tab file. So long as the multiple copies of each member_state row in the wide tab are all the same, the data for lower_house, lower_house_qid, upper_house, and upper_house_qid in the new ms_tab_t sequence should be correct (the new function takes only the row of data from the first encounter of a member state). Some of those data are not currently used: member_state, lower_house, and upper_house could be excluded from the new ms_tab_t sequence.
Trappist the monk (talk) 01:04, 4 April 2025 (UTC)[reply]
This last point means removing member_state = row_t.member_state, and the two other similar lines from extract_ms_data in the config file, right? Julius Schwarz (talk) 09:12, 4 April 2025 (UTC)[reply]
Or not. If there will be a need for those then you should leave them in; if not, delete of comment out.
Trappist the monk (talk) 13:58, 4 April 2025 (UTC)[reply]
I will try and get started on this module tomorrow or the day after. Julius Schwarz (talk) 15:51, 6 April 2025 (UTC)[reply]
@Trappist the monk I have done some work on the national_party_composition_bar function and it seems to be working (although test cases are tricky because it is always called from the page of a national party). Would you mind having a look and checking whether the code is sound? I have tried it successfully on The Ecologists and on a non-party page where, expectedly, it gives an error message. Julius Schwarz (talk) 19:48, 7 April 2025 (UTC)[reply]
Seems like there is some commonality between composition_bar() and national_party_composition_bar(). Perhaps parts of those function that can be shared ought to be shared as separate functions.
Trappist the monk (talk) 22:07, 7 April 2025 (UTC)[reply]
They are close and do related things, but they operate differently, as the first one applies to all institutions but only for the European parties/alliances listed in the config file, while the other only works for lower/upper houses (therefore a different validation mechanism) and for all parties listed in the wide table. It's close, but, given the differences, I do not know whether we truly gain from trying to force a unique function that would have to be implemented in different ways. Just my two cents as things stand and happy to be proven wrong :) Julius Schwarz (talk) 07:17, 8 April 2025 (UTC)[reply]
@Trappist the monk Anything else to consider before we deploy the sandbox to the main module? Julius Schwarz (talk) 14:00, 8 April 2025 (UTC)[reply]
Almost always. The problem is in knowing what to consider. That lack of knowledge hasn't stopped you from deploying this module in the past, why worry about it now? If doing so breaks stuff, you'll know it soon enough.
Trappist the monk (talk) 14:16, 8 April 2025 (UTC)[reply]
Maybe I'm trying to learn from my mistakes and referring to a higher authority to be more careful? Julius Schwarz (talk) 14:38, 8 April 2025 (UTC)[reply]

Adding support for European political alliances

Hi @Trappist the monk, I added European political alliances in the config file. However, I then made changes to the module (seemed like a quick fix) but, I must have forgotten something, because it broke the non-party calls (misc_parties_t and keywords_t). Basically, European political alliances should work just like European political parties but should not count in the sum of seats occupied by all European parties ('all') and therefore also not in the sum of seats occupied by no European party ('none'); but should be able to get their number of seats and derive a composition bar. Julius Schwarz (talk) 15:20, 3 April 2025 (UTC)[reply]

Some of the problem was resolved by exporting alliances_t from ~/config. I fixed most of the other glaring red error messages. One that I didn't fix was this from one of the testcases pages:
{{#invoke:EUPP seats/sandbox|main|EP||%}}Script error: No such module "EUPP seats/sandbox".
That used to work (produced the 'party is required for share' error message). I leave it to you to figure out what it is that you did to break it.
Trappist the monk (talk) 17:05, 3 April 2025 (UTC)[reply]
Oh, and, I first made these changes to the live module; I should not have done that. I have reverted the changes in the live module and made them in the sandbox because that is what sandboxen are for.
Trappist the monk (talk) 17:15, 3 April 2025 (UTC)[reply]
Thanks @Trappist the monk; is it perhaps possible that I changed an "if ... else..." into an "if ... elseif ... elseif..." (where the double elseif was aimed at separating cfg.parties_t from cfg.alliances_t) but that, in doing so, the other cases (everything else caught by "else") was not accounted for? I am having a look here and am looking at line 160 (old version). Julius Schwarz (talk) 20:35, 3 April 2025 (UTC)[reply]
Could well be. In the current live version, args_t ends up as {'property', nil, 'P1410'} which causes the call to expand {{wikidata}} to return an empty string. Perhaps the thing to do is to add this at line 154:
	elseif not party then														-- <party> missing
		return	make_error_msg (substitute (cfg.error_messages_t.party_req_share));
	else																		-- <party> unknown
		return  make_error_msg (substitute (cfg.error_messages_t.inst_unknown_party, {institution, party}));
Current lines 161–164 go away as redundant.
I gotta wonder: is that the correct error message? single() is called twice: from seats() (currently line 222) and from seats_share() (currently line 260). Certainly the ...required for share bit is required for seats_share() but for seats()?
Trappist the monk (talk) 22:03, 3 April 2025 (UTC)[reply]
It would seem like the errors are just due to too many calls, maybe? I made a separate testcase page just for composition bars and it all seems to work well. Julius Schwarz (talk) 08:19, 4 April 2025 (UTC)[reply]
As for the error message, it is to cover calls like this one {{#invoke:EUPP seats/sandbox|main|EP||%}}. Julius Schwarz (talk) 08:27, 4 April 2025 (UTC)[reply]
Really, just that? Then perhaps that error message should be moved to seats_share() right at the top; something like this:
	if not party then															-- party not specified, abandon with error message
		return	make_error_msg (substitute (cfg.error_messages_t.party_req_share));
	end
no point in doing all of the work in seats_share() only to have single() return an error message because a required element was missing.
Trappist the monk (talk) 14:40, 4 April 2025 (UTC)[reply]
At Module talk:EUPP seats/sandbox/testcases composition bar, not a single test passes. I gotta wonder if there is sommat wrong with Module:UnitTests. If I tweak the first test so that the numbers match (which in itself suggests that Module:EUPP seats/sandbox isn't working correctly). Then if the two outputs match I should get 'same':
{{#ifeq:{{#invoke:EUPP seats/sandbox|composition_bar|EP|ALDE}}|{{Composition bar|49|720|hex=#FFD700}}|same|not same}} → not same
and I do. Something about Module:UnitTests is not working correctly. That still leaves questions about the testcases:
  • is Module:EUPP seats/sandbox working correctly when it produces numbers that are different from the expected numbers?
  • are the expected numbers correct?
  • what about the tests that show different colors? which is correct?
As an experiment, I edited Module:EUPP seats/sandbox/testcases composition bar so that the first test expected and actual were the same:
self:preprocess_equals('{{#invoke:EUPP seats/sandbox|composition_bar|EP|ALDE}}', '{{#invoke:EUPP seats/sandbox|composition_bar|EP|ALDE}}')
Module:UnitTests still thinks that the test fails.
Trappist the monk (talk) 14:40, 4 April 2025 (UTC)[reply]
I made changes here and there to the test, varying the party, etc., without always warying the colour for instance, so there are normal discrepancies. However, even when the bars exactly match the result of the test is shown as negative, it's always been like this for me.
More worryingly, though, all the composition bars are broken, even in the main module, the one that worked an hour ago (haven't touched it since). Check European Green Party for instance Julius Schwarz (talk) 14:52, 4 April 2025 (UTC)[reply]
The error is always "Lua error in Module:EUPP_seats/config at line 151: table index is nil." Julius Schwarz (talk) 14:54, 4 April 2025 (UTC)[reply]
Why does the last row of c:Data:Seats of EU national parties in lower and upper houses.tab hold only 'null' values. Delete that row and I expect that European Green Party will stop showing the glaring red error messages. You did just edit that table, right?
Trappist the monk (talk) 15:15, 4 April 2025 (UTC)[reply]
You were right, that was the issues. Turns out it's something that is added when importing a csv file. Would it be possible for the function to account for that and to simply ignore a line that has no european_party? Julius Schwarz (talk) 18:41, 4 April 2025 (UTC)[reply]
When testing the output of a template or module against the output of another template or module, you need to use preprocess_equals_preprocess. When that test is used, this test passes:
self:preprocess_equals_preprocess('{{#invoke:EUPP seats/sandbox|composition_bar|EP|ALDE}}', '{{#invoke:EUPP seats/sandbox|composition_bar|EP|ALDE}}')
preprocess_equals fails because the test is comparing the preprocessed output of the #invoke against the plain wikitext of the expected template. This:
<strong class="error"><span class="scribunto-error mw-scribunto-error-24c2d55e">Script error: No such module &quot;EUPP seats/sandbox&quot;.</span></strong>
does not equal this:
{{#invoke:EUPP seats/sandbox|composition_bar|EP|ALDE}}
Trappist the monk (talk) 17:03, 4 April 2025 (UTC)[reply]
Just changed it, thanks! Julius Schwarz (talk) 17:53, 4 April 2025 (UTC)[reply]