0

I am trying to do the "Grocery" problem, and I have many issues.

First, the program exits after the first input.

Second, I have an issue with associating the counted item with the list.

My code is as follows:

x = input("give me the list: ").capitalize()

#gets input from user

while True:
    try:
        z = [""]
        y = 1
        if x in z:
            y += y
            z.append(x)
            z.sort()
#if the user input already is in the list, then the count of the item (y) should increase by one,
#and the input is added to the list
        else:
            y = 1
            z.append(x)
            z.sort()
#Otherwise the list increase and the count remain of one

    except EOFError:
        for i in z:
            print(y, i)
#I do not know how I can print the associated item counted
    break

Following the advice given, I have the following code:

def main():

  while True:
     try:
         x = input("give me the list: ")
     except EOFError:
         print(groceries_dict).capitalize()
#print the list by using the function below


def updateGroceries(cart,item):
    cart = [""]
    cart.append(item)
    return cart

def DicGroceries(cart):
    cart.count()
    groceries_dict = {i:cart.count(i) for i in cart}
    return groceries_dict


if __name__ == "__main__":
    main()

I know that it is still not working. My main issue is making the functions communicate with each other.

I do not understand why python is telling me that "groceries_dict" is not defined.

With this proposal, I know that I am completely disrespecting all the advice in the answer, but trying to setup functions still make me crazy. Naturally I see the point of breaking down a program in small unit, but functions really break my head. Calling them make me crazy.

I did respect however the point that a dictionary was needed, but I wonder why I could not rather use a list.

Anyway, the result is still wrong...but it is "something":

cart = {}

while True:
    try:
       x = input("give me the list: ").lower()
       if x in cart:
           cart[x] += 1
       else:
           cart[x] = 1
    except EOFError:
       for key in cart.keys():
           print(cart[key])

This counting is inspired by the piece of code shared in the answer. But this frustrates me because I do not understand why this happens in this way. I get that we are telling the dictionary to have keys representing a count. But why would it ever happen in that way? What in the dictionary as a python object makes it happen in this way? I mean when I see this dictionary description, I do not see or understand anything that would make the dictionary "behave" that way. Why is it doing this? Why?

Again I understand the principle of:

cart[x] += 1

but why is this happening for the dictionary?

What I also understand is that dictionary is not allowing any duplicates. OK. Good. But I still cannot understand full.

21
  • 1
    stop jumping from problem to problem until you can resolve a problem you are encountering the same problem everywhere you go. you are using the wrong data structures.
    – UpAndAdam
    Commented Mar 28 at 0:44
  • 1
    Its wrong because you never called the functions in main
    – UpAndAdam
    Commented Mar 28 at 18:57
  • 1
    you clearly dont get functions at all instead of making random stabs at using them in different questions here ask a question about the thing you don't understand it's clear you dont understand the difference between defining a function, what the definition means, or how to call a function, did you even watch a single lecture?
    – UpAndAdam
    Commented Mar 28 at 18:59
  • 1
    it's all good you are trying to learn. sorry if i sounded frustrating... i try to help out during downtime during my work. i was probably more rude than i should have been to be honest.
    – UpAndAdam
    Commented Mar 28 at 21:43
  • 1

2 Answers 2

1

you only prompt for input once so it exits after one input.. eventually you have a loop problem. what you are doing isnt making sense. why are you adding x to the list and sorting it whether x is in the list or not? the only difference is in one case you double y and the other you reset it to.

your approach is entirely unsuitable for this problem and will never yield a working solution. You are using the wrong data structure to try to work on this.

again you need to start with an outline and then implment. You have a pattern established of coding blindly just trying to see where it takes you. and if you have noticed it is not taking you anywhere.

  1. You need an outer loop to get input from user
  2. You need a function that given an item from the user updates a 'grocery list' appropriately
  3. You need to iterate over the list to print out the results when they are done with input

Do this in phases. First pass see if you can just build a list of the inputs. don't worry about counting, dont worry about duplicates, just get your input loop working so that when they hit ctrl-d it ends and prints everything in the list sorted. The way you should 'build' the list is by making a function you call for example updateGroceries(cart, item) that will put item into the cart. Up to you for now what type cart is. the important part is you do that all in a function.

Second pass: now we will work on your function that builds and maintains the 'grocery list' previously you could have used a list or a set... we're going to use a dictionary because that is an intelligent solution to your problem. The key will be the name of the item, the value will be the count. This is pretty easy. if the item is in the cart, update the value of that item by 1, (do not add it to itself, add 1) if it not in the cart, put it in the cart with a value of 1.

Third pass: this time tidy up, capitalize the input string after you receive it and have validated that it isnt empty. Figure out how to print in order properly.

Done, pat yourself on the back.

10
  • 1
    You break programs down into functions to make things more manageable, more readable, more testable, and for deduplication, reusability, and simplicity. If you struggle with functions you need to go back to rework the earlier lessons in this course and watch all the videos. go back to pset0 tip calculator, that shows a way to get use return values from functions by passing in variables. Functions allow you to change the value of things passed in or to change the value of globals or class members if its a class method as opposed to a raw function.
    – UpAndAdam
    Commented Mar 28 at 14:20
  • 1
    The reason for doing it in a function is modularity.. Say you do part 1 as i described, if you kept the logic i specified in a function, than during the next phase you are MOSTLY only changing the code in your function and not the code calling the function ( aside perhaps from the data type you pass into it). Also it means that instead of just calling main, you can make a test program that simply imports your file and calls your functions with hardcoded inputs to test that it behaves as expected. much easier to debug.
    – UpAndAdam
    Commented Mar 28 at 14:22
  • 1
    in the solution i describe you'd have really only two functions ( I don't count main ) you'd have an update_grocery_list function and possibly a print_grocery_cost function. or you could do the printing in main. do you need functions here technically no, but i think it will be helpful for you since you seem to struggle with functions and will make it more testable and give you smaller chunks to check for errors in. Computer Science and programming is the science/art of turning a problem into a collection of subproblems and by solving all the subproblems you solve the big problem
    – UpAndAdam
    Commented Mar 28 at 14:25
  • 1
    you pass variables into a function if you need the function to have access to them. sometimes a function doesnt need variables passed to it because of globals ( which are BAD ) or because it doesnt take any input. But thats a FAR BETTER QUESTION to ask then most of what you have asked. if you ask a specific question we can answer it for you. Do you have any concept of the understanding of what variable scope is? this should have been covered in lectures
    – UpAndAdam
    Commented Mar 28 at 18:56
  • 1
    Then you have missed something in the videos and slides.
    – UpAndAdam
    Commented Mar 28 at 21:42
1

Adding an answer from your updated code to simply explain your updated code

Nothing is happening because you didn't call any of the functions. You admit you have some confusion so I'm just going to explain your code and what it says and in some spots what you need.


# this defines a function called main that takes no arguments, it does not call main
def main():
  ## you probably want to create `cart` here
  # cart = []
  ## you need to know when to exit loop, make a new variable for that
  stop = False  ## I added this
  while not stop: ## note I altered this line
    try:
      x = input("give me the list: ")
      ## this is completely broken because you don't do anything with `x` you just ask for another one... you need to do something with `x` first... like call the function I suggested for you to write
      ## this is probably where you should be calling updateGroceries(cart, x)
    except EOFError: # this is good you catch the exception... except this should be your cue to simply exit the while loop.
       ## exit the while loop by setting stop to True
       stop = True ## i added this

  #we are outside the while loop now so print
  
  ## This is wrong for 3 reasons. 
  ## 1st you have not defined groceries_dict anywhere nor assigned a value to it. that's why its undefined. where did you declare it? ( only inside the scope of a function; its not visible here in main)
  ## 2nd you dont print a list or a dict like this
  ## 3rd that's not how to capitalize either.
  print(groceries_dict).capitalize()

## This comment is useless   
#print the list by using the function below

## this defines a function 'updateGroceries' accepting a cart and an item, but does not call the function, you have to call it in the program flow ( likely main in your case) when needed
## NOTE you never call this function!
def updateGroceries(cart, item):
    cart = [""]     ## No don't empty the cart everytime, this causes you to lose everything.  As mentioned above define cart in `main`.
    cart.append(item) ## You are treating `cart` as a list and appending item into it, this is reasonable
    ## NOTE you should probably capitalize `item` as you are putting it in! are Oranges and oranges different? should they have different counts?  are you going to later print the value twice with two different numbers?
    return cart ## you are returning cart unnecessarily because you because you passed it in, no return needed.
    

# this defines but does not call a function called `DicGroceries` that takes a `cart` as input; you need to call this function somewhere for it to be executed
# NOTE you never call this function!
def DicGroceries(cart):
    cart.count() # this does absolutely nothing here because the output isnt captured

    groceries_dict = {i:cart.count(i) for i in cart} ## A lot about this
    # this is a dictionary comprehension that you clearly googled or got
    # from somewhere else becuase I know you don't know what this means,
    # how it works and what it's doing or you wouldn't have bothered with
    # it. You are also replicating things in the dictionary. 
    # This defeats the point of using a dictionary in this problem.
    # Instead use the dictionary as your `cart` to start with. 
    #
    # if item not in cart:
    #   cart[item] = 1 
    # else:
    #   cart[item] = cart[item]+1
    #
    # Isn't that easier? OR for no if make use of dictionary.get with default value return of 0
    # count = cart.get(item, 0) # gets the value of item which is the count, 0 if it wasn't found
    # cart[item] = count + 1  # updates/inserts the item into the dictionary with an updated 'count' by adding 1 to 0 or the old value

    # you return the groceries_dict which is reasonable here IF you capture it where you call the function, but as mentioned I would have made `cart` the dictionary the whole time, and you wouldnt have to have this function. 
    return groceries_dict


if __name__ == "__main__":  #if you run this python file from command line or say on commandline `python this_file` the code starts executing here after loading all code above.  If you include this python file in another python file, then this section never gets run, so main wouldn't be run unless you called it.  This is good practice so that you can include python code in other code to reuse functions but still possibly have standalone functionality.

    main() # calls the main function

6
  • Many thanks for your extremely high amount of comments, it is a lot to take in, I am digesting it. Commented Mar 30 at 21:10
  • Regarding the dictionary comprehension: yes, was trying to find a way to count duplicates element in the list, googled and found this Stackoverflow question. Commented Mar 30 at 21:14
  • 1
    dont just take in code you dont understand the thing is you have no need to have duplicates in the first place and that code isnt particularly good
    – UpAndAdam
    Commented Mar 31 at 18:22
  • Why is a dictionary a good / clever solution? Commented Apr 9 at 16:23
  • 1
    because infinite loops are bad.. the control-D doesn't break the loop, it causes an exception that YOU use to break the loop. The user doesn't interact with loops. its a better practice to use a variable then to use a while true, and break on the exception that you catch... thats not a the biggest problem you had though. far from it. The biggest problem is you reset the cart in every pass of your function calls.
    – UpAndAdam
    Commented Apr 9 at 16:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .