I am trying to create a code that mimics a phone book.
I want the program to accept a last name, a first name or a phone number from the user and to read through the text file/list, looking for a match. If match(s) are found, display the information, and then redisplay the menu.
If the entry was not found display the appropriate not found message. All search results will be written to the screen.
def main():
firstname=[]
lastname=[]
phone=[]
loadLists(firstname, lastname, phone)
choice = menu()
while choice != '4':
if choice == '1':
getLastName(firstname, lastname, phone)
elif choice == '2':
getFirstName(firstname, lastname, phone)
elif choice == '3':
getPhone(firstname, lastname, phone)
choice = menu()
def loadLists(firstname, lastname, phone):
myFile="entries.txt"
fileInput=open(myFile)
count = 0
for myString in fileInput:
myString = myString.strip()
myString = myString.lower()
myNum = count % 3
if myNum == 0:
lastname.append(myString)
elif myNum == 1:
firstname.append(myString)
elif myNum == 2:
phone.append(myString)
count = count +1
fileInput.close()
def menu():
option = '0'
while option != '1' and option != '2' and option != '3' and option != '4':
print("\n1. Look up contact by last name")
print("2. Look up contact by first name")
print("3. Look up contact by phone number")
print("4. Quit")
option = input("\nMenu option: ")
if option != '1' and option != '2' and option != '3' and option != '4':
print("Invalid option. Please select again.")
return option
def getLastName(firstname, lastname, phone):
target=input("\nEnter contacts last name: ")
target=target.strip().lower()
position=0
if target in lastname:
while True:
try:
position=lastname.index(target, position)
entry =firstname[position].title()+" "+lastname[position].title()+" "+phone[position].title()
print("\n" + entry)
position= position + 1
except:
break
else:
print("\nNot found")
def getFirstName(firstname, lastname, phone):
target=input("\nEnter contacts first name: ")
target=target.strip().lower()
position=0
if target in firstname:
while True:
try:
position=firstname.index(target, position)
entry=firstname[position].title()+" "+lastname[position].title()+" "+phone[position].title()
print("\n" + entry)
position= position + 1
except:
break
else:
print("\nNot found")
def getPhone(firstname, lastname, phone):
target=input("\nEnter contacts phone number: ")
target=target.strip().lower()
position=0
if target in phone:
while True:
try:
position=phone.index(target, position)
entry=firstname[position].title()+" "+lastname[position].title()+" "+phone[position].title()
print("\n" + entry)
position=position + 1
except:
break
else:
print("\nNot found")
main()
When I run the program it won't load the file I have assigned 'entries.txt'. Could someone explain to me why? I have the file saved to my computer as 'entries' and i've double checked that it is a txt file.
You're not even getting into the loop in loadList, since fileInputis a pointer to a file. Try for myString in fileInput.readlines(): instead.
Instead of using:
def loadLists(firstname, lastname, phone):
myFile="entries.txt"
fileInput=open(myFile)
count = 0
Try using:
def loadLists(firstname, lastname, phone):
myFile="entries.txt"
fileInput=open(myFile, "r")
count = 0
Related
I am a beginner in Python so kindly do not use complex or advanced code.
contact = {}
def display_contact():
for name, number in sorted((k,v) for k, v in contact.items()):
print(f'Name: {name}, Number: {number}')
#def display_contact():
# print("Name\t\tContact Number")
# for key in contact:
# print("{}\t\t{}".format(key,contact.get(key)))
while True:
choice = int(input(" 1. Add new contact \n 2. Search contact \n 3. Display contact\n 4. Edit contact \n 5. Delete contact \n 6. Print \n 7. Exit \n Enter "))
#I have already tried
if choice == 1:
while True:
try:
name = str(input("Enter the contact name "))
if name != str:
except ValueError:
continue
else:
break
while True:
try:
phone = int(input("Enter number "))
except ValueError:
print("Sorry you can only enter a phone number")
continue
else:
break
contact[name] = phone
elif choice == 2:
search_name = input("Enter contact name ")
if search_name in contact:
print(search_name, "'s contact number is ", contact[search_name])
else:
print("Name is not found in contact book")
elif choice == 3:
if not contact:
print("Empty Phonebook")
else:
display_contact()
elif choice == 4:
edit_contact = input("Enter the contact to be edited ")
if edit_contact in contact:
phone = input("Enter number")
contact[edit_contact]=phone
print("Contact Updated")
display_contact()
else:
print("Name is not found in contact book")
elif choice == 5:
del_contact = input("Enter the contact to be deleted ")
if del_contact in contact:
confirm = input("Do you want to delete this contact Yes or No? ")
if confirm == 'Yes' or confirm == 'yes':
contact.pop(del_contact)
display_contact
else:
print("Name is not found in phone book")
elif choice == 6:
sort_contact = input("Enter yes to print your contact")
if sort_contact in contact:
confirm = input("Do you want to print your contact Yes or No? ")
if confirm == 'Yes' or confirm == 'yes':
strs = [display_contact]
print(sorted(strs))
else:
print("Phone book is printed.")
else:
break
I tried but keep getting errors and I can't fiugre out how to make it only take string or letter as input and not numbers.
if choice == 1:
while True:
try:
name = str(input("Enter the contact name "))
if name != str:
except ValueError:
continue
else:
break
it is not working my code still accepts the ans in integer and string.
I am a beginner so I might have made a lot of mistakes. Your patience would be appreciated.
You can use a regex with re.fullmatch:
import re
while True:
name = input("Enter the contact name ")
if re.fullmatch(r'[a-zA-Z]+', name):
break
Or use the case-insensitive flag: re.fullmatch(r'[a-z]+', name, flags=re.I):
As you noted that you are a beginner, I'm adding this piece of code
as a "custom-made" validation, just so you can check how you would do something like this by your own .
Note: #mozway gave a MUCH BETTER solution, that is super clean, and I recommend it over this one.
def valid_input(input: str):
# Check if any char is a number
for char in input:
if char.isdigit():
print('Numbers are not allowed!')
return False
return True
while True:
name = input("Enter data:")
if valid_input(name):
break
I found this answer from another website:
extracted_letters = " ".join(re.findall("[a-zA-Z]+", numlettersstring))
First, import re to use the re function.
Then let's say that numlettersstring is the string you want only the letters from.
This piece of code will extract the letters from numlettersstring and output it in the extracted_letters variable.
import re
contact = {}
def display_contact():
for name, number in sorted((k,v) for k, v in contact.items()):
print(f'Name: {name}, Number: {number}')
#def display_contact():
# print("Name\t\tContact Number")
# for key in contact:
# print("{}\t\t{}".format(key,contact.get(key)))
while True:
choice = int(input(" 1. Add new contact \n 2. Search contact \n 3. Display contact\n 4. Edit contact \n 5. Delete contact \n 6. Save your contact as a file \n 7. Update Saved List \n 8. Exit \n Your choice: "))
if choice == 1:
while True:
name = input("Enter the contact name ")
if re.fullmatch(r'[a-zA-Z]+', name):
break
while True:
try:
phone = int(input("Enter number "))
except ValueError:
print("Sorry you can only enter a phone number")
continue
else:
break
contact[name] = phone
elif choice == 2:
search_name = input("Enter contact name ")
if search_name in contact:
print(search_name, "'s contact number is ", contact[search_name])
else:
print("Name is not found in contact book")
elif choice == 3:
if not contact:
print("Empty Phonebook")
else:
display_contact()
elif choice == 4:
edit_contact = input("Enter the contact to be edited ")
if edit_contact in contact:
phone = input("Enter number")
contact[edit_contact]=phone
print("Contact Updated")
display_contact()
else:
print("Name is not found in contact book")
elif choice == 5:
del_contact = input("Enter the contact to be deleted ")
if del_contact in contact:
confirm = input("Do you want to delete this contact Yes or No? ")
if confirm == 'Yes' or confirm == 'yes':
contact.pop(del_contact)
display_contact
else:
print("Name is not found in phone book")
elif choice == 6:
confirm = input("Do you want to save your contact-book Yes or No?")
if confirm == 'Yes' or confirm == 'yes':
with open('contact_list.txt','w') as file:
file.write(str(contact))
print("Your contact-book is saved!")
else:
print("Your contact book was not saved.")
# else:
elif choice == 7:
confirm = input("Do you want to update your saved contact-book Yes or No?")
if confirm == 'Yes' or confirm == 'yes':
with open('contact_list.txt','a') as file:
file.write(str(contact))
print("Your contact-book has been updated!")
else:
print("Your contact book was not updated.")
else:
break
I add to if else function, one to save the contact list and one to just update it with the new contact. But When I run it I still get the old contact that where already saved. Any ideas on how to fix it to only append the new contacts to the already saved txt file.
elif choice == 6:
confirm = input("Do you want to save your contact-book Yes or No?")
if confirm == 'Yes' or confirm == 'yes':
with open('contact_list.txt','w') as file:
file.write(str(contact))
print("Your contact-book is saved!")
else:
print("Your contact book was not saved.")
# else:
elif choice == 7:
confirm = input("Do you want to update your saved contact-book Yes or No?")
if confirm == 'Yes' or confirm == 'yes':
with open('contact_list.txt','a') as file:
file.write(str(contact))
print("Your contact-book has been updated!")
else:
print("Your contact book was not updated.")
I just changed the "w" in choice 7 to "a" to append the new contact but I still get all the old one in the new save. Any ideas.
I'm working on an exercise, but I'm stuck on the last part
The section goes here:
Rewrite the function remove_friend so it asks for both the firstname and the lastname and remove all in the list_of_friends for which the first- and last name of the friend object equals the first- and last name entered by the user
In the remove_friends function, I know it's not correct.
In my head, I think I need to compare the delete_first_name and delete_last_name against the first_name and last_name in the new_friends class.
However, I don't know what the syntax would be in order to accomplish this.
Does anyone have hints on how to proceed? I would greatly appreciate if you could give suggestions, and not write the solution.
class Friend:
def __init__(self, first_name, last_name, phone_number):
self.first_name = first_name
self.last_name = last_name
self.phone_number = phone_number
def print_info(self, index):
print(f"\n {self.first_name}, {self.last_name}, {self.phone_number} \n")
list_of_friends = []
def add_friends():
print(" ")
first_name = input("Enter the first name: ")
last_name = input("Enter the last name: ")
phone_number = input("Enter the phone number: ")
new_friend = Friend(first_name.upper(), last_name.upper(), phone_number)
list_of_friends.append(new_friend)
print(f"{new_friend.first_name.title()} {new_friend.last_name.title()} has been added to the list \n")
def view_friends():
if len(list_of_friends):
for counter, new_friend in enumerate(list_of_friends, 0):
print(" ")
new_friend.print_info(counter)
else:
print(" ")
print("List is empty \n")
def remove_friends():
print(" ")
delete_first_name = input("Enter first name to remove: ").upper()
delete_last_name = input("Enter last name to remove: ").upper()
full_name = [delete_first_name, delete_last_name]
if full_name not in list_of_friends:
print(f"{delete_first_name} {delete_last_name} does not exist in the list \n")
else:
list_of_friends.remove(delete_first_name)
list_of_friends.remove(delete_last_name)
print(f"{delete_first_name} {delete_last_name}has been deleted from the list \n")
def print_menu():
menu_string = "\n----Options----\n"
menu_string += "1: Add\n"
menu_string += "2: View\n"
menu_string += "3: Remove\n"
menu_string += "4: Exit\n"
print(menu_string)
user_input = 0
while user_input != 4:
print_menu()
try:
user_input = int(input("Choose one of the above options: "))
if user_input < 1 or user_input > 4:
print("Invalid number. Number must be between 1-4 \n")
elif user_input == 1:
add_friends()
elif user_input == 2:
view_friends()
elif user_input == 3:
remove_friends()
except Exception as err:
print(f"Invalid input: {err}")
print("Exiting \n")
Loop the the list of friends and check first and last name
def remove_friends():
print(" ")
delete_first_name = input("Enter first name to remove: ").upper()
delete_last_name = input("Enter last name to remove: ").upper()
new_list = []
for frnds in list_of_friends:
fnm = frnds.first_name
lnm = frnds.last_name
if(fnm == delete_first_name and lnm == delete_last_name):
# print something meaningfull
continue
else:
new_list.append(frnds)
# new_list will contain the list of friends after removal
The list list_friends has Friend objects and not strings.
you need to access the Friend attributes.
for example like this (function is not complete):
def remove_friends():
first_name=...
last_name = ...
temp_list = list_of_friends[:]
for friend in temp_list :
if first_name == friend.first_name and last_name == friend.last_name:
list_of_friends.remove(friend)
Note that in the beginning I copied the list - do not iterate over a list (or similar) and delete objects from the same list, it is a recipe for bugs.
I am having trouble writing a program to repeat input part. for instance
input 1 ___run add_contact()
again ask for input
input 4____run disp_contact()
...
...
I've never written a long code! :\
I'm totally begginer! and learning a bit of Python in my spare time
my mentor said you should define several functions and put them in a main function which get input.
so If anyone can tell me why I get stuck like this I would appreciate it.
contact={}
print(''' phone book
1. add contact
2.delete contact
3.search contact
4.display all
5.Quit''')
def add_contact():
name=input('enter the name: ')
number=input('enter the number: ')
contact[name]=number
print(name, 'added to phone book!')
def del_contact():
name=input('enter the name: ')
while name not in contact:
print("not found! try again" )
name=input('enter again: ')
else:
print(name,' deleted')
del contact[name]
name=False
def search_contact():
name=input('enter the name: ')
while name not in contact:
print('not found!')
name=input('enter again: ')
else:
print(name, 'number is :', contact[name])
def disp_contact():
if len(contact)>0:
print('phone book contacts are: ')
for i in contact:
print(i, end=' ')
else:
print('phone book is empty!')
def main_def(num):
if num==1:
add_contact()
elif num==2:
del_contact()
elif num==3:
search_contact()
elif num==4:
disp_contact()
elif num==5:
print('bye bye')
x=int(input(' enter a number: '))
main_def(x)
You may wrap the main_def in a while True, and use exit(O) to quit properly when 5 is given
def main_def(num):
if num == 1:
add_contact()
elif num == 2:
del_contact()
elif num == 3:
search_contact()
elif num == 4:
disp_contact()
elif num == 5:
exit(0)
while True:
x = int(input(' enter a number: '))
main_def(x)
Note
For del_contact and search_contact, you don't need the else just put after like this
def del_contact():
name = input('enter the name: ')
while name not in contact:
print("not found! try again")
name = input('enter again: ')
print(name, ' deleted')
del contact[name]
Code:
students = []
choice = None
while choice != 0:
print(
"""
0 - Exit
1 - Show all students
2 - Add a student
"""
)
choice = input("Choice: ")
print()
if choice == "0":
print("Goodbye")
break
elif choice == "1":
print("\nStudents: ")
for entry in students:
email, name, number = entry
print(name, "\t", email, "\t", number)
elif choice == "2":
name = input("What is the students name?")
email = input("What is the students email adress? ")
number = int(input("What is the students number? ")
entry = email, name, number
students.append(info)
students.sort(reverse=False)
student = students
else:
print("Sorry, but", choice, "isn't a valid choice.")
When I run this in the compiler, I get a syntax error for the line
entry = email, name, number
I don't know why, please tell me.
You have a missing ) on the line immediately above the line of the error.
number = int(input("What is the students number? ") #here
entry = email, name, number
In general, missing parentheses cause the stack trace to point to the line immediately following.