Als Equatoriaal-Guinea halverwege tussen Angola en Mauritius ligt, Noorwegen halverwege tussen El Salvador en Iran, Fiji halverwege tussen Spanje en Gabon, en Ierland halverwege tussen Zuid-Korea en Frans-Guyana, welk land ligt dan halverwege tussen Saudi-Arabië en de Verenigde Staten van Amerika?
Als je de "halverwege" op een wereldbol probeert te bepalen, dan zal je snel merken dat bovenstaande verbanden niet kloppen. In plaats daarvan gebruiken we de internationale standaard ISO 3166-11 die voor alle landen een unieke tweeletterige code (alpha-2), een unieke drieletterige code (alpha-3) en een unieke driecijferige code (numeric-3) vastlegt. Deze standaard wordt vastgelegd in het tekstbestand iso_3166-1.txt2:
Country;Alpha-2 code;Alpha-3 code;Numeric code;Latitude (average);Longitude (average) Afghanistan;AF;AFG;004;33;65 Albania;AL;ALB;008;41;20 Algeria;DZ;DZA;012;28;3 American Samoa;AS;ASM;016;-14.3333;-170 Andorra;AD;AND;020;42.5;1.6 Angola;AO;AGO;024;-12.5;18.5 Anguilla;AI;AIA;660;18.25;-63.1667 Antarctica;AQ;ATA;010;-90;0 Antigua and Barbuda;AG;ATG;028;17.05;-61.8 …
De eerste regel van het bestand is een hoofding. Elke andere regel beschrijft een land aan de hand van zes informatievelden die door puntkomma's (;) van elkaar gescheiden worden: i) unieke naam (Engels), ii) unieke tweeletterige code (alpha-2), iii) unieke drieletterige code (alpha-3), iv) unieke driecijferige code (numeric-3), v) (gemiddelde) breedtegraad en vi) (gemiddelde) lengtegraad. De informatievelden bevatten zelf geen puntkomma's.
Voor elk land gebruiken we de drieletterige code die bestaat uit drie hoofdletters. Om het middelpunt van twee codes te bepalen, leggen we eerst vast hoe we het middelpunt van twee letters bepalen. Daarvoor gebruiken we twee varianten. Het symmetrisch middelpunt van twee letters heeft een positie in het alfabet die precies in het midden ligt tussen de posities van de twee letters, ongeacht de volgorde van die twee posities. Zo is de letter J het symmetrisch middelpunt van de letters F en N die acht posities uit elkaar liggen, en het is ook het symmetrisch middelpunt van de letters N en F.
We kunnen de letters van het alfabet ook in wijzerzin rond een cirkel plaatsen, waarbij na de letter Z terug de letter A volgt. Nu moeten we opnieuw 8 stappen zetten om in wijzerzin van de letter F naar de letter N te gaan, waardoor de letter J het asymmetrisch middelpunt is van F en N, omdat die in wijzerzin $$\frac{8}{2} = 4$$ stappen verder ligt dan de letter F. Maar we hebben 18 stappen nodig om in wijzerzin van de letter N naar de letter F te gaan, waardoor de letter W het asymmetrisch middelpunt is van N en F, omdat die in wijzerzin $$\frac{18}{2} = 9$$ stappen verder ligt dan de letter N.
Een andere manier om het asymmetrisch middelpunt te bepalen is door het alfabet twee keer na elkaar te zetten. Daarin bepalen we de positie waar de eerste letter voor het eerst voorkomt, en daarna de positie waar de tweede voor het eerst voorkomt vanaf de positie van de eerste letter.
Het middelpunt van twee drieletterige codes is dan een string (str) van drie hoofdletters, waarvan de eerste letter het middelpunt is van de eerste letters van beide codes, de tweede letter het middelpunt van de tweede letters van beide codes en de derde letter het middelpunt van de derde letters van beide codes. Gevraagd wordt:
Schrijf een functie lees_standaard waaraan de locatie (str) moet doorgegeven worden van een tekstbestand dat een standaard vastlegt met unieke codes voor alle landen, in het formaat van het bestand iso_3166_1.txt3. De functie moet een dictionary (dict) teruggeven die de naam (str) van elk land uit het bestand afbeeldt op een tuple (tuple) met drie strings (str) met unieke codes voor het land: i) tweeletterige code (alpha-2), ii) drieletterige code (alpha-3), en iii) driecijferige code (numeric-3). We noemen dit de dictionary met landcodes voor de gegeven standaard.
Schrijf een functie omkeren waaraan een dictionary met landcodes $$\mathcal{C}$$ moet doorgegeven worden. De functie moet een nieuwe dictionary (dict) teruggeven die alle drieletterige codes (str; alpha-3) uit $$\mathcal{C}$$ afbeeldt op de naam (str) van het corresponderende land.
Schrijf een functie middelletter waaraan twee hoofdletters (str) moeten doorgegeven worden. Als het aantal stappen in het alfabet tussen deze twee letters oneven is, dan moet een AssertionError opgeworpen worden met de boodschap geen middelpunt. Anders moet de functie het middelpunt van de twee letters teruggeven. De functie heeft ook nog een optionele parameter asymmetrisch waaraan een Booleaanse waarde (bool; standaardwaarde: False) kan doorgegeven worden. De waarde van deze parameter bepaalt of het symmetrisch (False) of het asymmetrisch (True) middelpunt moet teruggeven worden.
Schrijf een functie middelcode waaraan twee drieletterige codes (str) moeten doorgegeven worden. Als het aantal stappen in het alfabet tussen twee corresponderende letters van deze codes oneven is, dan moet een AssertionError opgeworpen worden met de boodschap geen middelpunt. Anders moet de functie het middelpunt van de twee codes teruggeven. De functie heeft ook nog een optionele parameter asymmetrisch waaraan een Booleaanse waarde (bool; standaardwaarde: False) kan doorgegeven worden. De waarde van deze parameter bepaalt of het symmetrisch (False) of het asymmetrisch (True) middelpunt moet teruggeven worden.
Schrijf een functie halverwege waaraan drie argumenten moeten doorgegeven worden: de namen (str) van twee landen en een dictionary met landcodes $$\mathcal{C}$$. De functie moet de naam (str) van het land teruggeven waarvan de drieletterige code het middelpunt is van de drieletterige codes voor de twee gegeven landen, op basis van de landen en hun codes zoals vastgelegd in $$\mathcal{C}$$. Als dit land niet kan bepaald worden dan moet een AssertionError opgeworpen worden met de boodschap geen middelpunt. De functie heeft ook nog een optionele parameter asymmetrisch waaraan een Booleaanse waarde (bool; standaardwaarde: False) kan doorgegeven worden. De waarde van deze parameter bepaalt of het symmetrisch (False) of het asymmetrisch (True) middelpunt moet gebruikt worden.
In onderstaande voorbeeldsessie gaan we ervan uit dat het tekstbestand iso_3166_1.txt4 zich in de huidige directory bevindt.
>>> land2codes = lees_standaard('iso_3166_1.txt5')
>>> land2codes['Angola']
('AO', 'AGO', '024')
>>> land2codes['Mauritius']
('MU', 'MUS', '480')
>>> land2codes['Equatorial Guinea']
('GQ', 'GNQ', '226')
>>> code2land = omkeren(land2codes)
>>> code2land['AGO']
'Angola'
>>> code2land['MUS']
'Mauritius'
>>> code2land['GNQ']
'Equatorial Guinea'
>>> middelletter('F', 'N')
'J'
>>> middelletter('N', 'F')
'J'
>>> middelletter('F', 'N', asymmetrisch=True)
'J'
>>> middelletter('N', 'F', asymmetrisch=True)
'W'
>>> middelletter('A', 'D')
Traceback (most recent call last):
AssertionError: geen middelpunt
>>> middelcode('AGO', 'MUS')
'GNQ'
>>> middelcode('ISL', 'CYP')
'FVN'
>>> middelcode('ISL', 'CYP', asymmetrisch=True)
'SVN'
>>> middelcode('KHM', 'VNM')
Traceback (most recent call last):
AssertionError: geen middelpunt
>>> halverwege('Angola', 'Mauritius', land2codes)
'Equatorial Guinea'
>>> halverwege('Iceland', "Cyprus", land2codes)
Traceback (most recent call last):
AssertionError: geen middelpunt
>>> halverwege('Iceland', "Cyprus", land2codes, asymmetrisch=True)
'Slovenia'