De International Statistical Classification of Diseases and Related Health Problems1 (ICD) is een lijst van de Wereldgezondheidsorganisatie2 (WHO) met beschrijvingen van meer dan 10.000 kwalen en aandoeningen waaraan patiënten kunnen leiden. Naast een beschrijving krijgen de kwalen en aandoeningen ook een unieke ICD-code die binnen de medische wereld gebruikt wordt voor archiveringsdoeleinden. Zo wordt een patiënt bijvoorbeeld geregistreerd met ICD-code A37 als hij met kinkhoest wordt opgenomen in het ziekenhuis.
Enkele van de vreemdste klachten die we op de lijst aantroffen:
ICD-code | beschrijving (Engels) | vertaling (Nederlands) |
---|---|---|
A82.1 | Urban rabies | Stadsrabies3 |
A92.1 | O'nyong-nyong fever | O'nyong-nyong-koorts4 |
K08.10 | Complete loss of teeth, unspecified cause | Verlies van alle tanden, oorzaak niet nader gespecificeerd |
M26.0 | Major anomalies of jaw size | Grote afwijkingen van kaakgrootte |
N36.42 | Intrinsic sphincter deficiency (ISD) | Intrinsieke sfincterdeficiëntie5 (ISD) |
Q71.63 | Lobster-claw hand, bilateral | Kreeftenschaarhand6, bilateraal |
T40.5X6 | Underdosing of cocaine | Onderdosering van cocaïne |
V96.15 | Hang glider explosion injuring occupant | Explosie van deltavlieger met gewond raken van inzittende |
W17.0 | Fall into well | Val in waterput |
W61.43 | Pecked by turkey | Door kalkoen gepikt |
X15.1 | Contact with hot toaster | Contact met hete broodrooster |
X52 | Prolonged stay in weightless environment | Langdurig verblijf in gewichtloze omgeving |
Maar tot nu toe is onze favoriete aandoening toch wel Burn due to water-skis on fire (verbranden door ontvlamde waterski's; V91.07). Het is een gevaarlijke wereld daarbuiten. Hou het dus veilig.
De code van Hippocrates is een geheimschrift dat gebruikmaakt van ICD-codes. Een tekst wordt gecodeerd door elk karakter te vervangen door een Hippocrates-code van de vorm
<ICD-code>.$$n$$ ($$n \in \mathbb{N}$$)
De Hippocrates-code wordt zo gekozen dat de $$n$$-de positie in de beschrijving van de ICD-code ingenomen wordt door het gecodeerde karakter. De positie van de karakters wordt hierbij genummerd vanaf nul. In het gecodeerde bericht worden opeenvolgende Hippocrates-codes telkens van elkaar gescheiden door één enkele spatie. Op die manier wordt de zin
Eat wise, drop a size
gecodeerd als
A75.0.0 K50.119.59 T43.2.75 V14.1.21 V42.1.54 E10.32.53 T21.70.5 T21.06.12 S59.239.62 M85.812.56 M85.812.34 Q95.3.27 V64.0.22 T37.3.61 S00.261.34 T49.4X6.76 F44.6.32 A02.24.23 V59.9.62 J10.89.41 O91.1.13
We zien bijvoorbeeld dat de eerste letter (positie 0) in de beschrijving van ICD-code A75.0 (Epidemic louse-borne typhus fever due to Rickettsia prowazekii) ingenomen wordt door de hoofdletter E en dat er een kleine letter a staat op positie 59 in de beschrijving van ICD-code K50.119 (Crohn's disease of large intestine with unspecified complications). Bij het coderen worden hoofdletters en kleine letters als verschillende karakters aanzien, en worden ook de spaties en leestekens vervangen door een corresponderende Hippocrates-code.
De codering is echter niet uniek omdat een karakter op verschillende posities en in verschillende beschrijvingen kan voorkomen. Daardoor had dezelfde zin bijvoorbeeld ook kunnen gecodeerd worden als
W92.XXXD.0 I97.611.84 I97.611.38 S59.099.31 M90.832.38 V42.1.93 M61.25.29 I67.83.43 T37.92.67 W93.38 O22.23 V59.9.48 F04.23 C34.2.13 F44.6.43 A00.0.28 M85.812.5 A02.24.23 Z96.621.21 J10.89.41 N07.9.31
Voor het coderen en decoderen van berichten volgens de code van Hippocrates werken we met tekstbestanden waarvan elke regel een ICD-code en een bijhorende beschrijving bevat, van elkaar gescheiden door een spatie. Dit zijn de ICD-codes die bij het coderen en decoderen moeten gebruikt worden. Een ICD-code bevat nooit spaties (punten zijn wel toegelaten). Gevraagd wordt:
Schrijf een functie code2karakter waaraan de locatie (str) van een tekstbestand met ICD-codes moet doorgegeven worden. De functie moet een dictionary (dict) teruggeven die alle mogelijke Hippocrates-codes (str) voor het gegeven tekstbestand afbeeldt op hun corresponderend karakter (str).
Schrijf een functie decodeer waaraan twee argumenten moeten doorgegeven worden: i) een gecodeerde tekst (str) waarbij het coderen gebeurde volgens de code van Hippocrates en ii) een dictionary (dict) zoals die wordt teruggegeven door de functie code2karakter. De functie moet de originele tekst (str) teruggeven. Als het eerste argument geen geldige codering voorstelt volgens de gegeven code van Hippocrates (tweede argument), dan moet een ValueError opgeworpen worden met de boodschap ongeldige gecodeerde tekst.
Schrijf een functie karakter2codes waaraan de locatie (str) van een tekstbestand met ICD-codes moet doorgegeven worden. De functie moet een dictionary (dict) teruggeven die elk karakter (str) dat voorkomt in minstens één beschrijving uit het gegeven tekstbestand afbeeldt op een verzameling (set) van alle Hippocrates-codes (str) waardoor het gegeven karakter kan vervangen worden in het geheimschrift.
Schrijf een functie codeer waaraan twee argumenten moeten doorgegeven worden: i) een tekst (str) en ii) een dictionary (dict) zoals die wordt teruggegeven door de functie karakter2codes. De functie moet een gecodeerde versie van de gegeven tekst (str) teruggeven, waarbij het coderen gebeurt volgens de code van Hippocrates. Daarbij moet elk karakter van de gegeven tekst vervangen worden door willekeurig te kiezen uit alle mogelijke Hippocrates-codes die het karakter coderen. Als de gegeven tekst karakters bevat die door geen enkele Hippocrates-code gecodeerd worden, dan moet een ValueError opgeworpen worden met de boodschap ongeldige platte tekst.
In onderstaande voorbeeldsessie gaan we ervan uit dat het tekstbestand ICD.txt7 zich in de huidige directory bevindt.
>>> c2k = code2karakter('ICD.txt8')
>>> c2k['A00.0']
'C'
>>> c2k['A00.2']
'o'
>>> c2k['A00.0.33']
','
>>> c2k['A00.2.33']
Traceback (most recent call last):
KeyError: 'A00.2.33'
>>> decodeer('A75.0.0 K50.119.59 T43.2.75 V14.1.21 V42.1.54 E10.32.53 T21.70.5 T21.06.12 S59.239.62 M85.812.56 M85.812.34 Q95.3.27 V64.0.22 T37.3.61 S00.261.34 T49.4X6.76 F44.6.32 A02.24.23 V59.9.62 J10.89.41 O91.1.13', c2k)
'Eat wise, drop a size'
>>> decodeer('W92.XXXD.0 I97.611.84 I97.611.38 S59.099.31 M90.832.38 V42.1.93 M61.25.29 I67.83.43 T37.92.67 W93.38 O22.23 V59.9.48 F04.23 C34.2.13 F44.6.43 A00.0.28 M85.812.5 A02.24.23 Z96.621.21 J10.89.41 N07.9.31', c2k)
'Eat wise, drop a size'
>>> decodeer('X66.6 Q99.99 Z12.34', c2k)
Traceback (most recent call last):
ValueError: ongeldige gecodeerde tekst
>>> k2c = karakter2codes('ICD.txt9')
>>> k2c['V']
{'O22.0', 'A00.1.15', 'I83.218.0', 'A00.0.15'}
>>> k2c['v']
{'I67.83.12', 'V59.9.50', 'V64.0.76', 'H59.121.12', 'M50.022.3', 'S44.8X9.19', 'T37.92.46', 'S44.8X9.51', 'V42.1.68', 'S66.911.68', 'T37.3.16', 'T37.1X.16', 'V04.92.67', 'M67.971.28', 'B08.04.4', 'Q95.3.53', 'V49.60.69', 'V64.0.3', 'T43.2.16', 'V64.0.26', 'E10.32.49', 'B57.30.40', 'A00.0.38', 'V64.0.13', 'I89.9.10', 'I83.218.9', 'V04.92.54', 'F44.6.3', 'I89.9.35', 'W24.0.23', 'M67.232.4', 'B57.30.43', 'S90.464.16', 'N13.9', 'V52.1.88', 'S14.9.25', 'V52.1.30', 'S78.922.54', 'V92.16.45', 'V14.1.51', 'S00.261.16', 'B57.30.28', 'V59.9.13', 'W93.19', 'W92.XXXD.19', 'V64.0.63', 'M50.022.34', 'J10.89.44', 'A00.1.38', 'A75.0.30', 'V14.1.64', 'T37.1X5.2'}
>>> k2c['.']
{'Z68.35.29', 'Z68.35.24', 'Z68.42.29', 'Z68.36.29', 'Z68.42.24', 'Z68.36.24', 'Z68.43.27'}
>>> k2c['xxx']
Traceback (most recent call last):
KeyError: 'xxx'
>>> k2c['!']
Traceback (most recent call last):
KeyError: '!'
>>> codeer('Eat wise, drop a size', k2c)
'A75.0.0 K50.119.59 T43.2.75 V14.1.21 V42.1.54 E10.32.53 T21.70.5 T21.06.12 S59.239.62 M85.812.56 M85.812.34 Q95.3.27 V64.0.22 T37.3.61 S00.261.34 T49.4X6.76 F44.6.32 A02.24.23 V59.9.62 J10.89.41 O91.1.13'
>>> codeer('Eat wise, drop a size', k2c)
'W92.XXXD.0 I97.611.84 I97.611.38 S59.099.31 M90.832.38 V42.1.93 M61.25.29 I67.83.43 T37.92.67 W93.38 O22.23 V59.9.48 F04.23 C34.2.13 F44.6.43 A00.0.28 M85.812.5 A02.24.23 Z96.621.21 J10.89.41 N07.9.31'
>>> codeer('Eat wise, drop a size!', k2c)
Traceback (most recent call last):
ValueError: ongeldige platte tekst
Elk jaar publiceert de Amerikaanse overheidsorganisatie Occupational Safety and Health Administration10 (OHSA) een lijst van arbeidsongevallen met dodelijke afloop11, waarbij er telkens een korte beschrijving van elk ongeval gegeven wordt. Op deze manieren wil je liever niet aan je einde komen:
Werknemer stierf toen zijn postwagen gedeeltelijk in een meer werd ondergedompeld.
Werknemer zat klem tussen de roterende trommel en de laadtrechter van een zelfrijdende betonmolen.
Werknemer werd fataal verzwolgen door droog cement toen een stalen opslagsilo instortte.
Werknemer werd op ladder geslagen en gedood door bliksem.
Werknemer werd in een boomversnipperaar getrokken.
Werknemer werd verpletterd tussen twee vrachtwagens.
Hoofd van werknemer werd gespietst door metaal uit het aandrijfgedeelte van een reuzenrad. De werknemer struikelde nadat hij teken gegeven had klaar te zijn en het rad begon te draaien, waardoor zijn hoofd vastraakte.
Werknemer was een tank aan het draineren. Een collega klom naar de bovenkant van de tank, stak een sigaret op en zwaaide door de opening van de tank. De tank explodeerde, waardoor de arbeider stierf.
Werknemer werd vertrappeld door een olifant.
Agent in dienst van een sherrif was tijdens een moordonderzoek door een bos aan het wandelen, en viel in een zinkgat van 161 voet diep.
Het is lastig om er de slechtst mogelijke manier om te sterven uit te kiezen, maar we doen een poging.
Werknemer bediende een schranklader dichtbij een put met buitenmest tijdens het opruimen van een melkveestal. De schranklader en de werknemer vielen over de rand van het afzetplatform in de mestput, waarbij de werknemer in het voertuig opgesloten raakte. Werknemer verstikte door het inademen van de mest.