|
| 1 | +from typing import List, Union, Dict, Any |
| 2 | +from dataclasses import dataclass, asdict |
| 3 | + |
| 4 | + |
| 5 | +@dataclass |
| 6 | +class Contact: |
| 7 | + name: str |
| 8 | + email: str |
| 9 | + phone: str |
| 10 | + gender: str |
| 11 | + age: int |
| 12 | + |
| 13 | + |
| 14 | +class Agenda: |
| 15 | + def __init__(self, contacts: Union[List, None] = None): |
| 16 | + self.contacts = [] |
| 17 | + if contacts: |
| 18 | + for contact in contacts: |
| 19 | + self.register(contact) |
| 20 | + |
| 21 | + def register(self, contact): |
| 22 | + self.contacts.append(contact) |
| 23 | + |
| 24 | + def query(self, search_param_dict: Dict[str, Any], get_param=None): |
| 25 | + if type(search_param_dict) == dict: |
| 26 | + results = [] |
| 27 | + |
| 28 | + for contact in self.contacts: |
| 29 | + |
| 30 | + flag = True |
| 31 | + for k, v in search_param_dict.items(): |
| 32 | + if hasattr(contact, k): |
| 33 | + attr_ = getattr(contact, k) |
| 34 | + if callable(v): |
| 35 | + if v(attr_) is False: |
| 36 | + flag = False |
| 37 | + elif attr_ != v: |
| 38 | + flag = False |
| 39 | + if flag: |
| 40 | + if get_param is None: |
| 41 | + results.append(contact) |
| 42 | + elif get_param == 'all': |
| 43 | + results.append(asdict(contact)) |
| 44 | + elif type(get_param) == list: |
| 45 | + res = [] |
| 46 | + for key in get_param: |
| 47 | + if hasattr(contact, key): |
| 48 | + res.append(getattr(contact, key)) |
| 49 | + results.append(res) |
| 50 | + elif type(get_param) == str: |
| 51 | + results.append(getattr(contact, get_param)) |
| 52 | + return results |
| 53 | + else: |
| 54 | + print("Invalid query") |
| 55 | + return None |
| 56 | + |
| 57 | + def consult(self, contact_param: Union[int, str, List]): |
| 58 | + if type(contact_param) != list: |
| 59 | + contact_param = [contact_param] |
| 60 | + |
| 61 | + results = [] |
| 62 | + for contact in self.contacts: |
| 63 | + name = contact.name |
| 64 | + email = contact.email |
| 65 | + phone = contact.phone |
| 66 | + gender = contact.gender |
| 67 | + age = contact.age |
| 68 | + |
| 69 | + if (set(contact_param) - {name, email, phone, gender, age}) == set(): |
| 70 | + results.append(contact) |
| 71 | + return results |
| 72 | + |
| 73 | + def edit_contact(self, contact: 'Contact', new_param_values: Dict): |
| 74 | + if not isinstance(contact, Contact): |
| 75 | + print("Not a valid contact") |
| 76 | + return -1 |
| 77 | + else: |
| 78 | + if contact in self.contacts: |
| 79 | + pass |
| 80 | + else: |
| 81 | + print("Required contact is not added in the phone-book") |
| 82 | + return -1 |
| 83 | + |
| 84 | + for k, v in new_param_values.items(): |
| 85 | + if hasattr(contact, k): |
| 86 | + setattr(contact, k, type(getattr(contact, k))(v)) |
| 87 | + return 1 |
| 88 | + |
| 89 | + def delete(self, contact: 'Contact'): |
| 90 | + if not isinstance(contact, Contact): |
| 91 | + print("Not a valid contact") |
| 92 | + return -1 |
| 93 | + else: |
| 94 | + if contact in self.contacts: |
| 95 | + self.contacts.remove(contact) |
| 96 | + return 1 # success code |
| 97 | + else: |
| 98 | + print("Required contact is not added in the phone-book") |
| 99 | + return -1 |
| 100 | + |
| 101 | + def count_contacts(self) -> int: |
| 102 | + return len(self.contacts) |
| 103 | + |
| 104 | + def average_contacts_age(self) -> float: |
| 105 | + if len(self.contacts) > 0: # check to avoid ZeroDivisionError |
| 106 | + return sum({i.age for i in self.contacts}) / len(self.contacts) |
| 107 | + else: |
| 108 | + return -1 |
| 109 | + |
| 110 | + |
| 111 | +def show_menu(): |
| 112 | + display_string = '''\n |
| 113 | + :::MENU::: |
| 114 | + 1.Register a new contact; |
| 115 | + 2.Consult a specific contact; |
| 116 | + 3.Change the data of any contact; |
| 117 | + 4.Delete a particular contact; |
| 118 | + 5.Find out how many people were registered; |
| 119 | + 6.Find out the average age of people; |
| 120 | + 7.Print a list with the women who are registered on the agenda; |
| 121 | + 8.Print a list with the men who are registered in the agenda; |
| 122 | + 9.Print a list of people over a certain age; |
| 123 | + 10.Print a list of registered emails; |
| 124 | + 0. QUIT |
| 125 | +Enter your choice:''' |
| 126 | + print(display_string, end="") |
| 127 | + |
| 128 | + |
| 129 | +def register_contact(agenda: 'Agenda'): |
| 130 | + print("Enter contact details:") |
| 131 | + name = input(" name:") |
| 132 | + email = input(" email:") |
| 133 | + mobile = input(" mobile:") |
| 134 | + gender = input(" gender(M/W):").upper() |
| 135 | + age = int(input(" age:")) |
| 136 | + |
| 137 | + c_temp = Contact(name, email, mobile, gender, age) |
| 138 | + agenda.register(c_temp) |
| 139 | + |
| 140 | + |
| 141 | +def accept_choice(): |
| 142 | + show_menu() |
| 143 | + try: |
| 144 | + choice = int(input()) |
| 145 | + return choice |
| 146 | + except ValueError: |
| 147 | + print("Invalid choice, try again") |
| 148 | + return accept_choice() |
| 149 | + |
| 150 | + |
| 151 | +def consult_contact(agenda: 'Agenda'): |
| 152 | + contact_search_param = input("Enter contact name:") |
| 153 | + res = agenda.consult(contact_search_param) |
| 154 | + for item in res: |
| 155 | + print(asdict(item)) |
| 156 | + |
| 157 | + |
| 158 | +def edit_contact(agenda: 'Agenda'): |
| 159 | + name = input("Enter contact name:") |
| 160 | + contact_list = agenda.consult(name) |
| 161 | + contact = contact_list[0] |
| 162 | + |
| 163 | + field_name = input("Enter field to edit:") |
| 164 | + data = input("Enter data to replace with:") |
| 165 | + |
| 166 | + res = agenda.edit_contact(contact, {field_name: data}) |
| 167 | + if res == 1: |
| 168 | + print("Edit success!\n") |
| 169 | + else: |
| 170 | + print("Edit failed.\n") |
| 171 | + |
| 172 | + |
| 173 | +def delete_contact(agenda: 'Agenda'): |
| 174 | + name = input("Enter contact name:") |
| 175 | + contact_list = agenda.consult(name) |
| 176 | + if contact_list: |
| 177 | + contact = contact_list[0] |
| 178 | + else: |
| 179 | + print("No such contact found.") |
| 180 | + return -1 |
| 181 | + |
| 182 | + res = agenda.delete(contact) |
| 183 | + if res == 1: |
| 184 | + print("Deleted successfully!\n") |
| 185 | + elif res == -1: |
| 186 | + print("Deletion failed.\n") |
| 187 | + |
| 188 | + |
| 189 | +def process(): |
| 190 | + agenda = Agenda([p1, p2, p3, p4, p5]) |
| 191 | + while True: |
| 192 | + choice = accept_choice() |
| 193 | + print("".center(50, '='), '\n') |
| 194 | + |
| 195 | + if choice == 1: |
| 196 | + register_contact(agenda) |
| 197 | + elif choice == 2: |
| 198 | + consult_contact(agenda) |
| 199 | + elif choice == 3: |
| 200 | + edit_contact(agenda) |
| 201 | + elif choice == 4: |
| 202 | + delete_contact(agenda) |
| 203 | + elif choice == 5: |
| 204 | + n = agenda.count_contacts() |
| 205 | + print(f"{n} people registered.\n") |
| 206 | + elif choice == 6: |
| 207 | + avg_age = agenda.average_contacts_age() |
| 208 | + print(f"Average age of people: {avg_age}\n") |
| 209 | + elif choice == 7: |
| 210 | + res = agenda.query({'gender': 'W'}, get_param='name') |
| 211 | + print("Women who registered:") |
| 212 | + print("\n\t".join(res)) |
| 213 | + print() |
| 214 | + elif choice == 8: |
| 215 | + res = agenda.query({'gender': 'M'}, get_param='name') |
| 216 | + print("Men who registered:") |
| 217 | + print(' '+"\n ".join(res)) |
| 218 | + print() |
| 219 | + elif choice == 9: |
| 220 | + age_threshold = int(input("Age lower threshold:")) |
| 221 | + res = agenda.query(search_param_dict={'age': lambda x: x > age_threshold}, |
| 222 | + get_param='all') |
| 223 | + for item in res: |
| 224 | + print(item) |
| 225 | + elif choice == 10: |
| 226 | + res = agenda.query(search_param_dict={}, get_param='email') |
| 227 | + |
| 228 | + print("Registered emails:") |
| 229 | + for item in res: |
| 230 | + print(item) |
| 231 | + elif choice == 0: |
| 232 | + print("Exiting program.") |
| 233 | + break |
| 234 | + else: |
| 235 | + print("Wrong choice, try again") |
| 236 | + |
| 237 | + print("Thank you!".center(20, '-')) |
| 238 | + |
| 239 | + |
| 240 | +if __name__ == '__main__': |
| 241 | + p1 = Contact( "John", "[email protected]", "+60123334138", "M", 17) |
| 242 | + p2 = Contact( "Angel", "[email protected]", "+5433 214 229", "F", 23) |
| 243 | + p3 = Contact( "Danny", "[email protected]", "+065229 776", "M", 52) |
| 244 | + p4 = Contact( "Lisa", "[email protected]", "+02 7288 9944", "F", 32) |
| 245 | + p5 = Contact( "Jennifer", "[email protected]", "+606 528 2233", "F", 12) |
| 246 | + |
| 247 | + # agenda = Agenda([p1, p2, p3, p4, p5]) |
| 248 | + # min_age = int(input("age min:")) |
| 249 | + # res = agenda.query(search_param_dict={'age': lambda x: x >= min_age}, |
| 250 | + # get_param='all') |
| 251 | + # |
| 252 | + # for item in res: |
| 253 | + # print(item) |
| 254 | + process() |
0 commit comments