Skip to content

Commit 7eb8249

Browse files
authored
Create Contact-Book.py
1 parent 35c467e commit 7eb8249

1 file changed

Lines changed: 191 additions & 0 deletions

File tree

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
import os
2+
import json
3+
import re
4+
5+
# =========================
6+
# Globals
7+
# =========================
8+
contacts_file = "contacts.json"
9+
contacts = {}
10+
11+
# =========================
12+
# Helper Functions
13+
# =========================
14+
def load_contacts():
15+
global contacts
16+
if os.path.exists(contacts_file):
17+
with open(contacts_file, "r", encoding="utf-8") as f:
18+
contacts = json.load(f)
19+
else:
20+
contacts = {}
21+
22+
def save_contacts():
23+
with open(contacts_file, "w", encoding="utf-8") as f:
24+
json.dump(contacts, f, indent=4)
25+
26+
def display_contacts(filter_term=None):
27+
if not contacts:
28+
print("\nNo contacts available.\n")
29+
return
30+
31+
print("\nContacts List:")
32+
print("-" * 40)
33+
for name, info in contacts.items():
34+
if filter_term and filter_term.lower() not in name.lower():
35+
continue
36+
print(f"Name: {name}")
37+
print(f" Phone: {info.get('phone', 'N/A')}")
38+
print(f" Email: {info.get('email', 'N/A')}")
39+
print("-" * 40)
40+
print()
41+
42+
def add_contact():
43+
name = input("Enter name: ").strip()
44+
if not name:
45+
print("Name cannot be empty!")
46+
return
47+
phone = input("Enter phone: ").strip()
48+
email = input("Enter email: ").strip()
49+
50+
contacts[name] = {"phone": phone, "email": email}
51+
save_contacts()
52+
print(f"Contact '{name}' added successfully.\n")
53+
54+
def update_contact():
55+
name = input("Enter the name of the contact to update: ").strip()
56+
if name not in contacts:
57+
print(f"No contact found with name '{name}'\n")
58+
return
59+
60+
print("Leave blank to keep current value.")
61+
phone = input(f"Enter new phone [{contacts[name].get('phone','')}]: ").strip()
62+
email = input(f"Enter new email [{contacts[name].get('email','')}]: ").strip()
63+
64+
if phone:
65+
contacts[name]['phone'] = phone
66+
if email:
67+
contacts[name]['email'] = email
68+
69+
save_contacts()
70+
print(f"Contact '{name}' updated successfully.\n")
71+
72+
def delete_contact():
73+
name = input("Enter the name of the contact to delete: ").strip()
74+
if name not in contacts:
75+
print(f"No contact found with name '{name}'\n")
76+
return
77+
confirm = input(f"Are you sure you want to delete '{name}'? (y/n): ").strip().lower()
78+
if confirm == 'y':
79+
contacts.pop(name)
80+
save_contacts()
81+
print(f"Contact '{name}' deleted.\n")
82+
else:
83+
print("Deletion canceled.\n")
84+
85+
def search_contacts():
86+
term = input("Enter search term: ").strip()
87+
if not term:
88+
print("Search term cannot be empty!\n")
89+
return
90+
display_contacts(filter_term=term)
91+
92+
# =========================
93+
# Bulk Search & Replace
94+
# =========================
95+
def bulk_search_replace():
96+
global contacts # << Move this to the top
97+
if not contacts:
98+
print("\nNo contacts available for bulk search & replace.\n")
99+
return
100+
101+
print("\n--- Bulk Search & Replace ---")
102+
field = input("Choose field to update (name/phone/email): ").strip().lower()
103+
if field not in ['name', 'phone', 'email']:
104+
print("Invalid field. Choose 'name', 'phone', or 'email'.")
105+
return
106+
107+
search_text = input("Enter text to search: ").strip()
108+
replace_text = input("Enter replacement text: ").strip()
109+
110+
if not search_text:
111+
print("Search text cannot be empty!")
112+
return
113+
114+
# Keep track of changes for preview
115+
changes = []
116+
updated_contacts = {}
117+
118+
for name, info in contacts.items():
119+
if field == "name":
120+
if re.search(re.escape(search_text), name, re.IGNORECASE):
121+
new_name = re.sub(re.escape(search_text), replace_text, name, flags=re.IGNORECASE)
122+
updated_contacts[new_name] = info
123+
changes.append(f"{name} -> {new_name}")
124+
else:
125+
updated_contacts[name] = info
126+
else:
127+
value = info.get(field, "")
128+
if re.search(re.escape(search_text), value, re.IGNORECASE):
129+
new_value = re.sub(re.escape(search_text), replace_text, value, flags=re.IGNORECASE)
130+
info[field] = new_value
131+
changes.append(f"{name}: {field} -> {new_value}")
132+
updated_contacts[name] = info
133+
134+
if not changes:
135+
print("No matches found for the given search text.\n")
136+
return
137+
138+
# Preview changes
139+
print("\nPreview of changes:")
140+
print("-" * 40)
141+
for change in changes:
142+
print(change)
143+
print("-" * 40)
144+
145+
confirm = input("Apply these changes? (y/n): ").strip().lower()
146+
if confirm == 'y':
147+
contacts = updated_contacts
148+
save_contacts()
149+
print(f"{len(changes)} changes applied successfully.\n")
150+
else:
151+
print("Bulk replacement canceled.\n")
152+
153+
# =========================
154+
# Main Menu
155+
# =========================
156+
def main_menu():
157+
load_contacts()
158+
while True:
159+
print("\n=== Contact Book CLI ===")
160+
print("1. Display all contacts")
161+
print("2. Add contact")
162+
print("3. Update contact")
163+
print("4. Delete contact")
164+
print("5. Search contacts")
165+
print("6. Bulk Search & Replace")
166+
print("7. Exit")
167+
choice = input("Choose an option [1-7]: ").strip()
168+
169+
if choice == '1':
170+
display_contacts()
171+
elif choice == '2':
172+
add_contact()
173+
elif choice == '3':
174+
update_contact()
175+
elif choice == '4':
176+
delete_contact()
177+
elif choice == '5':
178+
search_contacts()
179+
elif choice == '6':
180+
bulk_search_replace()
181+
elif choice == '7':
182+
print("Exiting Contact Book. Goodbye!")
183+
break
184+
else:
185+
print("Invalid choice. Please enter a number between 1 and 7.\n")
186+
187+
# =========================
188+
# Run Program
189+
# =========================
190+
if __name__ == "__main__":
191+
main_menu()

0 commit comments

Comments
 (0)