3

I need to create a program that has a class that crates an object "Food" and a list called "fridge" that holds these objects created by class "Food".

class Food:
    def __init__(self, name, expiration):
        self.name = name
        self.expiration = expiration


fridge = [Food("beer",4), Food("steak",1),  Food("hamburger",1),  Food("donut",3),]

This was not hard. Then i created an function, that gives you a food with highest expiration number.

def exp(fridge):
    expList=[]
    xen = 0
    for i in range(0,len(fridge)):
        expList.append(fridge[xen].expiration)
        xen += 1
    print(expList)
    sortedList = sorted(expList)
    return sortedList.pop()

exp(fridge)

This one works too, now i have to create a function that returns a list where the index of the list is the expiration date and the number of that index is number of food with that expiration date. The output should look like: [0,2,1,1] - first index 0 means that there is no food with expiration date "0". Index 1 means that there are 2 pieces of food with expiration days left 1. And so on. I got stuck with too many if lines and i cant get this one to work at all. How should i approach this ? Thanks for the help.

3
  • is expList is the expiration date of each item ? from that list you want your o/p like you mentioned ? Commented Jan 29, 2018 at 12:21
  • Can you mention first o/ps you are getting and exact o/p you need next ? Commented Jan 29, 2018 at 12:22
  • My question has been already answered in the comments below. Thanks for the interest. expList is the exp date of each item, yes. Commented Jan 29, 2018 at 13:23

5 Answers 5

1

In order to return it as a list, you will first need to figure out the maximum expiration date in the fridge.

max_expiration = max(food.expiration for food in fridge) +1 # need +1 since 0 is also a possible expiration
exp_list = [0] * max_expiration
for food in fridge:
    exp_list[food.expiration] += 1
print(exp_list)

returns [0, 2, 0, 1, 1]

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks a lot for the answer. Could you please describe your function a little bit more ? I am having a hard time to understand it, even in debugger. Thanks :)
Sure, max(food.expiration for food in fridge) will iterate over the food in the fridge, look at the expiration and return the maximum encountered expiration number. In your example this would be 4. In your example you want to return a list of length 5, you want to show how often expiration 0, 1 , 2 ,3 and 4 is returned (hence the +1). You then initiate a list with 5 zeroes in it using the line [0] * max_expiration. Then you iterate through the food in the fridge and update the index matching the expiration date accordingly.
Thanks a lot. Now i understand :)
1

You can iterate on the list of Food objects and update a dictionary keyed on expiration, with the values as number of items having that expiration. Avoid redundancy such as keeping zero counts in a list by using a collections.Counter object (a subclass of dict):

from collections import Counter

d = Counter(food.expiration for food in fridge)
# fetch number of food with expiration 0
print(d[0]) # -> 0
# fetch number of food with expiration 1
print(d[1]) # -> 2

Comments

1

You can use itertools.groupby to create a dict where key will be the food expiration date and value will be the number of times it occurs in the list

>>> from itertools import groupby
>>> fridge = [Food("beer",4), Food("steak",1),  Food("hamburger",1),  Food("donut",3),]
>>> d = dict((k,len(list(v))) for k,v in groupby(sorted(l,key=lambda x: x.expiration), key=lambda x: x.expiration))

Here we specify groupby to group all elements of list that have same expiration(Note the key argument in groupby). The output of groupby operation is roughly equivalent to (k,[v]), where k is the group key and [v] is the list of values belong to that particular group.

This will produce output like this:

>>> d
>>> {1: 2, 3: 1, 4: 1}

At this point we have expiration and number of times a particular expiration occurs in a list, stored in a dict d.

Next we need to create a list such that If an element is present in the dict d output it, else output 0. We need to iterate from 0 till max number in dict d keys. To do this we can do:

>>> [0 if not d.get(x) else d.get(x) for x in range(0, max(d.keys())+1)]

This will yield your required output

>>> [0,2,0,1,1]

Comments

0

Here is a flexible method using collections.defaultdict:

from collections import defaultdict

def ReverseDictionary(input_dict):
    reversed_dict = defaultdict(set)
    for k, v in input_dict.items():
        reversed_dict[v].add(k)
    return reversed_dict

fridge_dict = {f.name: f.expiration for f in fridge}

exp_food = ReverseDictionary(fridge_dict)
# defaultdict(set, {1: {'hamburger', 'steak'}, 3: {'donut'}, 4: {'beer'}})

exp_count = {k: len(exp_food.get(k, set())) for k in range(max(exp_food)+1)}
# {0: 0, 1: 2, 2: 0, 3: 1, 4: 1}

Comments

0

Modify yours with count().

def exp(fridge):
    output = []
    exp_list = [i.expiration for i in fridge]
    for i in range(0, max(exp_list)+1):
        output.append(exp_list.count(i))
    return output

3 Comments

Thanks for the answer. Could you please explain a bit, how does your code works ?
I found a it would be wrong if the maximum of expiration is bigger then fridge's length. So I modified it from range(0, len(fridge)+1) torange(0, max(exp_list)+1 ).
Anyway, create a list of all the expiration, and iterate it from 0 to the maximum expiration. count() is a function to count specific item in a list, so in the loop it will append counts of the expiration to output list in sequence, output[0] = exp_list.count(0) and so on.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.