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')
Related
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
I need to define a search function for my code that searches for letters within my dictionary. I am only missing the actual 'search' loop and code. Many lines of code have been left out for ease of reading.
while True:
option = get_option()
...
elif (option == "S"):
search(users)
...
users = {}
def add(users):
student_number = input('Enter student number: ')
family_name = input("Enter family name: ")
first_name = input("Enter first name: ")
phone_number = input('Enter phone number: ')
single_info = {"student_number": student_number, "family_name": family_name, "first_name": first_name, "phone_number": phone_number}
users[student_number] = single_info
print("Record is added.")
...
family_name = input("Enter family name: ")
first_name = input("Enter first name: ")
# STN Name Phone
1 0123456 John Smith 111222
2 1111111 Mary Lee 001122
3 2222222 Hoa Zhang 334455
2 7676767 Milka Sjanovic 012012
This is the dictionary with the inputs, I require a search function to search for names within this.
expected output is
Search record by name.
Enter text to search: Mi
Search found 2 records.
# STN Name Phone
1 0123456 John Smith 111222
2 7676767 Milka Sjanovic 012012
You can traverse your dictionary using a comprehension to build a result set:
text = input("Enter text to search:").lower()
result = [ s for s in users.values() if text in (s["family_name"]+" "+s["first_name"]).lower() ]
print(f"Search found {len(result)} records")
for i,s in enumerate(result):
print(i+1,s["student_number"],s["first_name"],s["family_name"],s["phone_number"])
note: Given that you provided no usable test data, I just typed this in the answer box. You will need to fix any typos, and add formatting yourself
You could also separate the criteria definition from the search process like this:
criteria = lambda s:any(text in s[n].lower() for n in ["family_name","first_name"])
result = list(filter(criteria,users.values()))
This will give you more flexibility and the ability to easily create searches on other fields. For example, searching in any field:
criteria = lambda s: text in " ".join(s.values()).lower()
result = list(filter(criteria,users.values()))
I am writing a program that asks the user for a first and a last name, then stores that name and asks for another. I can write code to ask for the names and can get the program to display the names. The problem is the names aren't saving. Do I need to make a list to save the names?
I have tried tweaking the program multiple times but with no luck.
def make_names(first_name, last_name):
first_name = first_name.strip()
last_name = last_name.strip()
full_block = {'First name: ': first_name, 'Last Name': last_name}
return full_block
while True:
first_name = input("Enter the first name of someone you know, press q to exit: ")
last_name = input("Enter the last name of someone you know, press q to exit: ")
if first_name == 'q' or last_name == 'q':
print("You pressed q, quitting..")
break
else:
full_name = make_names(first_name, last_name)
print(full_name)
The expected result to would to store all names entered then display them in the end.
You need to put your result in a list such as:
def make_names(first_name, last_name):
first_name = first_name.strip()
last_name = last_name.strip()
full_block = {'First name: ': first_name, 'Last Name': last_name}
return full_block
full_list = []
while True:
first_name = input("Enter the first name of someone you know, press q to exit: ")
last_name = input("Enter the last name of someone you know, press q to exit: ")
if first_name == 'q' or last_name == 'q':
print("You pressed q, quitting..")
break
else:
full_name = make_names(first_name, last_name)
print(full_name)
full_list.append(full_name)
print(full_list)
That being said I wouldn't use a dict for this. Instead use something like a namedtuple:
from collections import namedtuple
Person = namedtuple("Person", "first_name last_name")
def make_names(first_name, last_name):
first_name = first_name.strip()
last_name = last_name.strip()
return Person(first_name, last_name)
persons = []
while True:
first_name = input("Enter the first name of someone you know, press q to exit: ")
last_name = input("Enter the last name of someone you know, press q to exit: ")
if first_name == 'q' or last_name == 'q':
print("You pressed q, quitting..")
break
else:
full_name = make_names(first_name, last_name)
print(full_name)
persons.append(full_name)
for person in persons:
print("First Name: {} --- Last Name: {}".format(person.first_name, person.last_name))
Just create an empty list before start your loop, then add each full_name dictionary to the list.
names = []
while True:
first_name = input("Enter the first name of someone you know, press q to exit: ")
last_name = input("Enter the last name of someone you know, press q to exit: ")
if first_name == 'q' or last_name == 'q':
print("You pressed q, quitting..")
break
else:
full_name = make_names(first_name, last_name)
names.append(full_name)
print(full_name)
print(names)
As I had mentioned in my comment, the OOP approach will be best for this. I just copied few lines of your code and implemented using OOP.
Note1: Few lines are documented with comments so do not forget to read.
I have also given o/p of my terminal. Here I have just entered first & last names of 2 people, stored them in a list as dictionaries.
make_names() method asks user to input first & last names until he/she presses q.
show_all_names() method returns a list of dictionaries.
show_name() method returns a single dictionary object (n denotes the place of item in list).
Note2: Just copy the code, paste in a file (in my case name.py) and run from terminal (In my case, python3 name.py).
class Name(object):
def __init__(self):
self.names = []
def make_names(self):
while True:
names = {} # Dictionary to store `first_name` & `last_name`
first_name = input("Enter the first name of someone you know, press q to exit: ")
if first_name == "q":
break
else:
names["first_name"] = first_name
last_name = input("Enter the last name of someone you know, press q to exit : ")
if last_name == "q":
# If no `last_name`, remove `first_name` (you can write your own logic as you want)
del names['first_name']
break
else:
names["last_name"] = last_name
self.names.append(names)
def get_all_names(self):
return self.names
def get_name(self, n):
# `n` will be 1 if you want to get the first entered names in the list & so on
try:
name = self.names[n-1]
except Exception as err:
name = None
print(err) # list index out of range
return name
if __name__ == "__main__":
name = Name()
name.make_names()
name_list = name.get_all_names()
import json
print(json.dumps(name_list, indent=4)) # PRETTY PRINT
# [
# {
# "first_name": "Rishikesh",
# "last_name": "Agrawani"
# },
# {
# "first_name": "Hemkesh",
# "last_name": "Agrawani"
# }
# ]
name1 = name.get_name(1)
print(name1)
# {'first_name': 'Rishikesh', 'last_name': 'Agrawani'}
name2 = name.get_name(2)
print(name2)
# {'first_name': 'Hemkesh', 'last_name': 'Agrawani'}
name3 = name.get_name(3) # None (only 2 names are there in this case)
print(name3)
# None
Output (Picture of my terminal)
Thank you very much.
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.
I'm trying to do a question out of my book and it asks:
Implement function names that takes no input and repeatedly asks the
user to enter a student's first name. When the user enters a blank
string, the function should print for every name, the number of
students with that name.
Example usage:
Usage:
names()
Enter next name: Valerie
Enter next name: Bob
Enter next name: Valerie
Enter next name: John
Enter next name: Amelia
Enter next name: Bob
Enter next name:
There is 1 student named Amelia
There are 2 students named Bob
There is 1 student named John
There are 2 students named Valerie
So far I have this code:
def names():
names = []
namecount = {a:name.count(a) for a in names}
while input != (''):
name = input('Enter next name: ')
names = name
if input == ('')
for x in names.split():
print ('There is', x ,'named', names[x])
I'm really lost here and any input would help out tons. Also if possible please explain how to fix my code
There are a lot of issues with namings in your function, you are using such variables like 'names' that is used for function name as well as 'input' that is a python function name for reading user input - so you have to avoid using this. Also you defining a namecount variable as a dict and trying to initialize it before fill. So try to check solution below:
def myFunc():
names = []
name = ''
while True: #bad stuff you can think on your own condition
name = raw_input('press space(or Q) to exit or enter next name: ')
if name.strip() in ('', 'q', 'Q'):
for x in set(names):
print '{0} is mentioned {1} times'.format(x, names.count(x))
break
else:
names.append(name)
myFunc()
OR:
from collections import defaultdict
def myFunc():
names = defaultdict(int)
name = ''
while True: #bad stuff you can think on your own condition
name = raw_input('press space(or Q) to exit or enter next name: ')
if name.strip() in ('', 'q', 'Q'):
for x in set(names):
print '{0} is mentioned {1} times'.format(x, names[x])
break
else:
names[name] += 1
I rewrote your function for you:
def names():
names = {} # Creates an empty dictionary called names
name = 'cabbage' # Creates a variable, name, so when we do our while loop,
# it won't immediately break
# It can be anything really. I just like to use cabbage
while name != '': # While name is not an empty string
name = input('Enter a name! ') # We get an input
if name in names: # Checks to see if the name is already in the dictionary
names[name] += 1 # Adds one to the value
else: # Otherwise
names[name] = 1 # We add a new key/value to the dictionary
del names[''] # Deleted the key '' from the dictionary
for i in names: # For every key in the dictionary
if names[i] > 1: # Checks to see if the value is greater for 1. Just for the grammar :D
print("There are", names[i], "students named", i) # Prints your expected output
else: # This runs if the value is 1
print("There is", names[i], "student named", i) # Prints your expected output
When doing names():
Enter a name! bob
Enter a name! bill
Enter a name! ben
Enter a name! bob
Enter a name! bill
Enter a name! bob
Enter a name!
There are 3 students named bob
There are 2 students named bill
There is 1 student named ben
Let's analyse your code:
def names():
names = []
namecount = {a:name.count(a) for a in names}
while input != (''):
name = input('Enter next name: ')
names = name
if input == ('')
for x in names.split():
print ('There is', x ,'named', names[x])
There seem to be a few problems, let's list them
The while loop's conditional
What you want to do check if input from user is '' (nothing)..
input is a built-in function for getting input from user, so it never will be ('').
The names = name statement
What you want to do is add name to the list names.
Here you are changing names to a string, which isn't what you want.
The if's conditional
same as 1.
The for loop
let's ignore.. just not valid.. here..
We fix these problems as follows(solution has same numbering as problem above that it solves)
Change the conditional to something like name != ''.
Also, before the loop begins, you need to get input once for this to work, which in this case has a bonus, the first input can have a different prompt.
Use names.append(name) to add name to names.
Same as 1.
Just look at the for loop below...
Try this
def names():
names = []
name = input('Enter a name: ').strip() # get first name
while name != '':
names.append(name)
name = raw_input('Enter next name: ').strip() # get next name
for n in set(names): # in a set, no values are repeated
print '%s is mentioned %s times' % (n, names.count(n)) # print output
def names():
counters = {}
while True:
name = input('Enter next name:')
if name == ' ':
break
if name in counters:
counters[name] += 1
else:
counters[name] = 1
for name in counters:
if counters[name] == 1:
print('There is {} student named {}'.format(counters[name],name))
else:
print('There are {} student named {}'.format(counters[name],name))
names()