How to correct input validation for array? - python

I was just wondering if there was a way so that
def main():
SIZE = 7
people = ["bob", "john", "amy", "jose", "kai", "joe", "leia"]
#phoneNumbers = ['1231111111', '1232222222', '1233333333', '1234444444', '1235555555', '1236666666', '1237777777']
# name validation
index = 0
nameInput = input("Enter a person's name: ")
while (nameInput.lower() != people[index]):
if (nameInput.lower() == people[index]):
input("Error: Please enter a name: ")
else:
index = index + 1
# find the name
found = False
index = 0
while (found == False and index <= SIZE - 1):
if (people[index] == nameInput.lower()):
found = True
else:
index = index + 1
if found:
print("The person's name and phone number is:", people[index], index + 1)
else:
print('No user found at ', index + 1)
main()
would print an error and ask for reinput upon the error and have this iterate
input("Error: Please enter a name: ")
Or I guess my main goal would be so that it'll cycle through the list of names and make sure the name validation goes through
Things I've tried:
Setting the conditions and trying to find which condition would allow that
Deleting the if portion nested in the while statement, but gets rid of the resulting code that shows which place the names are, and only allows "bob" to work
Pardon for the messy code, writing this atm

people = ["bob", "john", "amy", "jose", "kai", "joe", "leia"]
phoneNumbers = ['1231111111', '1232222222', '1233333333', '1234444444', '1235555555', '1236666666', '1237777777']
index = None
while index is None:
nameInput = input("Enter a person's name: ")
if nameInput in people:
index = phoneNumbers.index(nameInput)
print("The person's name and phone number is:", people[index], phoneNumbers[index], index + 1)
else:
print('No user found')

I don't know exactly what you are trying to do and more information would be great, but it sounds like a dictionary would be the perfect data structure, because it is easier to implement and fast to parse. For example if you had three people, say "Emily", "Bob" and "John", then you could assign their names to their phone numbers.
# Parallel lists, each index of one list corresponds to the same index of the other list
people = ["bob", "emily", "john"]
phones = ["123", "124", "125"]
people_dict = {}
for i in range(len(people)):
people_dict[people[i]] = phones[i]
print(people_dict) # prints "{'bob': '123', 'emily': '124', 'john': '125'}"
while True:
in_name = input("Person's name: ")
try:
print(f"{in_name}'s phone number is: {people_dict[in_name]}")
break
except KeyError:
print("The name you provided was not in the list\nPlease retry.\n")
This should work then. Easy enough and faster than looping in a list. The for loop I used was just to create the dictionary. Also to create the dictionary this way, there have to be the same number of people and phone numbers, or the program will exit with an IndexError inside the for loop.
If you had to use lists, you could still try to find the index of a name and if it is not found, retry.
# Parallel lists, each index of one list corresponds to the same index of the other list
people = ["bob", "emily", "john"]
phones = ["123", "124", "125"]
while True:
in_name = input("Person's name: ")
try:
print(f"{in_name}'s phone number is {phones[people.index(in_name)]}")
break
except ValueError:
print("The name you provided was not in the list\nPlease retry.\n")

def main():
SIZE = 7
people = ["bob", "john", "amy", "jose", "kai", "joe", "leia"]
phoneNumbers = ['121', '122', '123', '124', '125', '126', '127']
nameInput = input("Enter a person's name: ")
# find the name and phone number
found = False
index = 0
while (found == False and index <= SIZE - 1):
if (people[index] == nameInput.lower()):
found = True
else:
index = index + 1
if found:
print("The person's name and phone number is:", people[index], phoneNumbers[index])
else:
print('No user found')
# call main to run
main()
well i guess i got it to work
Thanks for those who pitched in an answer

Related

Is there a way i can search in a list for some letters of a word and delete the whole word?(SOLVED)

im trying to code a simple contact book with just names and phone numbers. I want it to have the options add,remove,search and exit obviously. In my remove and search option i got one problem: For example if the use adds a new name to the contact book for example "Alex Balex" and wants to remove it or search it after he needs to type Alex Balex but i want the program to find and delete Alex out of the list if i search for "Alex Bal" aswell. That was my attempt but i cant find a solution:
import pickle
import sys
while True:
option = int(input(("You got 3 options 1=add 2=remove 3=search 4=exit and save. Please enter what you want to do: ")))
if option == 1:
names = []
names = pickle.load(open("names.dat", "rb"))
new_entry, new_number = str(input("Enter a new name which you want to be added to the CB in this format name:phone_number\nINPUT: ")).split(":")
new_user = "Name: " + new_entry + " Number: " + new_number
names.append(new_user)
pickle.dump(names, open("names.dat", "wb"))
elif option == 2:
names = []
names = pickle.load(open("names.dat", "rb"))
print(names)
new_removal = str(input("Enter what you want to remove: "))
for element in names:
if new_removal in element:
names.remove(names[names.index(element)])
pickle.dump(names, open("names.dat", "wb"))
elif option == 4:
sys.exit()
elif option == 3:
names = []
names = pickle.load(open("names.dat", "rb"))
print(names)
new_search = str(input("Search either a name or a number: "))
for element in names:
if new_search in element:
new_search = names[names.index(element)]
print(new_search)
pickle.dump(names, open("names.dat", "wb"))
A simple solution to your problem is to find the first name with the prefix the user entered, and then remove that:
elif option == 2:
new_removal = str(input("Enter what you want to remove: "))
i_remove = -1
for i, name in enumerate(names):
if name.lower()[0:len(new_removal)] == new_removal.lower():
i_remove = i
break
if i_remove != -1:
names.remove(i_remove)
else:
print(f"Name not found: {new_removal}", file=sys.stderr)
One question you'll need to consider though is what to do if multiple names start with the same prefix.
For example, what if a user's contact list contains Alex Balex, and Alex Ball, and the user asks to remove Alex Bal?
The simplest solution here would be to simply not remove anything since the specific name of the contact cannot be deduced - but another option might be instead to prompt the user with the list of contacts with that prefix and ask them to choose which one they want to remove.
I leave this part to you - good luck!

Find duplicates and their indexes

I need to write a program using parallel arrays. The program should ask the user to input a name then it will check if the name is in an existing array and if the name is in the array it will return the first name, the last name, the index where it was found in the array and the phone number. If there is more than a name that matches then it will return both of the names and their indexes.
This is what I have so far but I cannot seem to figure out how to get the index of the second duplicate.
name = ["David", "Tony", "Josh", "Chloe", "David", "Olivia"]
lastName = ["Smith", "Jones", "Brown", "Miller", "Brown", "Williams"]
phone = ["111-123-1234","222-123-1234","333-123-1234","444-123-1234","555-123-1234","662-123-1234"]
for i in range(len(name)):
sName = input("Enter a Name: ")
if sName in name:
index = firstName.index(sName)
print(name[index],lastName[index],"is located at index",index)
print("Phone number:", phone[index])
print()
else:
print("The name:", sName, "does not exist in our records")
print("Please try a different name.")
print()
#The output should be something like:
#David Smith is located at index 0
#Phone number: 111-123-1234
#
#David Brown is located at index 4
#Phone number:555-123-1234
Here is a very simple solution to your problem.
name = ["David", "Tony", "Josh", "Chloe", "David", "Olivia"]
lastName = ["Smith", "Jones", "Brown", "Miller", "Brown", "Williams"]
phone = ["111-123-1234","222-123-1234","333-123-1234","444-123-1234","555-123-1234","662-123-1234"]
found = False
sName = input("Enter a Name: ")
for i in range(len(name)):
if sName == name[i]:
print(name[i],lastName[i],"is located at index",i)
print("Phone number:", phone[i])
found = True
if found == False:
print("The name:", sName, "does not exist in our records")
print("Please try a different name.")
You do not need to use the index function because as you iterate the list using the for loop, if the target name is found a name[i], that value of i is the index of the target name. Additionally I moved
sName = input("Enter a Name: ")
outside the for loop. If it remains in the for loop, it only compares the target name with the name at the current index i.
In Python list index method, you can specify additional arguments:
start: from which index to start searching
end: upto which index should the item be searched
Once you find the first index, you can try searching again by setting start index just after the first occurrence index.
Reference: https://docs.python.org/3/tutorial/datastructures.html
Here is a function that could the job:
name = ["David", "Tony", "Josh", "Chloe", "David", "Olivia"]
lastName = ["Smith", "Jones", "Brown", "Miller", "Brown", "Williams"]
phone = ["111-123-1234","222-123-1234","333-123-1234","444-123-1234","555-123-1234","662-123-1234"]
def findIndex(find_name, first_name):
pos = []
for x in range(len(first_name)):
if find_name == first_name[x]:
pos.append(x)
return pos
for i in range(len(name)):
sName = input("Enter a Name: ")
pos = findIndex(sName, name)
if len(pos) > 0:
for x in pos:
print(name[x],lastName[x],"is located at index",x)
print("Phone number:", phone[x])
print()
else:
print("The name:", sName, "does not exist in our records")
print("Please try a different name.")
print()
Here is a more pythonic function:
def findIndex(find_name, first_name):
return [x for x in range(len(first_name)) if find_name == first_name[x]]
You could also do something like this using the enumerate function:
lastName = ["Smith", "Jones", "Brown", "Miller", "Brown", "Williams"]
phone = ["111-123-1234","222-123-1234","333-123-1234","444-123-1234","555-123-1234","662-123-1234"]
sample_name = 'David Smith'
def find_details(full_name):
# Split the full name into first and last name
[first, last] = full_name.split(' ')
# check for the first name in the name list
for count, f_name in enumerate(name):
# if the first name is listed
if f_name == first:
# check if the last name at the same index is the last name we need
if lastName[count] == last:
phone_number = phone[count]
# we have found the person we need
print(f'{full_name} is located at position {count}. \nPhone number: {phone_number}\n')
return True
# Otherwise, we didn't find the name
print(f"The name: {full_name} does not exist in our records. \nPlease try a different name.\n")
return False
find_details('Josh Brown')
find_details('Delilah Le')

Another question: Phone dictionary problem 'while-loop' using Error

Simply question making phone dictionary
What I want to do is putting person's name and number and finding them in dictionary!
Examples what I want to do
Enter command (a, f, d, or q).: a
Enter new name................: Perry
Enter new phone number........: 229-449-9683
Enter command (a, f, d, or q).: f
Enter name to look up...:
I would like to find full name and number when I type
Phone dictionary code what I wrote so far:
phone_dict = {}
command = input('Enter command (a, f, d, or q).: ')
newname = input('Enter new name................: ')
newphone = input('Enter new phone number........: ')
while True:
if command == 'a':
newname
newphone
phone_dict[newname] = newphone
print(phone_dict)
# In here, 'while-loop' does not work.
In there, if I enter 'a' command, and type the name
The dictionary is supposed to be { Perry: 229-449-9683}
Thanks, The question might be little confused, but if you can help this out, I am very happy!
To find the result from the dictionary, you can loop through the items and check if the key contains the string you want to find. If you want to get all values which satisfy your query, you can create another list or dictionary and store the items you find:
phone_dict = {
"Han Perry": "1234",
"Harry Gildong": "2345",
"Hanny Test": "123",
}
find_str = "Han"
result = {}
for key, value in phone_dict.items():
# Converting it to lower makes it case insensitive
if find_str.lower().strip() in key.lower():
result[key] = value
print(result)
# {'Han Perry': '1234', 'Hanny Test': '123'}
Take note that this will run through all of the values of the dictionary: O(n)
To find the number using the first o last name of the person you could do:
a = 'Add a new phone number'
d = 'Delete a phone number'
f = 'Find a phone number'
q = 'Quit'
phone_dict = {}
while True:
# Gets the user command every loop
command = input('Enter command (a, f, d, or q).: ')
# Add a new registry to the directory
if command == 'a':
newname = input('Enter new name................: ')
newphone = input('Enter new phone number........: ')
phone_dict[newname] = newphone
print(phone_dict)
# Find a registry on the directory
elif command == "f"
query = input("Enter name to look up...: ")
match = None
for key in phone_dict.keys():
if query.strip() in key:
match = phone_dict[key]
break
if match is None:
print(f"The name {query} could not be found on the directory")
else:
print(f"The phone number of {query} is {match}")
elif command == "d":
# Delete registry
elif command == "q":
# Quits program
else:
print(f"The command {command} was not found, please try again!")
In this case, I am using query.strip() to remove any extra start/end spaces that could cause to not find the person.

How do I access the array using the for loop in the while loop

I am working with an external file which has data in the form of:
-12345 CSEE 35000 Bart Simpson
-12346 CSEE 25000 Harry Potter
-12350 Economics 30000 Krusty The Clown
-13123 Economics 55000 David Cameron
With the first item being the ID, the second the subject, the third the salary, and the rest being the name of the person.
In part of my program I am trying to print the information of the people who have salaries between values submitted by the user. I have put all the data in a list called lecturers then I put all the salaries in a separate list called lecturers salary and tried to make them integers because at first I thought the reason the for loop wasn't working was because when trying to access them from the lectures loop I thought they might still be part of a string at this point.
I have already used a loop in my program to print all the people who teach a specific subject. This subject is submitted by the user. I tried to use a for loop again for the salaries but its not working.
print""
# To God be the Glory
lecturer = []
lecturer_salary = []
x = 0
a = " "
print ""
String = raw_input("Please enter the lecturers details: ")
print ""
def printFormat(String):
String = String.split()
lastname = String[-1]
firstnames = " ".join(String[3:-1])
name = ", ".join([lastname, firstnames])
ID_Subject = " ".join(String[0:2])
money = String[2]
print "%s,%s %s %s" % (lastname,firstnames,ID_Subject,money)
printFormat(String)
while x < len(lecturer):
lecturer_salary.append(int(lecturer [x][2]))
x = x + 1
print ""
try:
fname = input("Enter filename within " ": ")
with open(fname) as f:
for line in f:
data = line.split()
printFormat(line)
line = line.split()
lecturer.append(line)
except IOError as e :
print("Problem opening file")
print ""
print ""
answer = raw_input("Would you like to display the details of lectureers from a particular department please enter YES or NO: ")
if answer == "YES" :
print ""
department = raw_input("Please enter the department: ")
print ""
while x < len(lecturer) :
for line in lecturer:
if lecturer[x][1] == department:
a = lecturer[x]
a = ' '.join(a)
printFormat(a)
x = x + 1
**elif answer == "NO" :
print ""
answer2 = raw_input ("Would you like to know all the lecturers within a particular salary range: ")
print ""
if answer2 == "YES":
lower_bound = int(input("Please enter the lower bound of the salary range: "))
upper_bound = int(input("Please enter the upper bound of the salary range: "))
print ""
while x < len(lecturer) :
for line in lecturer_salary:
if lower_bound < lecturer_salary[x] < upper_bound :
print lecturer_salary[x]
x = x + 1**
else:
print ""
print "Please enter a valid input"
So, you have an array of lecturer and one of lecturer salary. the
for line in lecturer_salary:
is not needed - just the while followed by the if. Note that this will only print out the salary, not the lecturer details. Since x is the index to both arrays you can access lecturer[x] for the rest. In truth you don't need the lecturer_salary at all, just walk through lecturer and check:
while x < len(lecturer) :
if lower_bound < lecturer[x][2] < upper_bound :
a = lecturer[x]
a = ' '.join(a)
printFormat(a)
x = x + 1
For starters, you shouldn't name your variable with a capital letter like String or Id_Subject.
It is simpler to break code into functions and try using a dictionary or class to improve readability and extensibility.
Here is a minimal code using class:
lecturers = [] # To store Lecturer instances, which isn't necessary
class Lecturer():
def __init__(self, id, subject, salary, name):
self.id = id
self.subject = subject
self.salary = salary
self.name = name
def readfile(filename):
"""read each line in a file and yield a list of fields"""
with open(filename, "r") as f:
for line in f.readlines():
# return a list of fields
yield line.replace("\n", "").split()
def new_lecturer(detail):
"""Return a new lecturer instance from a list of fields"""
return Lecturer(detail[0],
detail[1],
detail[2],
{"firstname": detail[3],
"lastname": detail[4]
})
def print_lecturer_detail(lecturer):
"""Accept a lecturer instance and print out information"""
print "{0},{1} {2} {3}".format(lecturer.name["lastname"],
lecturer.name["firstname"],
lecturer.id,
lecturer.salary)
def main():
"""This is where all the main user interaction should be"""
fname = raw_input("Enter filename: ")
for lecturer in (readfile(fname)):
lecturers.append(new_lecturer(lecturer))
print ""
answer = raw_input("Would you like to display lecturers by department(Y/N)?: ")
if answer == "Y":
print ""
department = raw_input("Please enter the department: ")
print ""
for lecturer in lecturers:
if lecturer.subject == department:
print_lecturer_detail(lecturer)
elif answer == "N":
# implement salary code here
pass
if __name__ == '__main__':
main()
This may be an overkill now, but it's better than dealing with lists in a long run. You'll see that dealing with properties become much simpler. You may want to improve each function further and make it more modular and reusable.
#Paul Morrington has the straight answer on the while part.

How to store multiple entries for each student using dictionaries

Here is the problem statement:
There is a record of 'n' students, each record having name of student, percent marks obtained in Maths, Physics and Chemistry. The user enters an integer 'n' followed by names and marks for the 'n' students. I am required to save the record in a dictionary data type. The user then enters name of a student and you are required to print the average percentage marks obtained by that student, correct to two decimal places.
what I have tried so far:
num_students = int(raw_input("Please enter number of students:"))
print "you entered %s students" %num_students
student_info = {}
student_data = ['studentname', 'mathmarks', 'physicsmarks', 'chemistrymarks']
for i in range(0,num_students):
for entry in student_data:
student_info[entry] = raw_input(entry )
print student_info
print"please enter student name"
name = raw_input("student name")
if student_info['studentname'] == name:
print "Average student marks:", (int(student_info['mathmarks']) + int(student_info['physicsmarks']) + int(student_info['chemistrymarks']))/3
else:
print"please enter valid name"
This code is working is num_students = 1, However if num_students >1 the code fails.
I am unable to save the entry of each student in dictionary.
I am pretty new to python, would be glad if any one can help me with this.
Actually you need to create a nested dictionary with name as values and another dict as keys, in pretty way the nested dict may look like:
{
'anmol': {'chemistrymarks': 3, 'physicsmarks': 2, 'mathmarks': 1},
'uppal': {'chemistrymarks': 6, 'physicsmarks': 5, 'mathmarks': 4}
}
So you need to add the following lines to create a nested dictionary.
num_students = int(raw_input("Please enter number of students:"))
print "you entered %s students" %num_students
student_info = {}
student_data = ['Math marks : ', 'Physics marks : ', 'Chemistry marks : ']
for i in range(0,num_students):
student_name = raw_input("Name :")
student_info[student_name] = {}
for entry in student_data:
student_info[student_name][entry] = int(raw_input(entry)) #storing the marks entered as integers to perform arithmetic operations later on.
#print student_info
print"Please enter student name ?"
name = raw_input("Student name : ")
if name in student_info.keys():
print "Average student marks : ", str(sum(student_info[name].values())/3.0)
else:
print"please enter valid name"
#youcan use print stmts. acording to your problem
n = raw_input()
grades = []
for entry in range(int(n)):
grades.append([i for i in raw_input().split()])
query = raw_input()
# Find list where first item matches name in query and
# assign grades to queryResult
queryResult = [x[1:] for x in grades if x[0] == query]
total = 0
scores = 0
for x in queryResult:
for y in x:
total += float(y)
scores += 1
print "%.2f" % (float(total/scores))
#Another way
num_of_student = int(raw_input())
dir_student = {}
for i in range(0,num_of_student):
student_info = raw_input()
name = student_info.split()
dir_student[name[0]] = [float(name[1]),float(name[2]),float(name[3])]
find_name = raw_input()
if dir_student.has_key(find_name):
print "{0:.2f}".format(sum(dir_student[find_name])/3.0)

Categories