1
+ """
2
+ Write a function which checks the red blood cell compatibility between donor and recipient.
3
+ https://en.wikipedia.org/wiki/Blood_type#Red_blood_cell_compatibility
4
+ For simplicity, the appearance of 8 basic types of blood is considered.
5
+ The input of blood type can be in the form of:
6
+ pre defined Bloodtype enum e.g.: Bloodtype.ZERO_NEG
7
+ value of the pre-defined Bloodtype 0..7
8
+ pre defined text e.g. "0-", "B+", "AB+", ...
9
+ If input value is not a required type TypeError is raised.
10
+ If input value is not in defined interval ValueError is raised.
11
+ Keywords: enum, exception handling, multi type input
12
+ """
13
+
14
+ from enum import Enum
15
+
16
+
17
+ class Bloodtype (Enum ):
18
+ ZERO_NEG = 0
19
+ ZERO_POS = 1
20
+ B_NEG = 2
21
+ B_POS = 3
22
+ A_NEG = 4
23
+ A_POS = 5
24
+ AB_NEG = 6
25
+ AB_POS = 7
26
+
27
+
28
+ blood_type_text = {
29
+ "0-" : Bloodtype .ZERO_NEG ,
30
+ "0+" : Bloodtype .ZERO_POS ,
31
+ "B-" : Bloodtype .B_NEG ,
32
+ "B+" : Bloodtype .B_POS ,
33
+ "A-" : Bloodtype .A_NEG ,
34
+ "A+" : Bloodtype .A_POS ,
35
+ "AB-" : Bloodtype .AB_NEG ,
36
+ "AB+" : Bloodtype .AB_POS ,
37
+ }
38
+
39
+ # print(Bloodtype.A_NEG.value)
40
+ # complete :
41
+
42
+ # print(type(Bloodtype.AB_POS.value))
43
+
44
+
45
+ def check_bt (donor , recipient ):
46
+ """ Checks red blood cell compatibility based on 8 blood types
47
+ Args:
48
+ donor (int | str | Bloodtype): red blood cell type of the donor
49
+ recipient (int | str | Bloodtype): red blood cell type of the recipient
50
+ Returns:
51
+ bool: True for compatability, False otherwise.
52
+ """
53
+
54
+ if type (donor ) is int and type (recipient ) is int :
55
+ if donor not in [0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] or recipient not in [0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ]:
56
+ raise ValueError
57
+ elif donor == Bloodtype .ZERO_NEG .value :
58
+ return True
59
+ elif donor == Bloodtype .ZERO_POS .value and recipient in [Bloodtype .AB_POS .value , Bloodtype .A_POS .value , Bloodtype .B_POS .value , Bloodtype .ZERO_POS .value ]:
60
+ return True
61
+ elif donor == Bloodtype .B_NEG .value and recipient in [Bloodtype .AB_POS .value , Bloodtype .AB_NEG .value , Bloodtype .B_POS .value , Bloodtype .B_NEG .value ]:
62
+ return True
63
+ elif donor == Bloodtype .B_POS .value and recipient in [Bloodtype .AB_POS .value , Bloodtype .B_POS .value ]:
64
+ return True
65
+ elif donor == Bloodtype .A_NEG .value and recipient in [Bloodtype .AB_POS .value , Bloodtype .AB_NEG .value , Bloodtype .A_POS .value , Bloodtype .A_NEG .value ]:
66
+ return True
67
+ elif donor == Bloodtype .A_POS .value and recipient in [Bloodtype .AB_POS .value , Bloodtype .A_POS .value ]:
68
+ return True
69
+ elif donor == Bloodtype .AB_NEG .value and recipient in [Bloodtype .AB_POS .value , Bloodtype .AB_NEG .value ]:
70
+ return True
71
+ elif donor == Bloodtype .AB_POS .value and recipient == Bloodtype .AB_POS .value :
72
+ return True
73
+ else :
74
+ return False
75
+ elif type (donor ) is str and type (recipient ) is str :
76
+ if donor not in blood_type_text .keys () or recipient not in blood_type_text .keys ():
77
+ raise ValueError
78
+ elif donor == "0-" :
79
+ return True
80
+ elif donor == "0+" and recipient in ["AB+" , "A+" , "B+" , "0+" ]:
81
+ return True
82
+ elif donor == "B-" and recipient in ["AB+" , "AB-" , "B+" , "B-" ]:
83
+ return True
84
+ elif donor == "B+" and recipient in ["AB+" , "B+" ]:
85
+ return True
86
+ elif donor == "A-" and recipient in ["AB+" , "AB-" , "A+" , "A-" ]:
87
+ return True
88
+ elif donor == "A+" and recipient in ["AB+" , "A+" ]:
89
+ return True
90
+ elif donor == "AB-" and recipient in ["AB+" , "AB-" ]:
91
+ return True
92
+ elif donor == "AB+" and recipient == "AB+" :
93
+ return True
94
+ else :
95
+ return False
96
+ elif type (donor ) is Bloodtype and type (recipient ) is Bloodtype :
97
+ if donor not in blood_type_text .values () or recipient not in blood_type_text .values ():
98
+ raise ValueError
99
+ elif donor == blood_type_text .get ("0-" ):
100
+ return True
101
+ elif donor == blood_type_text .get ("0+" ) and recipient in [blood_type_text .get ("AB+" ), blood_type_text .get ("A+" ),
102
+ blood_type_text .get ("B+" ), blood_type_text .get ("O+" )]:
103
+ return True
104
+ elif donor == blood_type_text .get ("B-" ) and recipient in [blood_type_text .get ("AB+" ),
105
+ blood_type_text .get ("AB-" ),
106
+ blood_type_text .get ("B+" ),
107
+ blood_type_text .get ("B-" )]:
108
+ return True
109
+ elif donor == blood_type_text .get ("B+" ) and recipient in [blood_type_text .get ("AB+" ),
110
+ blood_type_text .get ("B+" )]:
111
+ return True
112
+ elif donor == blood_type_text .get ("A-" ) and recipient in [blood_type_text .get ("AB+" ),
113
+ blood_type_text .get ("AB-" ),
114
+ blood_type_text .get ("A+" ),
115
+ blood_type_text .get ("A-" )]:
116
+ return True
117
+ elif donor == blood_type_text .get ("A+" ) and recipient in [blood_type_text .get ("AB+" ),
118
+ blood_type_text .get ("A+" )]:
119
+ return True
120
+ elif donor == blood_type_text .get ("AB-" ) and recipient in [blood_type_text .get ("AB+" ),
121
+ blood_type_text .get ("AB-" )]:
122
+ return True
123
+ elif donor == blood_type_text .get ("AB+" ) and recipient == blood_type_text .get ("AB+" ):
124
+ return True
125
+ else :
126
+ return False
127
+ else :
128
+ raise TypeError
129
+
130
+ # print(check_bt(7, 1))
131
+ # hint
132
+
133
+
134
+ def _particular_antigen_comp (donor : int , recipient : int ) -> tuple :
135
+ """Returns a particalar antigen compatibility, where each tuple member
136
+ marks a compatibility for a particular antigen (A, B, Rh-D).
137
+ If tuple member is non-negative there is a compatibility.
138
+ For red blood cell compatibility is required that
139
+ all tuple members are non-negative (i.e. compatibility for all 3 antigens).
140
+ 0- bloodtype is represented as 0 ; AB+ is represented as 7; see Bloodtype enum
141
+ Examples:
142
+ _particular_antigen_comp(0, 7) -> (1, 1, 1) 0- can donate to AB+
143
+ _particular_antigen_comp(1, 3) -> (0, 1, 0) 0+ can donate to B+
144
+ _particular_antigen_comp(2, 5) -> (1, -1, 1) B+ cannot donate to A+
145
+ _particular_antigen_comp(7, 0) -> (-1, -1, -1) AB+ cannot donate to 0-
146
+ """
147
+ return (
148
+ ((recipient // 4 ) % 2 ) - ((donor // 4 ) % 2 ),
149
+ ((recipient // 2 ) % 2 ) - ((donor // 2 ) % 2 ),
150
+ (recipient % 2 ) - (donor % 2 ),
151
+ )
0 commit comments