How to check String input from user inside Class Array - python

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.

Related

How to have input in Python only take in string and not number or anything else only letters

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.

Is there a better way to check if a series of inputs match a certain stop condition?

(Python 3.7)
I have a similar program to what's included below. I was just trying to figure out if there is a better way to check if any user input matches an "end" condition, I do need to save each input separately.
while True:
fname = input("Enter Customer first name: ")
if fname == "end":
break
lname = input("Enter Customer last name: ")
if lname == "end":
break
email = input("Enter Customer email: ")
if email == "end":
break
num = input("Enter Customer id: ")
if num == "end":
break
elif not num.isdigit():
num = -1
# not worried about error here
num = int(num)
print(fname, lname, email, num)
print("User has ended program")
I'm not worried about errors at this stage just trying to brainstorm here about the cleanest implementation. I will have a lot of inputs so I'm hoping I won't have to include the same if statement over and over again for each individual input.
This would be a good opportunity to create a user exception:
class UserExit(BaseException):
pass
def get_input(prompt):
response = input(prompt)
if response=="end":
raise UserExit("User Exit.")
return response
try:
while True:
fname = get_input("Enter Customer first name: ")
lname = get_input("Enter Customer last name: ")
email = get_input("Enter Customer email: ")
num = get_input("Enter Customer id:")
if not num.isdigit():
num = -1
else:
num = int(num)
print (fname,lname,email,num)
except UserExit as e:
print ("User ended program.")

Mimic a phone book

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

Update value of object in list

I have several lists that each contain objects. All objects have the values "name" and "amount". What I want to do is create a method to update "amount" by first finding the item in the list by user input (enter name to find name) then adding or subtracting a user input value (enter value to add/enter value to subtract).
How would I go about doing this?
This is what I have so far (It's incomplete but it's all I could get done):
Containers = []
Lids = []
Wicks = []
Labels = []
Misc = []
class item(object):
#Constructor
def __init__(self, name, amount):
self.name = name
self.amount = amount
#Accessors
def getName(self):
return self.name
def getAmount(self):
return self.amount
#Mutators
def __str__(self):
return "[Name: " + self.name + \
", Amount: " + self.amount + \
"]"
def addAmount():
found = False
name = input("Enter the name of a container you wish to change: ")
addNewAmount = input("Enter the amount you wish to add: ")
for item in Containers:
if name in item.getName():
found = True
position = Containers.index(name)
print(Containers[position])
if not found:
print("No names match that input.")
def subtractAmount():
update = input("Enter a new amount to subtract: ")
self.amount = amount - update
def addContainer():
name = input("Enter a name for the new container: ")
amount = input("Enter an amount for the new container: ")
return item(name, amount)
def addLid():
name = input("Enter a name for the new lid: ")
amount = input("Enter an amount for the new lid: ")
return item(name, amount)
def addWick():
name = input("Enter a name for the new wick: ")
amount = input("Enter an amount for the new wick: ")
return item(name, amount)
def addLabel():
name = input("Enter a name for the new label: ")
amount = input("Enter an amount for the new label: ")
return item(name, amount)
def addMisc():
name = input("Enter a name for the new misc item: ")
amount = input("Enter an amount for the new misc item: ")
return item(name, amount)
def main():
running = True
while running:
print("Enter a number to start.")
print("1) Add new container 2) Add new lid")
print("3) Add new wick 4) Add new label")
print("5) Add new misc Item 6) Print Inventory")
print("7) Add Amount from item 8) Subtract Amount from item")
print("10) quit")
print("11) print list")
choice = input("> ")
if choice == "1":
Containers.append(addContainer())
elif choice == "2":
Lids.append(addLid())
elif choice == "3":
Wicks.append(addWick())
elif choice == "4":
Labels.append(addLabel())
elif choice == "5":
Misc.append(addMisc())
elif choice == "6":
print("<==========Containers==========>")
for i in Containers:
print(i)
print("<=============Lids=============>")
for i in Lids:
print(i)
print("<=============Wicks============>")
for i in Wicks:
print(i)
print("<============Labels============>")
for i in Labels:
print(i)
print("<==========Misc Items==========>")
for i in Misc:
print(i)
elif choice == "7":
return addAmount()
elif choice == "8":
return subtractAmount()
elif choice == "10":
quit()
elif choice == "11":
print('[%s]' % ', '.join(map(str, Containers)))
else:
print("Invalid entry, please try again.")
if __name__ == "__main__":
main()
There's a couple of issues here. The first is whether you want containers, lids, wicks, etc to all be the same type of object ("item") or whether it would make more sense to have subclasses. Assuming you want them all to be the same ("item") you could adjust your methods according to the code below (I've left out a lot of options for simplicity).
A couple things to note:
"amount" needs to be numerical (int) in order to add or subtract from it correctly
the creation of an item is a function outside the class, and allocates the item to the appropriate list (Containers, Lids)
the "add_amount" function looks through all lists of all items to find a possible match and adjusts the amount accordingly. If a lid and container have the same name, it will modify the first match.
Containers = []
Lids = []
Items = [Containers, Lids]
class item(object):
#Constructor
def __init__(self, name, amount):
self.name = name
self.amount = amount
#Accessors
def getName(self):
return self.name
def getAmount(self):
return self.amount
def __str__(self):
return "[Name: " + self.name + \
", Amount: " + str(self.amount) + \
"]"
def addItem():
global new_item
name = input("Enter a name for the new item: ")
amount = int(input("Enter an amount for the new item: "))
new_item = item(name, amount)
return new_item
def add_amount():
found = False
name = input("Enter the name of the item you wish to change: ")
add_amount = int(input("Enter the amount you wish to add: "))
for itemList in Items:
for item in itemList:
if name == item.getName():
found = True
position = itemList.index(item)
item.amount += add_amount
print(itemList[position])
if not found:
print("No names in match that input.")
def main():
running = True
while running:
print("Enter a number to start.")
print("1) Make a container 2) Make a lid")
print("3) add amount 4) quit")
choice = input("> ")
if choice == "1":
addItem()
print new_item.amount
Containers.append(new_item)
elif choice == "2":
addItem()
print new_item.amount
Lids.append(new_item)
elif choice == "3":
add_amount()
elif choice == "4":
quit()
else:
print("Invalid entry, please try again.")
if __name__ == "__main__":
main()
This might be kind of messy, but should do the work:
def subtractAmount():
containers = [Containers, Lids, Wicks, Labels, Misc]
names = ['Containers', 'Lids', 'Wicks', 'Labels', 'Misc']
print('Select the number of list you want to search for item')
print('\n'.join('{}) {}'.format(str(idx), lst_name) for (idx, lst_name) in enumerate(names, 1)))
selected = input(': ')) - 1
item_name = input('Enter the item name you are looking for: ')
item = None
for value in containers[selected]:
if value.getName().lower() == item_name.lower():
item = value
break
else:
print('No item was found with that name!')
new_amount = input('Enter the new amount for item: ')
item.amount = new_amount

Why do I get an invalid syntax error in this piece of code, Python?

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.

Categories

Resources