update dictionary and compare to new items - python

Ok so I am completely lost for this problem, please help me. I have already created a function that takes in a text file and sorts all the names into the text file, puts them in a dictionary. So my new dictionary looks like this:
namesDict = {'J': ['Jacob', 'Joshua'], 'T': ['Tyler'], 'A': ['Austin'], 'B': ['Brandon'], 'D': ['Daniel'], 'M': ['Michael', 'Matthew'], 'C': ['Christopher'], 'N': ['Nicholas']}
now I have to take in this dictionary I created and add new names. The new function has to do this
The function will ask the user to input their name. Assume the user will enter names with a capital first letter, and all lowercase letters after that.
If their name is already in the dictionary, print “[name] is already in the dictionary”, and then return the same dictionary.
If their name is not already in the dictionary, then you will add their name to the dictionary under the appropriate key, print “[name] added to dictionary”, and then return the updated dictionary.
If their name is not already in the dictionary AND the first letter of their name is not already a key in the dictionary, then you will add the first letter of their name as a key, with a list containing their name as the value. You will then print “[name] added to dictionary”, and return the updated dictionary.
so I have this so far which of course is not complete:
def updateDictionary(namesDict):
newname= input('What is your name?')
if newname = key:
print(newname'is already in the dictionary')
elif newname != key:
print (newname 'added to dictionary')
elif newname = key[0]:
print (newname 'added to dictionary')
also my first code to create the dictionary from the text file is this:
def newDictionary():
names={}
file = open('file.txt','r')
lines = file.read().split('\n')
if len(lines) == 1 and len(lines[0]) == 0:
print('empty file')
else:
for line in lines:
if line in names:
names[(line[0])].append(line)
else:
names[(line[0])] = [line,]
return names
but i am having an error in this code which says names[(line[0])] = [line,]
IndexError: string index out of range.
PLEASE PLEASE help me out. I don't know how to take in the new input name and put it in the dictionary.
Thank you

If you are getting IndexError for this line:
[(line[0])] = [line,]
it means that there is no first (line[0]) character in the line - in other words, the line is blank. So you need to ignore blank lines
updating the dictionary can be done as follows:
def updateDictionary(namesDict):
newname = input('What is your name?')
key = newname[0]
if key not in namesDict:
namesDict[key] = []
item = namesDict[key]
if newname in item:
print(newname, 'is already in the dictionary')
else:
item.append(newname)
print(newname, 'added to dictionary')
return namesDict

Problem:
Your newDictionary() cannot produce the dictionary because probably there is an empty line in your file.
Solution:
collections.defaultdict will make things easier:
from collections import defaultdict
def newDictionary():
names = defaultdict(list)
with open('file.txt','r') as f:
for line in f:
line = line.strip()
if line:
names[line[0]].append(line)
return names

Related

How do I take a dictionary from one function and use it in another in python?

Edit: changing code as the issue came up first somewhere else in my code
I'm trying to figure out how to use my dictionary from one function in another one and the other answers on here haven't helped.
The overall goal is to print the key and value just entered into the dictionary named contacts but contacts can only be defined inside init_phonebook
def init_phonebook():
contacts = {}
while True:
choice = print_menu()
if choice == 1:
list_contacts(contacts)
elif choice == 2:
add_contact(contacts)
elif choice == 3:
find_contact(contacts)
elif choice == 4:
edit_contact(contacts)
elif choice == 5:
delete_contact(contacts)
elif choice == 6:
delete_all(contacts)
elif choice == 7:
thanks()
Down here the issue is that .keys and .values don't work as it's not recognizing contacts as a dictionary. I've tried changing the parameter to something else but it doesn't work that way either.
def add_contact(contacts):
phone_number = input('Please enter a phone number: ')
name = input('What would you like to save the name as?: ')
if name in contacts:
print('This contact already exists in your phonebook')
elif name not in contacts:
contacts[name] = phone_number
print('Contact successfully saved')
print('Your updated phonebook is shown below')
for c in contacts:
print('{} --> {}'.format(contacts.keys(c), contacts.values(c)))
print()
the error message I get is:
File "c:\Users\myname\Desktop\VS Code Projects\contact_list.py", line 54, in add_contact
print('{} --> {}'.format(contacts.keys(c), contacts.values(c)))
TypeError: dict.keys() takes no arguments (1 given)
The problem is not how you go about passing the dictionary to these other functions.The error actually arising within your add_contact() function, due to how you are trying to iterate through the dictionary key-val pairs:
for c in contacts:
print('{} --> {}'.format(contacts.keys(c), contacts.values(c)))
It seems you want to iterate through the contacts. contact.keys() does not let you access/index a key, this method returns all of the keys in a dict. contact.values does not let you access/index a value, it returns all of the values in the dict. When you call "for c in contacts", c represents a key. So here are two alternative ways to iterate through:
Properly indexing on the contacts dict using the key c:
for c in contacts:
print('{} --> {}'.format(c, contacts[c]))
By iterating through both the key and value pairs:
for key,value in contacts.items():
print('{} --> {}'.format(key, value))
If confused about a type in Python, I recommend referring to the documentation!
dict.keys() and dict.values() both return arrays that can be indexed but accepts no inputs when called.
But in your case, since you are looping over the dictionary, each iteration stores the key in c. In your case that will be the name associated with the contact.
So you already have the key stored in c on each iteration. What you need next is to use the key to get the value like so dict[key] or dict.get(key).
Alternatively, you can loop over both keys and values simultaneously like so:
for name, phone_number in contacts:
print("{} ==> {}".format(name, phone_number))
I am altering your original code as follows:
def add_contact(contacts):
phone_number = input('Please enter a phone number: ')
name = input('What would you like to save the name as?: ')
if name in contacts:
print('This contact already exists in your phonebook')
else: #You seem to have only two options so no need for elif
contacts[name] = phone_number
print('Contact successfully saved')
print('Your updated phonebook is shown below')
for c in contacts: #c will hold name in each iteration
print('{} --> {}'.format(c, contacts[c]))

How to pass one variable/dictionary between two functions in Python

I want to pass a dictionary between two functions, but how to do this without using a global variable?
I'm trying to pass the dictionary that is in my "fileProcessing" function into the "swappingKandV_PrintingResults" function without having a global variable being modified.
dictionary = dict()
fileinputname = input("Please Input File Name: ")
try:
filehandling = open(fileinputname)
except:
print("Invalid Entry")
quit()
rawfile = filehandling.readlines()
def fileProcessing(rawfile):
for iteration in(range(len(rawfile))):
rawfile[iteration] = rawfile[iteration].lower()
for line in rawfile:
line.rstrip()
line.split()
for words in line:
letter = words.split()
for iteration in letter:
if iteration.isalpha() :
dictionary[iteration] = dictionary.get(iteration, 0) + 1
def swappingKandV_PrintingResults(dictionary):
finalresults = []
for (k,v) in dictionary.items():
newtuple = (v, k)
finalresults.append(newtuple)
finalresults = sorted(finalresults, reverse=True)
for iteration in finalresults:
print(iteration)
fileProcessing(rawfile)
swappingKandV_PrintingResults(dictionary)
By making the first function create and return the dictionary. Then pass that returned dictionary to the second function.
fileinputname = input("Please Input File Name: ")
try:
filehandling = open(fileinputname)
except:
print("Invalid Entry")
quit()
rawfile = filehandling.readlines()
def fileProcessing(rawfile):
dictionary = {}
for iteration in(range(len(rawfile))):
rawfile[iteration] = rawfile[iteration].lower()
for line in rawfile:
line.rstrip()
line.split()
for words in line:
letter = words.split()
for iteration in letter:
if iteration.isalpha() :
dictionary[iteration] = dictionary.get(iteration, 0) + 1
return dictionary
def swappingKandV_PrintingResults(dictionary):
finalresults = []
for (k,v) in dictionary.items():
newtuple = (v, k)
finalresults.append(newtuple)
finalresults = sorted(finalresults, reverse=True)
for iteration in finalresults:
print(iteration)
swappingKandV_PrintingResults(fileProcessing(rawfile))
From the way you phrased the question, it seems you have some confusion on how to work with passing arguments to functions and how to handle scope. I would suggest having at look at what a variable is in Python to begin with and then what passing it to a function means.
You can accomplish this task in 2 ways:
1. Nested Function Call :
If you want to necessarily call 2nd function after 1st, just write -
'swappingKandV_PrintingResults(dictionary)' as the ending line in the fileProcessing function.
2. Accepting Return from 1st and Passing as Argument to 2nd :
As insisted by #Reti43 too, just write -
'return dictionary' as the ending line in the fileProcessing function and replace your last 2 lines of code by -
Dict = fileProcessing(rawfile)
swappingKandV_PrintingResults(Dict)

Python- Update txt file every time data appended to print

Currently I'm doing my first project which consists on a program for restaurants.
To log in as a waiter/tres you insert your name and is added to a TXT file.
My problem is that in the code when I print the TXT file to see the users that signed in it won't show the updated list if not the original list.
snames = list()
f_n = (open('names.txt')).read()
print("Welcome to NAME.app")
try:
while True:
name = input("Please select waiter/tress NAME - ADD to save new name - LIST to see saved names:")
if name.lower() == "add":
n_input = input("Name:")
with open('names.txt', 'a') as f:
f.write(n_input + '\n')
continue
elif name.lower() == "list":
print(f_n.split())
elif name == snames:
print("Logged as", name)#doubtful line. print name of list.
elif name == "exit":
exit()
except:
print("Invalid input")
In the second ELIF is what I wrote to see saved names(users).
But as I said prints the TXT file without including what I added in the first IF.
This might help.
OUTPUT
Welcome to NAME.app
Please select waiter/tress NAME - ADD to save new name - LIST to see saved names:add
Name:Python
Please select waiter/tress NAME - ADD to save new name - LIST to see saved names:list
['Ale', 'Sarah', 'Annette', 'Dan']
Please select waiter/tress NAME - ADD to save new name - LIST to see saved names:
Appreciate recommendations and solutions.
thank you very much.
In the first line you read all the names, only after that you added more names, so the f_n variable doesn't get updated.
Change the "list" option to this
elif name.lower() == "list":
with open('names.txt') as f:
print(f.read().splitlines())
This will make sure to read the updated list each time you choose this option

How to make search input case insensitive for txt file

Right now the code is working but if I don't capitalize the first letter of both first and last name the code will return "error: person not found."
How can I set it up so that no matter how the user inputs the search it will return the requested data?
#Iterate through the lines and save them in a dictionary, with the
#full name as the key
for line in file:
stripped = line.strip()
name = stripped[:stripped.index(',')]
d[name] = stripped[stripped.index(',')+1:].strip()
def main():
#call the input function to read the file
addresses = input_address()
#Get the user option
option = int(input("Lookup (1) phone numbers or (2) addresses: "))
if option == 1:
phone = True
else:
phone = False
#Ask for names and print their information in case they exist, end on blank entry
while True:
name = input("Enter space-separated first and last name: ")
if name == "":
return main()
if name not in addresses:
print("Error: person not found")
else:
display(addresses[name], phone)
main()
Try using:
.capitalize()
For example:
'hello world'.capitalize()
yields,
'Hello World'
So in your case, you would do:
name.capitalize()
then look for it inside addresses.
You can use lower(), upper(), or capitalize(), as long as you attach the chosen method to end of both variables.
Using lower():
for i in range(len(addresses)):
addresses[i] = addresses[i].lower() # Converting array values to lowercase
if name.lower() not in addresses: # Seeing if lowercase variable is in lowercase array
print("Error: person not found")
else:
print("Person found")

Repeating input to dictionary loop

"Create a dictionary whose keys are names and whose value for a key is a favorite food of the person with that name as follows:
- The program should prompt for a name and favorite food and keep inputting names and favorite foods until the user enters an empty string for the name."
So far I have:
mydict=dict()
def favorite_food_name():
name=input(str("name:"))
food=input(str("food:"))
mydict[name]=food
print(mydict)
favorite_food_name()
But I can't get the code to repeat in any kind of loop. What kind of loop would you use?
Use While True loop, and test value of name after its input.
By the way, some tips when coding:
you do not need str("name:"), since "name:" is str
if not necessary, put mydict in the function part, use return statement, do not use it as model level
you can do more to validate the input, here I call a strip function to remove typo of input.
Here is a sample code:
def favorite_food_name():
mydict = dict()
while True:
name = input("name:")
name = name.strip()
if name == '':
break
food = input("food:")
food = food.strip()
mydict[name] = food
# print(mydict)
return mydict
if __name__ == '__main__':
mydict = favorite_food_name()
print(mydict)

Categories