As the most likely audience for this post are Flemish table tennis players, most of it is written in Dutch. Here a short summary:
I have played table tennis competitively for the last 15 years at table tennis club TTK Minderhout. Unfortunately a lot of visiting players do not like our accommodation and believe we have an unfair home advantage. All Flemish table tennis matches since season 2006-2007 are accessible through an open API. Analysing that data, shows that the average home advantage across all Antwerp clubs is about 5 percentage points (difference in win probability of home games versus out games). TTK Minderhout has no excessive home advantage whatsoever.
Nee, is het antwoord.
Ik speel sinds 2002 tafeltennis bij tafeltennisclub TTK Minderhout. Na 4 jaar jeugdcompetitie, heb ik er nu ook een 15-tal jaren herencompetitie binnen de provincie Antwerpen opzitten, op een korte uitzwerving naar Ekerse na. TTK Minderhout huurt al zolang ik er speel tafeltennislokaal de noodkerk van het kerkfabriek. De speelzaal heeft een betonnen vloer, wat enige voordelen heeft inzake multifunctioneel gebruik van de zaal.
De meeste Antwerpse clubs spelen op een houten vloer of een sportvloer als in een turnzaal. In tafeltennis beinvloedt de ondergrond best wel de speelervaring, zoals in tennis gravel en gras dat ook doen (doch minder extreem in tafeltennis). Daar bezoekende ploegen en spelers onze vloer niet gewend zijn, en tafeltennisspelers een ras apart zijn, geeft dit regelmatig klagende en jammerende tegenstanders, wat voor ons als gastploeg al jaren een domper op de speelvreugde zet. Maar goed, misschien hebben ze gelijk. Vandaar dat ik tijdens de competitiestilte tijdens de coronacrisis eens de moeite heb genomen om na te rekenen wat de statistieken zeggen.
Sinds seizoen 2006-2007 worden alle wedstrijden van de Vlaamse Tafeltennis Liga (VTTL) bijgehouden op https://competitie.vttl.be/. In de beginjaren was de URL iets als vttl.frenoy.net
(URL werkt niet meer), naar de hoofdontwikkelaar Gaetan Frenoy. Tafeltennis was daarmee een van de eersten om zo uitgebreid digitaal te gaan. Badminton, squash, tennis zijn veel later gevolgd (badminton en squash met een toernooi.nl systeem, tennisvlaanderen met zijn eigen systeem). Na al die tijd vind ik het VTTL systeem het meest responsieve en gebruiksvriendelijke systeem, althans om snel en veel gedetailleerde resultaten te kunnen raadplegen. Ook de Franstalige vleugel en recreatieve federatie Sporcrea gebruiken ditzelfde systeem.
Gaetan Frenoy is zelfs zo goed geweest om een publieke SOAP API naar de database met spelers en uitslagen te voorzien. Deze heet de TabT API: http://tabt.frenoy.net/index.php?l=EN&display=MainPage_EN
Nu ben ik zelf geen held in web development en het ontrafelen van dergelijke APIs. Volgende website van TTC Erembodegem is voor mij daarom erg waardevol geweest om geautomatiseerd de nodige wedstrijd data te downloaden: Op http://ttc-erembodegem.be/tabtapi-test/ kan je bepaalde queries via een formulier doen. De broncode achter dit formulier is ook openbaar, namelijk: https://github.com/Laoujin/ttc-test-tabtapi
Om de SOAP API aan te roepen, is de zeep
module een handige manier
import zeep
wsdl = 'https://api.vttl.be/?wsdl'
client = zeep.Client(wsdl=wsdl)
credentials = {'Account':'foo', 'Password':'bar'}
client.service.Test(credentials)
{
'Timestamp': datetime.datetime(2021, 7, 21, 14, 12, 38, tzinfo=<FixedOffset '+02:00'>),
'ApiVersion': '0.7.25',
'IsValidAccount': False,
'Language': 'nl',
'Database': 'vttl',
'RequestorIp': '2.15.139.88',
'ConsumedTicks': 18,
'CurrentQuota': 0,
'AllowedQuota': 8000,
'PhpVersion': None,
'DbVersion': None
}
Wat je nog meer kan met niet-dummy credentials, weet ik niet. De response geeft ook wat aan van quota. Als we hier tegenaanlopen, dan doen we even een sleep
en proberen we nog eens. Excuses Gaetan!
result = client.service.GetClubs()
print(result.ClubCount)
534
Een print
van de hele result is zeer leerrijk, maar laat ik hier achterwege omwille van de lengte. Dit resultaat ziet er erg uit als een json
dingetje. In praktijk is het een zeep
object, dat eerder als een klasse met attributen aangeroepen moet worden dan een dict
met keys.
result = client.service.GetSeasons()
print(result.CurrentSeason, result.CurrentSeasonName)
22 2021-2022
Seizoenen hebben naast een naam ook een integer label, wat gebruikt kan worden als argument van API calls (bvb. leden van een club in een bepaald seizoen).
Voor clubs is dan weer de clubcode als string nodig. Voor TTK Minderhout is deze A135
result = client.service.GetClubTeams(credentials, 'A135')
result.ClubName
'TTK Minderhout'
Als we GetMatches
aanklikken op de TTC Erembodgemse test website, krijgen we signatuur van de GetMatches
functie te zien. Deze ziet er zo uit:
Request structure:
Array
(
[Credentials] => Credentials Object
(
[Account] =>
[Password] =>
)
[DivisionId] =>
[Club] =>
[Team] =>
[DivisionCategory] =>
[Season] =>
[WeekName] =>
[Level] =>
[ShowDivisionName] => no
[WithDetails] =>
[MatchId] =>
)
Met deze API call trekken we alle competitieve ontmoetingen van TTK Minderhout in seizoen 2017-2018 binnen. Dit waren er 130.
club = 'A135'
result = client.service.GetMatches(credentials, None, club, None, None, 18)
print(result.MatchCount)
130
Een enkele ontmoeting ziet er dan zo uit:
result.TeamMatchesEntries[0]
{
'DivisionName': None,
'MatchId': 'PANTH01/014',
'WeekName': '01',
'Date': datetime.date(2017, 9, 15),
'Time': datetime.time(20, 0),
'Venue': 1,
'VenueClub': 'A135',
'VenueEntry': {
'Id': None,
'ClubVenue': None,
'Name': 'TTC Minderhout (Noodkerk)',
'Street': 'Schoolstraat',
'Town': '2322 Minderhout',
'Phone': None,
'Comment': None
},
'HomeClub': 'A135',
'HomeTeam': 'Minderhout A',
'AwayClub': 'A139',
'AwayTeam': 'Hallaar A',
'Score': '13-3',
'MatchUniqueId': 278412,
'NextWeekName': '02',
'PreviousWeekName': None,
'IsHomeForfeited': False,
'IsAwayForfeited': False,
'MatchDetails': None,
'DivisionId': 3324,
'DivisionCategory': 1,
'IsHomeWithdrawn': 'N',
'IsAwayWithdrawn': 'N',
'IsValidated': True,
'IsLocked': True
}
Mijn houtje touwtje code hieronder parst de Score
string en filtert bovendien de jeugdwedstrijden eruit op basis van de MatchID
string.
home_games = 0
away_games = 0
home_wins = 0
home_loss = 0
away_wins = 0
away_loss = 0
for i, entry in enumerate(result.TeamMatchesEntries):
if 'J' in entry.MatchId: # Filter jeugdwedstrijden er uit...
continue
if not entry.Score:
continue
home, away = entry.Score.split('-')
try:
home = int(home)
away = int(away)
except:
continue
if entry.HomeClub == 'A135':
home_games += 1
home_wins += home
home_loss += away
else:
away_games += 1
away_wins += away
away_loss += home
print(home_games, away_games)
53 53
We tellen evenveel uitwedstrijden als thuiswedstrijden
print("%i, %i, %.3f, %i, %i, %.3f" % (home_wins, home_loss, home_wins/(home_wins + home_loss), away_wins, away_loss, away_wins/(away_wins + away_loss)))
476, 371, 0.562, 426, 422, 0.502
In dit ene seizoen heeft TTK Minderhout 476 individuele overwinningen thuis gehad, tegenover 371 nederlagen, goed voor een winstpercentage van 56%. Op verplaatsing heeft TTK Minderhout 426 overwinningen geboekt tegenover 422 nederlagen, goed voor een winstpercentage van 50%.
home_wins/(home_wins + home_loss) - away_wins/(away_wins + away_loss)
0.05962498050834242
In dit specifieke seizoen heeft TTK Minderhout een thuisvoordeel van 6 procentpunten gekend. Bovendien geen slecht seizoen voor de club met meer gewonnen dan verloren wedstrijden.
Laten we nu itereren over alle beschikbaren seizoenen:
divisionId = None
club = 'A135'
team = None
divisionCategory = None
for season in range(7, 22):
result = client.service.GetMatches(credentials, divisionId, club, team, divisionCategory, season)
home_games = 0
away_games = 0
home_wins = 0
home_loss = 0
away_wins = 0
away_loss = 0
for i, entry in enumerate(result.TeamMatchesEntries):
if 'J' in entry.MatchId: # Jeugd...
continue
if not entry.Score:
continue
home, away = entry.Score.split('-')
try:
home = int(home)
away = int(away)
except:
continue
if entry.HomeClub == 'A135':
home_games += 1
home_wins += home
home_loss += away
else:
away_games += 1
away_wins += away
away_loss += home
#print(i, home, away)
try:
home_ratio = home_wins/(home_wins + home_loss)
away_ratio = away_wins/(away_wins + away_loss)
except:
home_ratio = -1
away_ratio = -1
print("%i, %i, %i -- %i, %i, %.3f, %i, %i, %.3f, \t %.3f" % (season, home_games, away_games,
home_wins, home_loss, home_ratio,
away_wins, away_loss, away_ratio, home_ratio - away_ratio))
7, 33, 33 -- 304, 200, 0.603, 319, 184, 0.634, -0.031
8, 42, 42 -- 337, 335, 0.501, 284, 388, 0.423, 0.079
9, 60, 60 -- 683, 277, 0.711, 627, 333, 0.653, 0.058
10, 61, 61 -- 500, 474, 0.513, 446, 529, 0.457, 0.056
11, 58, 55 -- 476, 452, 0.513, 418, 462, 0.475, 0.038
12, 53, 51 -- 285, 563, 0.336, 212, 604, 0.260, 0.076
13, 42, 40 -- 282, 389, 0.420, 233, 407, 0.364, 0.056
14, 41, 41 -- 393, 263, 0.599, 347, 309, 0.529, 0.070
15, 41, 41 -- 367, 289, 0.559, 329, 327, 0.502, 0.058
16, 28, 29 -- 261, 187, 0.583, 273, 191, 0.588, -0.006
17, 32, 32 -- 296, 216, 0.578, 273, 239, 0.533, 0.045
18, 53, 53 -- 476, 371, 0.562, 426, 422, 0.502, 0.060
19, 60, 60 -- 604, 356, 0.629, 536, 424, 0.558, 0.071
20, 52, 52 -- 409, 423, 0.492, 342, 489, 0.412, 0.080
21, 11, 12 -- 81, 95, 0.460, 82, 110, 0.427, 0.033
Het schommelt dus rond de 3 en 8 procentpunten, met een gemiddelde van 5.3.
De code hieronder genereert de lijst van alle Antwerpse clubs.
names = []
for i, club in enumerate(client.service.GetClubs().ClubEntries):
if club.CategoryName != 'Antwerpen':
continue
if club.VenueCount == 0:
continue
clubId = club.UniqueIndex
names.append(club.Name)
print(i, clubId, club.Name)
1 A003 Salamander
2 A008 Brasgata
3 A062 AFP Antwerpen
4 A074 Hove
5 A075 Rupel
6 A095 Turnhout
7 A097 Nijlen
8 A105 Dessel
9 A115 Dylan Berlaar
10 A117 Geelse
11 A118 Rijkevorsel
12 A123 Virtus
13 A127 Retie
14 A129 Borsbeek
15 A130 Schoten
16 A135 Minderhout
17 A136 Zoersel
18 A138 Blue Rackets
19 A139 Hallaar
20 A141 Merksplas
21 A142 Tecemo
22 A147 Gierle
23 A155 Wommelgem
24 A159 Real
25 A160 Walem
26 A167 Lille
27 A176 Sokah
28 A182 Nodo
29 A186 Willebroek
30 A201 Hulshout
31 A211 Zwijndrecht
32 A212 Antonius
33 A216 Henricus
34 A218 Poppel
35 A219 Stari Bog
We hebben dus een drievoudige lus nodig: over alle clubs, alle seizoenen en dan alle gevonden wedstrijden:
import time
for i, club in enumerate(client.service.GetClubs().ClubEntries):
if club.CategoryName != 'Antwerpen':
continue
if club.VenueCount == 0:
continue
clubId = club.UniqueIndex
time.sleep(1.) # Sleep helpt met de quota niet te overschrijven / server niet te overbelasten
divisionId = None
team = None
divisionCategory = None
home_games = 0
away_games = 0
home_wins = 0
home_loss = 0
away_wins = 0
away_loss = 0
for season in range(15, 22):
success = False
while not success:
try:
result = client.service.GetMatches(credentials, divisionId, clubId, team, divisionCategory, season)
success = True
except Exception as e:
print('fail', e)
time.sleep(30.) # Sorry Gaetan!
for i, entry in enumerate(result.TeamMatchesEntries):
if 'J' in entry.MatchId: # Jeugd...
continue
if not entry.Score:
continue
home, away = entry.Score.split('-')
try:
home = int(home)
away = int(away)
except:
continue
if entry.HomeClub == clubId:
home_games += 1
home_wins += home
home_loss += away
else:
away_games += 1
away_wins += away
away_loss += home
#print(i, home, away)
try:
home_ratio = home_wins/(home_wins + home_loss)
away_ratio = away_wins/(away_wins + away_loss)
except:
home_ratio = -1
away_ratio = -1
print("%4s, %20s -- %5i, %5i -- %5i, %5i, %.3f, %5i, %5i, %.3f, \t %.3f" % (clubId, club.Name, home_games, away_games,
home_wins, home_loss, home_ratio,
away_wins, away_loss, away_ratio, home_ratio - away_ratio))
De volledige resultaten staan hieronder. De laatste kolom geeft het thuisvoordeel aan:
Full results:
A003, Salamander -- 1602, 1587 -- 14166, 11005, 0.563, 12523, 12440, 0.502, 0.061
A008, Brasgata -- 1478, 1458 -- 11294, 11959, 0.486, 10144, 12836, 0.441, 0.044
A062, AFP Antwerpen -- 2082, 2070 -- 16127, 15710, 0.507, 14521, 17122, 0.459, 0.048
A074, Hove -- 660, 664 -- 5976, 4522, 0.569, 5454, 5108, 0.516, 0.053
A075, Rupel -- 767, 762 -- 6780, 5491, 0.553, 6121, 6071, 0.502, 0.050
A095, Turnhout -- 740, 716 -- 6239, 5350, 0.538, 5506, 5699, 0.491, 0.047
A097, Nijlen -- 760, 762 -- 5381, 6704, 0.445, 5175, 6956, 0.427, 0.019
A105, Dessel -- 150, 152 -- 1084, 1217, 0.471, 1010, 1322, 0.433, 0.038
A115, Dylan Berlaar -- 1589, 1566 -- 12441, 11110, 0.528, 11000, 12213, 0.474, 0.054
A117, Geelse -- 1473, 1491 -- 12544, 10559, 0.543, 11367, 12036, 0.486, 0.057
A118, Rijkevorsel -- 391, 393 -- 3608, 2648, 0.577, 3108, 3180, 0.494, 0.082
A123, Virtus -- 478, 471 -- 3660, 3597, 0.504, 3150, 4006, 0.440, 0.064
A127, Retie -- 667, 662 -- 5641, 4987, 0.531, 5070, 5476, 0.481, 0.050
A129, Borsbeek -- 589, 580 -- 4814, 4609, 0.511, 4276, 5001, 0.461, 0.050
A130, Schoten -- 1282, 1274 -- 10391, 10120, 0.507, 9411, 10972, 0.462, 0.045
A135, Minderhout -- 667, 662 -- 5754, 4890, 0.541, 5147, 5418, 0.487, 0.053
A136, Zoersel -- 955, 951 -- 8436, 6485, 0.565, 7446, 7401, 0.502, 0.064
A138, Blue Rackets -- 540, 543 -- 4201, 4347, 0.491, 3873, 4725, 0.450, 0.041
A139, Hallaar -- 840, 851 -- 6883, 6457, 0.516, 6228, 7296, 0.461, 0.055
A141, Merksplas -- 460, 461 -- 4167, 2663, 0.610, 3917, 2952, 0.570, 0.040
A142, Tecemo -- 687, 673 -- 5844, 4913, 0.543, 5221, 5320, 0.495, 0.048
A147, Gierle -- 2094, 2034 -- 16930, 16306, 0.509, 14774, 17510, 0.458, 0.052
A155, Wommelgem -- 350, 354 -- 3056, 2543, 0.546, 2707, 2955, 0.478, 0.068
A159, Real -- 24, 21 -- 44, 76, 0.367, 53, 52, 0.505, -0.138
A160, Walem -- 421, 420 -- 3320, 3416, 0.493, 3022, 3697, 0.450, 0.043
A167, Lille -- 457, 448 -- 3642, 3643, 0.500, 3148, 4009, 0.440, 0.060
A176, Sokah -- 2077, 2082 -- 17004, 13898, 0.550, 15337, 15694, 0.494, 0.056
A182, Nodo -- 1936, 1921 -- 14876, 13391, 0.526, 13485, 14640, 0.479, 0.047
A186, Willebroek -- 484, 485 -- 4022, 3722, 0.519, 3390, 4370, 0.437, 0.083
A201, Hulshout -- 349, 354 -- 3016, 2538, 0.543, 2954, 2679, 0.524, 0.019
A211, Zwijndrecht -- 407, 407 -- 3801, 2645, 0.590, 3473, 2973, 0.539, 0.051
A212, Antonius -- 917, 920 -- 7923, 6221, 0.560, 7271, 6968, 0.511, 0.050
A216, Henricus -- 94, 95 -- 957, 547, 0.636, 858, 662, 0.564, 0.072
Merk op dat Real een nieuwe club is, waardoor zij nog maar weinig statistiek hebben en op een extreme waarde van -14 procentpunten uitkomen. In de visualisatie verderop negeren we hen. Andere kolommen waar we niet dieper op ingaan geven winstpercentages. We zien daar bijvoorbeeld hoe TTK Merkplas, die de laatste jaren in opmars is, met een percentage van 60 procent, bij de top hoort.
Wat sorteren en visualiseren:
home_advantage = [0.061,0.044,0.048,0.053,0.050,0.047,0.019,0.038,0.054,0.057,0.082,0.064,0.050,0.050,0.045,0.053,0.064,0.041,0.055,0.040,0.048,0.052,0.068,-0.138,0.043,0.060,0.056,0.047,0.083,0.019,0.051,0.050,0.072]
import numpy as np
names = np.array(names)
home_advantage = np.array(home_advantage)
inds = np.argsort(home_advantage)
%matplotlib notebook
import matplotlib.pyplot as plt
plt.figure(figsize=(6, 10))
plt.barh(np.arange(len(inds)-1), home_advantage[inds[1:]])
plt.barh([18], home_advantage[inds[18+1]], color='C1')
ax = plt.gca()
ax.set_yticks(np.arange(len(inds)-1))
ax.set_yticklabels(names[inds[1:]])
plt.title('Thuisvoordeel in procentpunten')
plt.tight_layout()
<IPython.core.display.Javascript object>
De cijfers tonen dus dat 5 procentpunten een typisch thuisvoordeel is, en dat TTK Minderhout geen uitzonderlijk thuisvoordeel heeft. De clubs met aan de extremen zijn overigens relatief kleine clubs met weinig officiele wedstrijden. Toevoeging van enige onzekerheidsbanden zou interessant zijn, maar is voor een andere keer. Mogelijks dat Salamander als grote club met een groot thuisvoordeel dat bovenaan komt, maar die zijn enkele jaren van zaal gewisseld, dus ook dat zou dan uitgespit moeten worden.
Om nog net een beetje dieper te graven, heb ik bekeken of we met TTK Minderhout dan wel een significant thuisvoordeel zouden hebben als we enkel de hogere provinciale reeksen in beschouwing nemen. Misschien dat een bepaald speelniveau nodig is om een thuisvoordeel maximaal uit te buiten? De details heb ik uit de post gelaten, maar de conclusie van een analyse beperkt tot 1e, 2e en 3e provinciale was hetzelfde: Geen significant thuisvoordeel. Omdat data waarover we statistiek doen kleiner wordt, zien we wel dat de extremen groter worden, met Dylan Berlaar die tot 10 procentpunten thuisvoordeel in die reeksen behaalt.
In al de seizoenen dat ik bij Minderhout competitie heb gespeeld, heb ik er veel als kopman gefungeerd, waarbij ik in een lagere reeks speelde dan ik misschien zou aankunnen en hoge percentages (met regelmatige individuele leidersplaatsen in mijn reeks). Als dat geen clubliefde is!
Bovendien speel ik de meeste seizoenen bijna alle wedstrijden. Ik had dus het vermoeden dat er niet veel spelers in Vlaanderen meer individuele overwinningen in de enkelcompetitie zouden hebben dan ik. Met de TabT API werkend, de uitgelezen kans om dit eens te checken!
De GetMembers API ziet er als volgt uit:
Array
(
[Credentials] => Credentials Object
(
[Account] =>
[Password] =>
)
[Club] => A135
[Season] => 21
[PlayerCategory] =>
[UniqueIndex] =>
[NameSearch] =>
[ExtendedInformation] => 0
[RankingPointsInformation] =>
)
Deze staat toe om individuele spelers op te vragen, inclusief al hun individuele resultaten.
Eerst vullen we een dictionary met alle spelers bij een club
clubInds = []
for club in clubs.ClubEntries:
#if 'A' in club.UniqueIndex:
clubInds.append(club.UniqueIndex)
club_to_members = {}
for club in clubInds:
try:
club_to_members[club] = client.service.GetMembers(credentials, club, 20, None, None, None, 0, None)
except:
continue
Vervolgens vullen we een dictionary voor elke speler met al zijn individuele resultaten over alle beschikbare seizoenen. Spelers hebben een unieke lidnummer. Vanuit mijn jaren als kapitein zijn toen wedstrijdladen nog op papier ingevuld moesten worden, ken ik die nog vanbuiten: 502575
member_to_results = {}
for club in club_to_members:
#members = club_to_members[club]
print(club)
for season in range(7, 21):
success = False
tries = 0
members = None
while (not success) and (tries < 5):
try:
tries += 1
members = client.service.GetMembers(credentials, club, season, None, None, None, 0, None, True)
success = True
except Exception as e:
if not e.message.startswith('Quota'):
print(e.message)
members = None
success = True
else:
time.sleep(30.)
if tries >= 5:
print('Exceeded # of tries')
if not members:
continue
assert out.MemberCount <= 1
if out.MemberCount == 0:
continue
for member in members.MemberEntries:
index = member.UniqueIndex
if not index in member_to_results:
member_to_results[index] = [0, 0] # Wins, losses
results = member.ResultEntries
for result in results:
if not result.CompetitionType == 'C':
continue
assert result.Result in 'VD'
if result.Result == 'V':
member_to_results[index][0] += 1
if result.Result == 'D':
member_to_results[index][1] += 1
Deze keer presenteren we het wat mooier in een pandas
tabel
import pandas as pd
import copy
member_to_results2 = copy.deepcopy(member_to_results)
for club in club_to_members:
members = club_to_members[club].MemberEntries
for member in members:
index = member.UniqueIndex
if not index in member_to_results2:
continue
if len(member_to_results2[index]) == 2:
member_to_results2[index].append(member.FirstName)
member_to_results2[index].append(member.LastName)
df = pd.DataFrame.from_dict(member_to_results2, orient='index', columns=['W', 'L', 'FirstName', 'LastName'])
df.sort_values('W', ascending=False)
W | L | FirstName | LastName | |
---|---|---|---|---|
500376 | 1039 | 731 | JACQUES | INGELBRECHT |
502575 | 947 | 199 | LENSE | SWAENEN |
506488 | 944 | 291 | MICHEL | MENTENS |
503221 | 914 | 128 | ROB | WUYTS |
506188 | 879 | 348 | JAN | LEBBE |
505690 | 856 | 607 | ANDRE | AUDEZ |
506952 | 832 | 352 | TOMMY | VOET |
100577 | 829 | 334 | FRANCOIS | GOBEAUX |
509041 | 828 | 358 | JORNE | BICKX |
510800 | 824 | 204 | JOHAN | CARNA |
72832 rows × 4 columns
Aanvoerder van bovenstaande lijst is Jacques Ingelbrecht, 70-jarige speler bij het West-Vlaamse Zandvoorde. Hij voert bovenstaande lijst aan met 1039 overwinningen op meer dan 1700 wedstrijden. De reden dat Jacques zoveel wedstrijden op zijn teller heeft, is omdat hij als veteraan ook al jaren meedraait in de West-Vlaamse veteranen competitie, zodat hij wekelijks, naast 4 wedstrijden seniorencompetitie ook nog eens 3 wedstrijden veteranencompetitie speelt. Deze had ik er niet uitgefilterd…
Als we die wedstrijden negeren (en toegegeven, zonder veteranen-, toernooi- en jeugdwedstrijden wordt het een beetje cherrypicking :)), dan voer ik weldegelijk de Vlaamse lijst aan van spelers met de meeste individuele overwinningen in seniorencompetitie! Joepie!
Verder nog een shout-out naar collega Antwerpenaren Rob Wuyts en Jan Lebbe die mee de top aanvullen. Tegen Rob en Jan heb ik de voorbije jaren al vele wedstrijden op het scherpst van de snee gespeeld en beide hebben duidelijk een even groot hart voor hun kleine club getoond (Hulshout en Hove respectievelijk).
Tot slot de observatie dat mijn teller van overwinningen de 1000 aan het naderen is! Dat had ik eerder nog niet op mijn radar, maar dit geeft me dus nog ongeveer 1 volledig seizoen de tijd om een gepaste viering voor die mijlpaal te plannen!
Nog enkele ideeen voor toekomstige analyses en blogposts die ik alvast even neerpen hier:
Als enige lezers nog suggesties hebben voor analyses, ben ik zeer geinteresseerd. Hopelijk dat de beschikbaarheid van de code in deze post ook andere in staat kan stellen om zelf wat interessants uit die grote hoeveelheid data op te graven.
None yet
Very interested in your comments but still figuring out the most suited approach to this. For now, feel free to send me an email.