I have a file with a bunch of names and emails.
They are written as follows:
name
email
name
email
I cant figure out how to open the file and read line by line to where it pairs "name to email" in my dictionary
I got the code to work when I manually type in the names/emails into the dictionary but I need to pull it from the file.
LOOK_UP=1
ADD= 2
CHANGE= 3
DELETE=4
QUIT=5
def main():
emails={}
with open('phonebook.in') as f:
for line in f:
(name, email)=line.split
emails[name]=email
choice=0
while choice !=QUIT:
choice= get_menu_choice()
if choice == LOOK_UP:
look_up(emails)
elif choice == ADD:
add(emails)
elif choice == CHANGE:
change(emails)
elif choice == DELETE:
delete(emails)
def get_menu_choice():
print('Enter 1 to look up an email address')
print('Enter 2 to add an email address')
print('Enter 3 to change an email address')
print('Enter 4 to delete an email address')
print('Enter 5 to Quit the program')
print()
choice= int(input('Enter your choice: '))
while choice <LOOK_UP or choice >QUIT:
choice= int(input('Enter a valid choice'))
return choice
def look_up(emails):
name= str(input('Enter a name: '))
value=(emails.get(name, 'Not found.'))
print(value)
print()
def add(emails):
name= str(input('Enter a name: '))
emailsaddy= input(' Enter a email address: ')
if name not in emails:
emails[name]= emailsaddy
print()
else:
print('That contact already exists')
print()
def change(emails):
name=str(input ('Enter a name: '))
if name in emails:
emailsaddy= str(input(' Enter a new email: '))
emails[name]= emailsaddy
else:
print('That contact does not exist')
def delete(emails):
name=str(input ('Enter a name: '))
if name in emails:
del emails[name]
else:
print('That contact is not found')
main()
Do something like this, every name line goes in if statement, and every email line goes in else and add to directory.
emails = {}
i = 0
with open('phonebook.in') as f:
for line in f:
if i == 0:
name = line
i = 1
else:
email = line
emails[name] = email
i = 0
with open('phonebook.in') as f:
# convert file into list
pb = f.readlines()
# pair off elements into (name, email) tuples, and construct a dict from them
emails = dict(zip(pb[0::2], pb[1::2]))
See this answer for an explanation, in case that idiom is hard to understand
Related
//this asked a fresh user for log in details and then appends it to the file
while choice == '1':
username = input('enter a name: ')
if username == '':
print ('user name cant be blank')
else:
print ('hello', username,'welcome to the quiz')
password = input('please enter a password that is 4 characters long: ')
while (len(password)) < 4:
password = input('please enter a password that is 4 characters long: ')
else:
f = open("logininfo", "a")
f.write('---------'+'\n')
f.write(username+'\n')
f.write(password+'\n')
f.write('---------'+'\n')
f.close()
print('welcome you may now begin')
choice=choice+choice+choice
//this is for when a user wants to log in and the system checks in the file for already inputted data
while choice == '2':
print ('enter your log in details')
username = input('username:')
password = input('password:')
if username in logininfo:
print ("That user already exsist")
else:
f = open('logininfo','r')
if username in ('logininfo'):
print('welcome')
else:
print ('no entry')
Try like this:
with open("logininfo", "r") as f:
all_text = f.read()
Now find the username in the variable string 'all_text' with if statement
I'm a python beginner I tried making a contact book program but this is the problem, I
want to add search-like feature so after I add a contact name, phone number, email and store
it to another file(contact.txt) I want to access it and print it via search.
example:
Name: Johan
Phone: 036902480157
Email: Johan#Email.com
I want to access all the information regarding Johan just by typing his contact name or his phone number, how I can do that?
note: I want to print the name, phone number, and email in each different line
Thanks in advance
my code
import os
def head():
print("")
print("========================")
print(" Contact Book ")
print("========================")
def restart():
response = input("\nOpen menu again? (yes/no): ").lower()
if response == "yes":
task()
else:
print("\nSee You next time!")
def task():
head()
done = False
print('''1. Add Contact
2. Search
3. View Contact List
4. Delete All Contact
5. Exit''')
while not done:
task = input("\nWhat do You want to do? (1-5):")
if task == "1":
print("\nAdding a new contact!")
with open('contact.txt', 'a') as f:
name = input("Name: ")
phone = input("Phone Number: ")
if not phone.isnumeric():
while not phone.isnumeric():
print("Invalid input, please enter only a number!")
phone = input("Phone Number: ")
email = input("Enter an email: ")
f.writelines(('\n',('=' * 15),'\nName: ',name,
'\nPhone: ',phone,'\nEmail: ',email,'\n',('=' * 15)))
print("\nContact is saved!")
done = True
restart()
elif task == "2":
with open('contact.txt', 'r') as f:
search = input("\nSearch: ")
for i in f:
if search in i:
print(i)
else:
print("\nNo info was found!")
done = True
restart()
elif task == "3":
if os.path.getsize('contact.txt') == 0:
print("\nNo contact info available!")
else:
with open('contact.txt', 'r') as f:
print("\nAll Contact Info")
for i in f:
print(i,end="")
done = True
restart()
elif task == "4":
with open('contact.txt', 'w') as f:
print("\nSuccesfully deleted all contact info!")
done = True
restart()
elif task == "5":
print("See You next time!")
break
else:
print("Invalid input please enter a single number from 1 to 5")
restart()
task()
Adding a contact and then searching for this contact prints:
Adding a new contact!
Name: mrd
Phone Number: 99
Enter an email: the#ff.com
Contact is saved!
...
What do You want to do? (1-5):2
Search: mrd
Name: mrd
No info was found!
which is inaccurate as you just fount the name. What you want to do is save all the contact info in the same line in the contacts.txt so when you search for a number or a name it will give you back that line and then you can print it as you want.
Alternatively you could hold an in memory dictionary that you persist on exit in a json as suggested and you load when you start your program
In answer to the comment
if task == "1":
print("\nAdding a new contact!")
# TODO make sure no commas in the input!
name = input("Name: ")
phone = input("Phone Number: ")
while not phone.isnumeric():
print("Invalid input, please enter only a number!")
phone = input("Phone Number: ")
email = input("Enter an email: ")
with open('contact.txt', 'a') as f:
f.write(','.join([name, phone, email]) + '\n')
print("\nContact is saved!")
done = True
restart()
elif task == "2":
search = input("\nSearch: ")
with open('contact.txt', 'r') as f:
for i in f:
if search in i:
for caption, data in zip(['Name:', 'Phone:', 'Email:'],
i.split(',')):
print(caption, data)
break # contact was found don't go to the else!
else:
print("\nNo info was found!")
done = True
restart()
(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.")
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.
In the final days of my intro comp sci class, we got to creating dictionaries. A homework program in our book asks us to create something that can look up, add, change, and delete a set of names and email addresses. It asks us to pickle the dictionary, but the kicker for me is that it stipulates that each time the program starts, it should retrieve the dictionary from the file and unpickle it. I don't know if I coded myself into a corner, but I can't figure out how to do this with what I've done so far.
My code:
import mMyUtils
import pickle
LOOK_UP = 1
ADD = 2
CHANGE = 3
DELETE = 4
QUIT = 5
def main():
emails = {}
choice = 0
while choice != QUIT:
choice = getMenuChoice()
if choice == LOOK_UP:
lookUp(emails)
elif choice == ADD:
add(emails)
elif choice == CHANGE:
change(emails)
elif choice == DELETE:
delete(emails)
else:
exit
def getMenuChoice():
print()
print('Name and Email Address Catalog')
print('------------------------------')
print('1. Look up an email address')
print('2. Add a new email address')
print('3. Change an email address')
print('4. Delete an email address')
print('5. Quit the program')
print()
choice = int(input('Enter the choice: '))
while choice < LOOK_UP or choice > QUIT:
choice = int(input('Enter a valid choice: '))
return choice
def lookUp(emails):
name = input('Enter a name: ')
print(emails.get(name, 'Not found.'))
def add(emails):
name = input('Enter a name: ')
address = input('Enter an email address: ')
if name not in emails:
emails[name] = address
pickle.dump(emails, open("emails.dat", "wb"))
else:
print('That entry already exists.')
def change(emails):
name = input('Enter a name: ')
if name in emails:
address = input('Enter the new address: ')
emails[name] = address
pickle.dump(emails, open("emails.dat", "wb"))
else:
print('That name is not found.')
def delete(emails):
name = input('Enter a name: ')
if name in emails:
del emails[name]
else:
print('That name is not found.')
main()
I know I should set my emails variable to be some form of pickle.load, but I can't figure it out for the life of me. mMyUtils is a library I made for try/except logic, I'll put that in once I get the new stuff working.
If you're saving the dictionary like so:
pickle.dump(emails, open('emails.dat', 'wb'))
The following will load it back:
emails = pickle.load(open('emails.dat', 'rb'))
You must load the file and unpickle the data before you can access it, change lookUp() to this:
def lookUp(emails):
with open("emails.dat", "rb") as fo:
emails = pickle.load(fo)
name = input('Enter a name: ')
print(emails.get(name, 'Not found.'))
Consider yourself using ast.literal_eval instead of pickle: http://docs.python.org/2/library/ast.html#ast.literal_eval
>>>import ast
>>> print mydict
{'bob': 1, 'danny': 3, 'alan': 2, 'carl': 40}
>>> string="{'bob': 1, 'danny': 3, 'alan': 2, 'carl': 40}"
>>> type(string)
<type 'str'>
>>> type( ast.literal_eval(string) )
<type 'dict'>
To save/read dict from file, you can do it like with normal string.
The problem was, and I guess I didn't emphasis it enough, was what I was supposed to do if the dictionary didn't exist in the first place. The design doc states that you should load the dictionary every time you run the program. Well if you're running the program for the first time, you don't have a dictionary to load, leading to an error. I got around this by basically doing the function twice using try/except.
My code:
import mMyUtils
import pickle
import dictionaryGenerator
LOOK_UP = 1
ADD = 2
CHANGE = 3
DELETE = 4
QUIT = 5
def main():
hasError = False
try:
emails = pickle.load(open('emails.dat', 'rb'))
choice = 0
while choice != QUIT:
choice = getMenuChoice()
if choice == LOOK_UP:
lookUp(emails)
elif choice == ADD:
add(emails)
elif choice == CHANGE:
change(emails)
elif choice == DELETE:
delete(emails)
else:
print("Good-bye!")
exit
except Exception as err:
hasError = True
mMyUtils.printError("Error: no such file",err)
mMyUtils.writeToErrorLog()
finally:
if hasError:
emails = {}
choice = 0
while choice != QUIT:
choice = getMenuChoice()
if choice == LOOK_UP:
lookUp(emails)
elif choice == ADD:
add(emails)
elif choice == CHANGE:
change(emails)
elif choice == DELETE:
delete(emails)
else:
print("Good-bye!")
exit
def getMenuChoice():
print()
print('Name and Email Address Catalog')
print('------------------------------')
print('1. Look up an email address')
print('2. Add a new email address')
print('3. Change an email address')
print('4. Delete an email address')
print('5. Quit the program')
print()
choice = int(input('Enter the choice: '))
while choice < LOOK_UP or choice > QUIT:
choice = int(input('Enter a valid choice: '))
return choice
def lookUp(emails):
name = input('Enter a name: ')
print(emails.get(name, 'Not found.'))
def add(emails):
name = input('Enter a name: ')
address = input('Enter an email address: ')
if name not in emails:
emails[name] = address
with open("emails.dat", "wb") as infile:
pickle.dump(emails, infile)
else:
print('That entry already exists.')
def change(emails):
name = input('Enter a name: ')
if name in emails:
address = input('Enter the new address: ')
emails[name] = address
with open("emails.dat", "wb") as infile:
pickle.dump(emails, infile)
else:
print('That name is not found.')
def delete(emails):
name = input('Enter a name: ')
if name in emails:
del emails[name]
else:
print('That name is not found.')
main()