Updating and clearing dictionaries in Python - python

so I have a question regarding dictionaries in Python.
I'd like to create a dictionary where the user will be prompted with 2 options; either updating the dictionary or clearing the dictionary.
Let me first show you my code:
def myStuff():
food = {'Apple': 0, 'Banana': 0, 'Grapes': 0}
choice = raw_input('Please pick an option:\n1) Update number of food I have\n2) Clear all\n>>')
if choice == str(1):
apple = int(raw_input('How many apples do you want to add?\n>>'))
banana = int(raw_input('How many bananas do you want to add?\n>>'))
grapes = int(raw_input('How many grapes do you want to add?\n>>'))
print 'Updating...'
food['Apple'] = apple
food['Banana'] = banana
food['Grapes'] = grapes
print food
elif choice == str(2):
food['Apple'] = 0
food['Banana'] = 0
food['Grapes'] = 0
print food
else:
return False
myStuff()
Now here's what I'd like to add:
1.The ability for the user to keep updating the dictionary (which means that if someone input 10 apples, the dictionary will store 10 apples and the user will be prompted again to input the number of apples he want to input to update the dictionary).
I'm not really sure how to implement a loop into this.
2, The ability for the user to clear his dictionary after updating it. For example: if someone inputs 10 apples, the loop will ask the user again if he/she would like to clear the dictionary.
It's kind of like a bank where someone deposits money and clears their account if they don't have any money left in there account.

With what you are doing, it might be better to create your own class. You should also have different functions for all of the different actions you wish to do. ie. Update, Clear, Add
class Fruit:
Apple = 0
Banana = 0
Grape = 0
def __repr__(self):
return "You have {self.Apple} apples, {self.Banana} bananas, and {self.Grape} grapes".format(**locals())
def update(self):
while 1:
choice = raw_input('Please pick an option:\n1) Update number of food I have\n2) Clear all\n>>')
if (int(choice) == 1):
self.Add()
elif (int(choice) == 2):
self.Clear()
else:
print "Input not valid"
def Add(self):
self.Apple += int(raw_input('How many apples do you want to add?\n>>'))
self.Banana += int(raw_input('How many bananas do you want to add?\n>>'))
self.Grape += int(raw_input('How many grapes do you want to add?\n>>'))
print self
def Clear(self):
self.Apple = 0
self.Banana = 0
self.Grape = 0
print self
if __name__ == "__main__":
fruit = Fruit()
fruit.update()
You should also look in to using try and except statements to make sure the program does not crash if the wrong input is used. Also you should add in an exit command to exit the program, otherwise this will loop forever. for example. if the user input is "exit" then have a conditional notice it and break.

You can do that this way:
"""
in each loop check the fruit number to see if it is 0 or not.if it
is 0, then this means that you don't want to add fruit from the current
type and skips to the nextFruit.Focus on the code and you realize the other parts.
"""
import string
def myStuff():
food = {'Apples': 0, 'Bananas': 0, 'Grapes': 0}
choice = raw_input('Please pick an option:\n1) Update number of food I have\n2) Clear all\n>>')
fruit = 0
nextFruit = 'Apples'
while True:
if choice == str(1):
fruit = int(raw_input('How many ' + str.lower(nextFruit) + ' do you want to add?\n>>'))
if fruit == 0 and nextFruit == 'Apples':
nextFruit = 'Bananas'
continue
elif fruit == 0 and nextFruit == 'Bananas':
nextFruit = 'Grapes'
continue
elif fruit == 0 and nextFruit == 'Grapes':
print 'Updating...'
print food
choice = raw_input('Please pick an option:\n1) Update number of food I have\n2) Clear all\n>>')
else:
food[nextFruit] += fruit
elif choice == str(2):
food['Apples'] = 0
food['Bananas'] = 0
food['Grapes'] = 0
print 'Updating...'
print food
choice = raw_input('Please pick an option:\n1) Update number of food I have\n2) Clear all\n>>')
else:
print "You've entered a wrong number....try again please:"
print
choice = raw_input('Please pick an option:\n1) Update number of food I have\n2) Clear all\n>>')

For updating in a loop, maybe try something like:
for key in food:
food[key] += int(raw_input('How many %s do you want to add?> ' % key) or 0)
You are already clearing the dictionary by setting the values to zero.

If I understand correctly - you want to keep asking this question repeatedly? In that case, all you need to do is put while True: and indent the block of code you want to repeat, and it will loop through that forever. You probably want to have it from the raw_input (just input in Python 3) to just after the elif - or, if you make food a global variable (so that it doesn't get re-initialised to 0 every time myStuff() is called), you can just do:
while True:
myStuff()

Related

What is the error in the following program with the help of split() function?

This program is based on separating the items given by the user in sentence form and add it to a list using split() method.
total_list = []
billed_list = []
class Naveen:
question = input('what would you like to buy : ')
def shopping_cart(self,items):
items = question.split()
for item in items:
print(item)
def billed_items(self):
for item in items:
ask = input('do u really want '+ item+' ')
if ask == 'yes':
billed_list.append(item)
if ask == 'no':
pass
print(billed_list)
items = []
spacex = Naveen()
spacex.shopping_cart(items)
Without any indication of what your program should do, it's not obvious that there are any bugs. But if we assume that your program is a very basic shopping cart, it has the following problems;
The I/O should probably be handled outside the class;
The question should not be a class global;
The handling of inputs other than "yes" or "no" should be defined -- either regard everything which isn't "yes" as "no" (this is what your code currently does, but by the looks of it, by mistake), or loop until you have received either "yes" or "no" response.
The items handled in the shopping cart should be encapsulated into the instance, not global variables.
Probably try to give the class a descriptive name, rather than a random one.
So, perhaps something like this;
class ShoppingCart:
def __init__(self):
self.items = []
def shopping_cart(self, request):
self.items = request.split()
def billed_items(self):
billed = []
for item in self.items:
ask = input('Do you really want '+ item+'? ')
if ask == 'yes':
billed.append(item)
return billed
spacex = ShoppingCart()
spacex.shopping_cart(input("What would you like to buy? "))
to_pay = spacex.billed_list()
split() out of the box splits on whitespace, so you would input items in the form
carrot carrot turnip pepper
to produce the items list ['carrot', 'carrot', 'turnip', 'pepper']
Add self in front of question and you need to use seperator inside split() function.
Please check this solution code:
total_list = []
billed_list = []
class Naveen:
question = input('what would you like to buy : ')
def shopping_cart(self,items):
for item in items:
total_list.append(item)
print("Total List:", total_list)
def billed_items(self, items):
for item in items:
ask = input('do u really want '+ item+': ')
if ask == 'yes':
billed_list.append(item)
if ask == 'no':
pass
print("Billed List:", billed_list)
items = []
spacex = Naveen()
items = spacex.question.split(',')
spacex.shopping_cart(items)
spacex.billed_items(items)
Sample Input & Output:
what would you like to buy : Apple,Malta
Total List: ['Apple', 'Malta']
do u really want Apple: yes
do u really want Malta: no
Billed List: ['Apple']

str reset to 0 when not asked to?

I am trying to print the total of the shopping list but every time i call on the string it prints 0 instead of what it should be.
cash_due = 0
import pickle
picklee = open('Store_stuff.pickle', 'rb')
contents = pickle.load(picklee)
picklee.close()
shopping_list = ['Name price quantity total']
store_contents ='''Store Contents
Name Price GTIN-8 Code
Butter £1.20 70925647
Chocolate £1.00 11826975
Bread £1.00 59217367
Cheese £2.80 98512508
Bacon £2.40 92647640
Lamb £4.80 49811230
Ham £2.59 53261496
Potatoes £2.00 11356288
Chicken £3.40 89847268
Eggs £1.29 21271243'''
def item(barcode, quantity, cash_due, shopping_list):
shopping_list.append(contents[barcode]['name']+' £'+(str((int(contents[barcode]['price']))/100))+' '+str(quantity)+' £'+str((int(quantity)*int(contents[barcode]['price']))/100))
print(cash_due)
print(contents[barcode]['price'])
print(quantity)
cash_due += ((int(contents[barcode]['price'])*(int(quantity)))/100)
print(cash_due)
def shopkeeper_ui():
print('Welcome to Stanmore\'s Food Emporium! Feel free to browse.')
print(store_contents)
user_input = ''
while user_input != 'finish':
user_input = input('''Welcome to the checkout.
instructions -
if you are entering text make sure your \'CAP\'s Lock\' is turned off
if you are entering a barcode number, please enter it carefully
if you want to print your current recipt, enter \'recipt\'
if you want to see your current total, enter \'total\'
and if you are finished, enter \'finish\'
You can see the stores contents below
Thanks for shopping: ''')
if len(user_input) == 8:
quantity = int(input('Enter the quantity that you want: '))
item(user_input, quantity, cash_due, shopping_list)
elif user_input == 'recipt':
count8 = 0
for i in shopping_list:
print(shopping_list[count8])
count8 += 1
elif user_input == 'finish':
print('Your shopping list is',shopping_list,' \nand your total was', total,'\n Thank you for shopping with Stanmore\'s Food Emporium')
elif user_input == 'total':
print('your total is, £',cash_due)
else:
print('User_input not valid. Try again...')
shopkeeper_ui()
If i enter the code and my first entry is 21271243 (the barcode for eggs). then i enter 4 for the quantity. i can get the shopping_list list to understand the total and if I print the string cash_due from inside the item function it understands it but as soon as i try to call cash_due from the shopkeeper_ui function it prints 0 instead of what should be 5.12?
cash_due is not mutable. Changes in item function are lost when leaving the function.
Generally, the way out of this is to let the function (item) return the value.
In this case, I would just keep cash_due out of item function and let item only return the cost for that item. Something like this:
def item(barcode, quantity, shopping_list):
shopping_list.append(contents[barcode]['name']+' £'+(str((int(contents[barcode]['price']))/100))+' '+str(quantity)+' £'+str((int(quantity)*int(contents[barcode]['price']))/100))
print(contents[barcode]['price'])
print(quantity)
cost = ((int(contents[barcode]['price'])*(int(quantity)))/100)
print(cost)
return cost
[...]
if len(user_input) == 8:
quantity = int(input('Enter the quantity that you want: '))
cash_due += item(user_input, quantity, shopping_list)
You don't have the same issue with shopping_list because it is a mutable: it is changed in place. Read about mutables to understand the concept.
However, it could be better design to not let item modify the list. It could just return both the list element and the cost, and the caller would modify the list.
def item(barcode, quantity):
stuff = (contents[barcode]['name']+' £'+(str((int(contents[barcode]['price']))/100))+' '+str(quantity)+' £'+str((int(quantity)*int(contents[barcode]['price']))/100))
cost = ((int(contents[barcode]['price'])*(int(quantity)))/100)
return stuff, cost
[...]
if len(user_input) == 8:
quantity = int(input('Enter the quantity that you want: '))
stuff, cost = item(user_input, quantity, shopping_list)
shopping_list.append(stuff)
cash_due += cost

While loop in function not working (Python 3.5.0)

I am doing a piece of code for a school with 7-10 year old students which will test their basic arithmetic skills. The program is fully functional and should allows the teacher to see the scores in text files afterwards. However, it's currently 556 lines long. I have shortened it as much as possible but I can't seem to get this one piece of code to work:
def Repeat(repeat_q, option_right, t_class_right):
repeat_q = input("\n\nWould you like to see any other class details? ")
if repeat_q == "Yes" or repeat_q == "yes":
option_right = False
t_class_right = False
repeat_question = True
repeat_q = " "
elif repeat_q == "No" or repeat_q == "no":
print("Okay...")
repeat = False
T_Exit()
else:
print("Please only write 'yes' or 'no'")
return repeat_question
This function is called later on like this:
elif test == 2:
OP_2(list_counter, repeat_question)
while repeat_question != True:
Repeat(repeat_q, option_right, t_class_right)
All it does like this is repeat the 'repeat_q' variable. I have tried changing the value of the variable after it but nothing seems to work.I can get it to work if I take it out of the function, like this:
elif test == 3:
OP_3(list_counter, repeat_question)
while repeat_question != True:
repeat_q = input("\n\nWould you like to see any other class details? ")
if repeat_q == "Yes" or repeat_q == "yes":
option_right = False
t_class_right = False
repeat_question = True
elif repeat_q == "No" or repeat_q == "no":
print("Okay...")
repeat = False
T_Exit()
else:
print("Please only write 'yes' or 'no'")
This is what happens to the code:
Hello and welcome to my quiz.
Please write your name: teacher
Write the number of the class you would like to see (1, 2 or 3): 1
Opening Class 1
_________________________________________
| |
| 1) Alphabetical with highest score |
| 2) Highest score, highest to lowest |
| 3) Average score, highest to lowest |
|_________________________________________|
Choose one of the options above (1, 2 or 3): 2
Sorting by highest score, from highest to lowest
['Lol: 10', 'Zaid: 9', 'Abdul: 8', 'Hello: 5', 'Bruno: 5']
Would you like to see any other class details? yes
Would you like to see any other class details? yes
Would you like to see any other class details? yes
Would you like to see any other class details? yes
Would you like to see any other class details? no
Okay...
You have now finished viewing class details
Thank you for using this program
>>> # Exits the program
As opposed to this (The working but inefficient version):
Hello and welcome to my quiz.
Please write your name: teacher
Write the number of the class you would like to see (1, 2 or 3): 1
Opening Class 1
_________________________________________
| |
| 1) Alphabetical with highest score |
| 2) Highest score, highest to lowest |
| 3) Average score, highest to lowest |
|_________________________________________|
Choose one of the options above (1, 2 or 3): 1
Sorting alphabetically...
['Abdul: 8', 'Bruno: 5', 'Hello: 5', 'Lol: 10', 'Zaid: 9']
Would you like to see any other class details? yes
Write the number of the class you would like to see (1, 2 or 3): 1
Opening Class 1
_________________________________________
| |
| 1) Alphabetical with highest score |
| 2) Highest score, highest to lowest |
| 3) Average score, highest to lowest |
|_________________________________________|
Choose one of the options above (1, 2 or 3): 3
Sorting by average score, from highest to lowest
['Lol: 10.0', 'Zaid: 8.333333333333334', 'Abdul: 5.333333333333333', 'Hello: 3.3333333333333335', 'Bruno: 3.0']
Would you like to see any other class details? no
Okay...
You have now finished viewing class details
Thank you for using this program
>>>
Can anyone please help me. A full version of my code is available if anyone wants to check that out: http://www.filedropper.com/teacherprogramtask3-annotated
When you have the chunk of code inside of the Repeat() function, repeat_question = True is creating a local variable called repeat_question. This variable is a different variable to the one outside of the function that the while loop is checking.
This issue is to do with variable scope, this website explains it quite well: http://gettingstartedwithpython.blogspot.com.au/2012/05/variable-scope.html
There is a simple solution however, you just need to use the return repeat_question at the end of your function by setting repeat_question to the result of the function:
while repeat_question != True:
repeat_question = Repeat(repeat_q, option_right, t_class_right)
Also inside the function's elif...: and else: statements you may have to set repeat_question to False.
That should fix it.
EDIT: I think that it isn't working as when it is inside the function, the option_right and t_class_right variables are also only local variables and don't affect the option_right and t_class_right that are outside of the function.
It's a bit of a messy workaround but it should work.
OK I got it working!
Repeat function:
def Repeat(repeat_q, option_right, t_class_right):
repeat_q = input("\n\nWould you like to see any other class details? ")
if repeat_q == "Yes" or repeat_q == "yes":
option_right = False
t_class_right = False
repeat_question = True
repeat_q = " "
elif repeat_q == "No" or repeat_q == "no":
print("Okay...")
repeat = False
t_class_right = True
repeat_question = False
T_Exit()
else:
print("Please only write 'yes' or 'no'")
return repeat_question, t_class_right, repeat_question
And in the code:
if test == 1:
OP_1(list_counter, repeat_question)
while repeat_question != True:
repeat_question, t_class_right, repeat_question = Repeat(repeat_question, option_right, t_class_right)
elif test == 2:
OP_2(list_counter, repeat_question)
while repeat_question != True:
repeat_question, t_class_right, repeat_question = Repeat(repeat_question, option_right, t_class_right)
elif test == 3:
OP_3(list_counter, repeat_question)
while repeat_question != True:
repeat_question, t_class_right, repeat_question = Repeat(repeat_question, option_right, t_class_right)
else:
T_Broke()
You have to name repeat_q to repeat_question in the function call, as it is in the above code. That may have caused it to crash and stop working or it could have closed since option_right and t_class_right weren't being updated, or a combination of the two.

Problems transferring information from one part of a function to another

While working on my program I have run into a problem where the information stored in Menu option 1 is not being transferred to Menu option 2. As you can see it is correctly stored when in menu one. When it returns to go to menu option 2 its like it never went to option 1.
update #1:
some suggestions I've had is to understand scope? from what I can tell the program is not passing the data along to its parent program even though I've typed out return in each of the definitions.
#Must be able to store at least 4 grades
#Each class can have up to 6 tests and 8 hw's
#Weighted 40%*testavg 40% hw average attendance is 20%
#User must be able to input a minimum grade warning
#after each test the your program must calculate the students average and issue warning if necessary
##Define the Modules##
import math
def menu (a): #2nd thing to happen
menuend = 'a'
while menuend not in 'e':
menuend = raw_input("Type anything other then 'e' to continue:\n")
print "What would you like to do ?"
menudo = 0
print "1 - Enter Courses\n2 - Select Course to Edit\n3 - Save File\n4 - Load File\n5 - Exit\n"
menudo = input("Enter Selection:")
if (menudo == 1):
menuchck = 0
menuchck = raw_input("\nYou have entered #1 (y/n)?:\n")
if menuchck in ["Yes","yes","y","Y"]:
x = m1()
else:
print "I'm sorry,",nam,",for the confusion, lets try again\n"
menu()
elif (menudo == 2):
menuchck1 = 0
menuchck1 = raw_input("\nYou have entered #2 (y/n)?:\n")
if menuchck1 in ["Yes","yes","y","Y"]:
x = m2()
else:
print "I'm sorry,",nam,",for the confusion, lets try again\n"
menu()
elif (menudo == 3):
print "Entered 3"
elif (menudo == 4):
print "Entered 4"
else:
print "Anything Else Entered"
def course(): #3rd thing to happen
b = {}
while True:
while True:
print "\n",name,", please enter your courses below ('e' to end):"
coursename = raw_input("Course Name:")
if (coursename == 'e'):
break
will = None
while will not in ('y','n'):
will = raw_input('Ok for this name : %s ? (y/n)' % coursename)
if will=='y':
b[coursename] = {}
print "\n",name,", current course load:\n",b
coursechck = None
while coursechck not in ('y','n'):
coursechck = raw_input("Are your courses correct (y/n)")
if coursechck =='y':
return b
else:
b = {}
print
##Menu Options##
def m1():
a = course()
return a
def m2():
print "Excellent",name,"lets see what courses your enrolled in\n"
print x
return x
###User Input Section###
name = raw_input("Enter Students Name:\n")
a = {}
menu(a)
raw_input("This is the end, my only friend the end")
In your if-elif blocks in the do==1 case, you write m1(), but for the last case, you write x=m1(). You should have the latter everywhere (by typing m1() you only run the function, but do not store the returned x anywhere).
By the way, you can avoid this if-elif confusion using if chck in ["Yes","yes","Y","y"]:

Loop issue with python3

I'm struggeling a bit with a part of code for a little program I'm writing. Have in mind I'm very new with this.
Heres the code:
def sell():
sell = input("\nGreetings! What would you like to do today?\nPress 1 to sell an animal\nPress 2 to buy an animal\nPress 3 If you want to see all the farms and their animals first\n")
if sell == "1":
whichs = input("Which animal do you want to sell?\nPress 1 for pig\nPress 2 for horse\nPress 3 for cow\nPress 4 for bull\n")
if whichs == "1":
print ("\nYou just sold\n",p[0])
print ("\nYou now have 350gold")
print ("\nThese are the animals you have left:")
print (p[1], p[2], p[3]) #Prints the animals you have left from p list.
elif whichs == "2":
print ("\nYou just sold\n",p[1])
print ("\nYou now have 350gold")
print ("\nThese are the animals you have left:")
print (p[0], p[2], p[3])
elif whichs == "3":
print ("\nYou just sold\n",p[2])
print ("\nYou now have 360gold.")
print ("\nThese are the animals you have left:")
print (p[0], p[1], p[3])
elif whichs == "4":
print ("\nYou just sold\n",p[3])
print ("\nYou now have 350gold.")
print ("\nThese are the animals you have left:")
print (p[0], p[1], p[2])
else:
print ("Error")
I want this to loop so when the user has sold one animal, they start over with the:
sell = input("\nGreetings! What would you like to do today?\nPress 1 to sell an animal\nPress 2 to buy an animal\nPress 3 If you want to see all the farms and their animals first\n")
And I'm struggeling with how this is done.
The other two answers are right in telling you to use a while loop but fail to address a more general problem: the loop shouldn't be inside of the sell function but outside of it, as your text indicates that the user can also buy stuff or look at his stats. You should create individual functions for all of these actions and then create a loop that checks for the action and calls the appropriate functions:
def buy():
#...
def sell():
#...
def stats():
#...
while True:
choice = input("1: Buy 2:Sell 3:Stats - press any other key to exit")
if choice == "1": buy()
elif choice == "2": sell()
elif choice == "3": stats()
else: break
The loop could be optimized by using more pythonic approaches like mapping the choices to the functions in a dictionary, but I've written it with a simple if for clarity.
Also, if you don't choose to hold all your state in global variables (which you shouldn't), it would make sense to put the functions into a class which also holds the current balance, stock and other game parameters.
def sell():
looping = True
while looping:
sell = input("\nGreetings! ... Press Q for quit")
if sell == "1":
#rest of your code
elif sell == "Q":
looping = False
Try using a while loop:
def sell_function():
while True:
sell = input("\nGreetings! What would you like to do today?\nPress 1 to sell an animal\nPress 2 to buy an animal\nPress 3 If you want to see all the farms and their animals first\n")
# ...
else:
print("Error")
break # Stop looping on error
We could have also set a variable to True, done while variable and then variable = False instead of break for the same effect (in this instance).
I renamed your function, as you used a variable called sell and had a function with the same name which could cause problems. Also, you'll no doubt later find the break and continue statements useful.

Categories