How to read from dictionary that has no key in python? - python

this is a follow up from my previous question where I am working on multiple dictionary and having trouble with them. I have currently have a main dictionary where I store my data and one blank dictionary where I add data into.
Dairy_goods = {1:{'item':'Milk','p':2.47,'g':0.16,'offer':'Yes'},
2:{'item':'Butter','p':4.50,'g':0.32,'offer':'No'},
3:{'item':'Egg','p':3.40,'g':0.24,'offer':'No'}}
shopping_basket={}
Lets say for example I would like to add the item "Milk" into the blank shopping basket, i would do as below.
choose=int(input('1.Item= Milk, Price= $2.47, GST= $0.16, Offer=Yes\n'
'2.item= Butter, Price= $4.50, GST= $0.32, Offer=No\n'
'3.Item= Egg, Price= $4.50, GST= $0.32, Ofer=No\n'
'Enter your option: '))
qnty=int(input('How many do you want?: '))
shopping_basket[Dairy_goods[choose]['item']] = shopping_basket.get(Dairy_goods[choose]['item'], 0) + qnty,Dairy_goods[choose]['p'],Dairy_goods[choose]['g'],Dairy_goods[choose]['offer']
I would get an output as below.
print(shopping_basket)
{'Milk': (2, 2.47, 0.16, 'Yes')}
Now I would like to edit the values inside of this new dictionary, how do I go about doing so? As it has no fix key? I am aware it it is in a tupple and can convert to a list but will still give a error as shown below.
for item in shopping_basket:
item = str(input('key in an item to edit: '))
for item in shopping_basket:
shopping=list(shopping_basket)
qnty = int(input('Key in the quantity of %s you want: ' % item))
shopping[item][0] = qnty # i would get a error here.
print(shopping)
Let me know if more clarifications is needed, thank you in advance.

There are a few things off in your code in terms of data structures. First, a dictionary with incrementing keys {1: ..., 2: ..., ...} is basically the same as a list, so you can just as well use the simpler data structure and select items by indexing. The only thing to note here is that list indices start at 0, so you need to subtract 1 from your user's choice.
Dairy_goods = [{'item':'Milk','p':2.47,'g':0.16,'offer':'Yes'},
{'item':'Butter','p':4.50,'g':0.32,'offer':'No'},
{'item':'Egg','p':3.40,'g':0.24,'offer':'No'}]
choose = int(input('1.Item = ... ')) - 1 # subtract 1 to get 0-indexing
qnty = int(input('How many do you want?: '))
Next up, there is a lot going on in the line shopping_basket[Dairy_goods[choose]['item']] = ..., which makes it hard to work with. In my comment, I suggested to go for dictionaries to store the items in the shopping basket to make them easier to modify. The new format of the basket would look like
# shopping_basket
{'Milk':{'item':'Milk','p':2.47,'g':0.16,'offer':'Yes', 'qnty':1}}
which is a bit redundant because of the double item name (as key and within values), which is normally considered a bad thing, but in this case it allows for a much easier access to the shopping cart items.
However, it's actually sufficient to store only the quantities in the shopping basket - {'Milk':1, 'Egg':2, ...} - because all the other information is in Dairy_goods.
selection = Dairy_goods[choose] # e.g., {'item':'Milk','p':2.47,'g':0.16,'offer':'Yes'}
item = selection['item'] # e.g., 'Milk'
shopping_basket[item] = shopping_basket.get(item, 0) + qnty
# optional: delete item if the quantity is <= 0
if shopping_basket[item]['qnty'] <= 0:
shopping_basket.pop(item)
Then, the edit part becomes:
item = input('key in an item to edit: ') # e.g., 'Milk'
qnty = int(input(f'Key in the quantity of {item} you want: ')) # did you hear about f-strings? Super useful!
shopping_basket[item] = qnty # set the new quantity

I have your answer!
But first I want to address a major problem in your code:
for shopItem in shopping_basket:
item = str(input('key in an item to edit: '))
for item in shopping_basket: # unneeded
shopping=list(shopping_basket)
qnty = int(input('Key in the quantity of %s you want: ' % shopItem))
shopping[shopItem][0] = qnty # i would get a error here.
print(shopping)`
That internal for loop can be easily remove to get cleaner code.
for shopItem in shopping_basket:
item = str(input('key in an item to edit: '))
shopping=list(shopping_basket)
qnty = int(input('Key in the quantity of %s you want: ' % shopItem))
shopping[shopItem][0] = qnty # i would get a error here.
print(shopping)`
Now for the actual problem:
for shopItem in shopping_basket:
item = str(input('key in an item to edit: '))
shopping = list(shopping_basket[shopItem])
qnty = int(input('Key in the quantity of %s you want: ' % shopItem))
shopping[item] = qnty # Fixed
Originally with this line of code
shopping=list(shopping_basket) you were changing {'Milk': (2, 2.47, 0.16, 'Yes')} to ['Milk'], and then attempting to change a letter in the word milk, which was throwing an error. I fixed that by changing shopping[item][0] to shopping[item].
Have a great day and good luck with your code!

Related

How to delete items from a list using index on Python?

I have been studying Python and trying to create a simple telephone book. However, I can't solve how to delete an item by using an index. Here is the code that doesn't work:
number = 1
while number < len(book):
for x in book:
print("{}) NAME: {} NUMBER: {} ".format(number,x,book[x]))
number = number + 1
delete = input("Insert the number you want to delete\n")
delete = int(delete)
book.pop(delete - 1)
This code can successfully list all of the contact information in the phone book, but I cannot find any way to delete the items. I think it'd be impractical to insert the name of the person whom you want to delete.
Is there any alternative that I can do? Thank you so much.
Asuming book is a list, you can delete elements
by index with del book[index]
by element reference with book.remove(delete)
If I understood correctly what you want to do:
book=[("NAME1",2313),("NAME2",65345313),("NAME3",1112313),("NAME4",151377)]
while book:
for x in range(len(book)):
print("{}) NAME: {} NUMBER: {} ".format(x,book[x][0],book[x][1]))
book.pop(int(input("Insert the number you want to delete:")))

How to match input with elements in list/dictionary in Python3

I'm very new at coding, and I'm trying to create a shop list with items and prices on it.
That is, once typed in all the items, the function should calculate the sum and stop the moment you exceed the budget.
So I wrote something like:
def shoplist():
list={"apple":30, "orange":20, "milk":60......}
buy=str(input("What do you want to purchase?")
If buy in list:
While sum<=budget:
sum=sum+??
shoplist ()
I really don't know how to match the input of an item with the price in the list...
My first thought is to use 'if', but it's kinda impractical when you have more than 10 items on the list and random inputs.
I'm in desperate need of help....So any suggestions would be nice!! (or if you have a better solution and think me writing it this way is complete garbage... PLEASE let me know what those better solutions are😭😭😭
The code you post will not run in python. list is a builtin and should not be used for a variable name, and is doubly confusing since it refers to a dict object here. input() already returns a str so the cast has no effect. if and while should be lowercase, and there is no indentation, so we have no way of knowing the limits of those statements.
There are so many things wrong, take a look at this:
def shoplist(budget):
prices = {"apple":30, "orange":20, "milk":60}
# Initialise sum
sum = 0
while sum <= budget:
buy = input("What do you want to purchase?")
# Break out of the loop if the user hts <RETURN>
if not buy: break
if buy in prices:
sum += prices[buy] # This gets the price
else:
print("Invalid item", buy)
shoplist(142)
So what have I changed? The budget has to come from somewhere, so I pass it in as a parameter (142, I made that up). I initialise the sum to zero, and I moved the while loop to the outside.
Notice as well lots of whitespace - it makes the code easier to read and has no effect on performance.
Lots of improvements to make. The user should be shown a list of possible items and prices and also how much budget there is left for each purchase. Note as well that it is possible to go over budget since we might only have 30 in the budget but we can still buy milk (which is 60) - we need another check (if statement) in there!
I'll leave the improvements to you. Have fun!
Take a look at this as an example:
# this is a dictionary not a list
# be careful not using python reserved names as variable names
groceries = {
"apple":30,
"orange":20,
"milk":60
}
expenses = 0
budget = 100
cart = []
# while statements, as well as if statements are in lower letter
while expenses < budget:
# input always returns str, no need to cast
user_input = input("What do you want to purchase?")
if user_input not in groceries.keys():
print(f'{user_input} is not available!')
continue
if groceries[user_input] > budget - expenses:
print('You do not have enough budget to buy this')
user_input = input("Are you done shopping?Type 'y' if you are.")
if user_input == 'y':
break
continue
cart.append(user_input)
# this is how you add a number to anotherone
expenses += groceries[user_input]
print("Shopping cart full. You bought {} items and have {} left in your budget.".format(len(cart), budget-expenses))
I've made some changes to your code to make it work, with explanation including using comments indicated by the # symbol.
The two most important things are that all parentheses need to be closed:
fun((x, y) # broken
fun((x, y)) # not broken
and keywords in Python are all lowercase:
if, while, for, not # will work
If, While, For, Not # won't work
You might be confused by True and False, which probably should be lowercase. They've been that way so long that it's too late to change them now.
budget = 100 # You need to initialize variables before using them.
def shoplist():
prices = { # I re-named the price list from list to prices
'apple' : 30, # because list is a reserved keyword. You should only
'orange' : 20, # use the list keyword to initialize list objects.
'milk' : 60, # This type of object is called a dictionary.
} # The dots .... would have caused an error.
# In most programming languages, you need to close all braces ().
# I've renamed buy to item to make it clearer what that variable represents.
item = input('What do you want to purchase? ')
# Also, you don't need to cast the value of input to str;
# it's already a str.
if item in prices:
# If you need an int, you do have to cast from string to int.
count = int(input('How many? '))
cost = count*prices[item] # Access dictionary items using [].
if cost > budget:
print('You can\'t afford that many!')
else:
# You can put data into strings using the % symbol like so:
print('That\'ll be %i.' % cost) # Here %i indicates an int.
else:
print('We don\'t have %s in stock.' % item) # Here %s means str.
shoplist()
A lot of beginners post broken code on StackOverflow without saying that they're getting errors or what those errors are. It's always helpful to post the error messages. Let me know if you have more questions.

python 3 position change in a list with user input

Okay, so I'm kind of lost here. I understand how to insert a value into the code myself [Example - x.insert(2, 99)] but what I'm getting hung up on is what happens if I'm trying to get the user to tell me where they want the item to be in regards to position in the list.
Example
inventory = [dagger, sword, shield, breastplate, helmet]
this is what I have and I know it doesn't work.
def edit_it():
inventory = ["orb", "staff", "spellbook", "hat", "potion", "robe"]
inventory[item] = input("Number: ")
print(inventory)
I just want it to show an updated position list if the user wanted to move say, the spellbook to the front, thus pushing back all other items. I've been at this all day and I'm spent. Help?
After reading the item and new index for the item as a number, find it in the list, pop it, and insert it into the list at that index.
def edit_it():
inventory = ["orb", "staff", "spellbook", "hat", "potion", "robe"]
item = input("Which item do you want to move? ")
new_index = int(input("Number: "))
inventory.insert(new_index, inventory.pop(inventory.index(item)))
print(inventory)
How about something like this:
item= int(input("Number: "))
inventory.insert(0,inventory.pop(item))
*This works on python 2, and python 3

Auto append list items in dictionary with default values python

I am trying to create an attendance logger where I create a dictionary which I fill with student names. The names will be lists where I append their class attendance data (whether they attended class or not). The code I have so far is displayed below`
#! /bin/python3
#add student to dict
def add_student(_dict):
student=input('Add student :')
_dict[student]=[]
return _dict
#collect outcomes
def collector(student,_dict, outcome):
_dict[student].append(outcome)
return _dict
#counts target
def count(_dict,target):
for i in _dict:
# records total attendance names
attendance_stat = len(_dict[i])
# records total instances absent
freq_of_absence=_dict[i].count(target)
# records percentage of absence
perc_absence = float((freq_of_absence/attendance_stat)*100)
print(i,'DAYS ABSENT =',freq_of_absence)
print('TOTAL DAYS: ', i, attendance_stat)
print('PERCENTAGE OF ABSENCE:', i, str(round(perc_absence, 2))+'%')
#main function
def main():
#date=input('DATE: ')
outcomes=['Y','N']
student_names = {}
try:
totalstudents = int(input('NO. OF STUDENTS: '))
except ValueError:
print('input an integer')
totalstudents = int(input('NO. OF STUDENTS: '))
while len(student_names) < totalstudents:
add_student(student_names)
print(student_names)
i = 0
while i < totalstudents:
i = i + 1
target='Y'
student=str(input('student :'))
outcome=str(input('outcome :'))
collector(student,student_names,outcome)
count(student_names,target)
if __name__=='__main__':
main()
`
The code works well so far but the problem is when the number of students is too large, time taken to input is extensive cutting in on class time. Since the number of absentees is usually less than those present, is it possible to select from the dictionary students absent which will append the value Y for each selected absent, while appending N to the remaining lists in dictionary.
This isn't exactly what you're asking for, but I think it will help. Instead of asking the user to input a name each time for the second part, why not just print the name yourself, and only ask for the outcome? Your last while loop would then become a for loop instead, like this:
for student_name in student_names:
outcome = input("Outcome for {}: ".format(sudent_name))
collector(student_name, student_names, outcome)
You could also add some logic to check if outcome is an empty string, and if so, set it to 'N'. This would just allow you to hit enter for most of the names, and only have to type in 'Y' for the certain ones that are absent. That would look like this:
for student_name in student_names:
outcome = input("Outcome for {}: ".format(sudent_name))
if outcome = "":
outcome = "N"
collector(student_name, student_names, outcome)

How to find and print out of a specific value from a list (at least i think thats what i want to do?)

if n == 0:
print('And your products are: ')
for i in inputs:
with open('items.txt') as f:
for line in f:
if i in line:
desc1 = line[9:17]
price1 = line[21:25]
print(str(desc1) + ' ' +str(price1) + ' ' + str(quantities))
There is no error when running the code. When run, it outputs:
Our available products are:
15372185 ChocBisc
13281038 AppJuice
26419633 TomaSoup
74283187 SprRolls
Enter the product code: 74283187
SprRolls
Price = 0.90
Available Quantity = 86
Is this what you want? (Y/N) y
How much would you like? 34
Would you like to continue? (Y/N) y
Continuing!
Enter the product code: 15372185
ChocBisc
Price = 1.20
Available Quantity = 50
Is this what you want? (Y/N) y
How much would you like? 45
Would you like to continue? (Y/N) n
System Closing!
And your products are:
SprRolls 0.90 [34, 45]
ChocBisc 1.20 [34, 45]
As you can see, right at the bottom, it prints both quantities entered. I knew it was going to do this but i dont know how to rectify it. What i need it to do is to print only the quantity entered for that product code. Any help as always would be greatly appreciated. Thank you!!
Also i removed most of the script under while n == 1 since this is my coursework, and i would rather it didn't get copied or anything like that. Hopefully this still shows the relevant section of the code to the question.
I would re-write the latter part of your code to iterate through the range of values in inputs, rather than the values themselves. Then, you can call the index of the element you want to print from quantities.
As a caveat, this works in your case because the user send inputs to inputs one at a time (so, the indices of inputs correspond with the indices of quantities). You might consider a different data structure to use within this code, like a dictionary, which could store product codes and quantities as key/value pairs. Then, you can simply refer to the key of the dictionary when printing.
Here is how I would suggest changing your code:
if n == 0:
print('And your products are: ')
for i in range(len(inputs)):
with open('items.txt') as f:
for line in f:
if inputs[i] in line:
desc1 = line[9:17]
price1 = line[21:25]
print(str(desc1) + ' ' +str(price1) + ' ' + str(quantities[i]))
You're creating a new list for the quantities so at the end where you print out this list you can append it to print out only the product code of that item. Understand? I'll post the code in a little bit if I can.
You can use enumerate. For example:
for index, i in enumerate(inputs):
print(index, i)
That should print out
0, 74283187
1, 15372185
Getting the quantities is trivial: quantities[index]

Categories

Resources