how to find most and least popular product? - python

I'm trying to output the most popular and least popular item a store has sold. The items include: beef,chicken,egg,tuna. In my code, I've declared the variables:
beef = 0
egg= 0
tuna = 0
chicken= 0
and when a customer purchases a particular item, it would be beef+=1 and so on.
My current problem is that i dont know how to display the name of the most sold item as the function min() and max() would only show the values of thew variables. I've even tried using a dictionary where the code was:
itemsList = [beef,egg,tuna,chicken]
mostPopular = max(itemsList)
items = {"Beef":beef,"Egg":egg","Tuna":tuna,"Chicken":chicken}
for key, value in items:
if mostPopular == value:
print(key)
unfortunately, this does not work as i would receive the error "too many values to unpack" :// is there another way to obtain the most popular item?

You were almost there:
for key, value in items.items():
By default iterating over a dictionary only gives you the keys. You have to call dict.items() to get key-value pairs.
You could've also imported collections.Counter and printed Counter(items).most_common(1).

Related

dict with one key and multiple values

I was wondering if there's a way for me to pull a value at a specific index. Let's say I have a key with multiple values associated with it. But in my dictionary I have multiple keys, each key with multiple values. I want to iterate through the keys and then each respective value associated with that key. I want to be able to pull the value at the first index and subtract it from the value at the second index.
d= {108572791: [200356.77, 200358], 108577388: [19168.7, 19169]}
output for key 108572791 would be -1.33
output for key 108577388 would be -.03
I've try reading up on dict and how it works apparently you can't really index it. I just wanted to know if there's a way to get around that.
for key, values in total_iteritems():
for value in values:
value[0]-value[1]:
Edit:
Since the question is way different now, I'll address the new subject:
d= {108572791: [200356.77, 200358], 108577388: [19168.7, 19169]}
for i in d:
print("Output for key ",str(i), "would be ",(d[i][1]-d[i][0]))
Output:
Output for key 108572791 would be 1.2300000000104774
Output for key 108577388 would be 0.2999999999992724
Original answer
Yes. When you have a dict containing a list as value if you want to obtain a specific value, then you need to address the index in the list. An example is:
a = {'Name':['John','Max','Robert']}
This means that:
print(a['Name'])
Output:
['John','Max','Robert']
Since ['Name'] is a list:
for i in range(len(a['Name'])):
print(a['Name'][i]
Output:
John #(Because it's the index 0)
Max #(Index = 1)
Robert #(Index = 2)
If you want a specific value (for instance 'Max' which is index = 1)
print(a['Name'][1]
Output:
Max
Depends on how many values in key obvious but this does the trick:
for x in d:
print(x)
print(d[x][0]-d[x][1])
You can use list of tuples if you want to use indexing.
d= [(108572791,[200356.77, 200358]), (108577388,[19168.7, 19169)]
for tuple in my_list:
print(tuple[0])
for value in tuple[1]:
print(value)

python dictionary: value and the key not corresponding in my code to find max

My goal is to figure out who has the most message the file is here.mbox-short.txt.
My code is here.
fhand = open('mbox-short.txt')
counts = dict()
#this loop is to creat a dictionary in which key is the mail's name
#value is times the mail's name appeared
for line in fhand:
if not (line.startswith('From')and not line.startswith('From:')):
continue
words = line.split()
counts[words[1]] = counts.get(words[1],0) + 1
num = None
#this loop is to find max value and its key
for key, value in counts.items():
#print key, value
if num == None or counts[key] > num:
num = counts[key]
print key, num.
After I ran the code. The result is:
But when I run the line print key,value in the second loop, comment the line which under the print key, value, the result is show that the ray#media.berkeley.edu is 1 instead of 5. The cwen#input.edu is 5.
So why the key and value is not corresponding. I thin the problem is on line 19. How can solve it?
It seemly that I didn't save the key.
Thank you for all.
Thank all of you. I solved it.
In the second loop, I created a variable to save the key
I’m not sure if i understand what you want to do. The fist loop should count all address and the second should find the maximum?
You have to inialize num with some value, but I would choose zero. Then you haven’t check for num == None. And you muss save the key, not only the value. The key will always be the last key in the dict.
You need to use the Counter class, its designed for this exact purpose:
import re
from collections import Counter
with open('mbox-short.txt') as f:
emails = Counter([i.strip() for i in re.findall(r'From:(.*?)', f.read(), re.M)])
for email, count in emails.most_common():
print('{} - {}'.format(email, count))
As you realized you need to store the key which gives the max value, or at least max-value-so-far. Then you don't need to store num, the maximum counts[key] value so far, only the key that gives it max_key.
Also, you iterate on the items in counts with for key, value in counts: ..., but then you ignore value inside the loop. Use value; there's no need to look up counts[key] again. And as long as counts has >=1 item, you don't need the pessimism of setting num = None and then testing against that inside your loop. Anyway, num is unnecessary.
# Iterative approach
max_key = counts.keys()[0] # default assumption
for key, value in counts.items():
if value > counts[max_key]:
max_key = key
but you can avoid all this by directly finding the max without needing to iterate:
# Direct approach, using `max(..., key=...)`
max_key = max(counts, key=lambda kv: kv[1])
print max_key, counts[max_key]
cwen#iupui.edu 5
This works because Python sorted(), max(), min() will accept a dictionary, and they have an optional parameter key which allows you to pass in a function telling the comparison which element in each item to use.
Look at the doc for sorted(), max(), min(), and read about Python idioms using them.
There is also the custom collections.Counter which #Burhan references. But it's important to learn how to sort things first. Then you can use it.

Product dictionary addition and subtraction

I need to write a function that accepts a dictionary as the inventory and also a product_list of (name, number) pairs which indicate when we should update the inventory of that product by adding a certain number to it which could be a negative number.
Once a product is mentioned for the first time it is added to the dictionary and when its count reaches zero it shold remain in the dictionary. If the count ever becomes negative I need to raise a value error.
Example:
d = {"apple":50, "pear":30, "orange":25}
ps = [("apple",20),("pear",-10),("grape",18)]
shelve(d,ps)
d
{'pear': 20, 'grape': 18, 'orange': 25, 'apple': 70}
shelve(d,[("apple",-1000)])
Traceback (most recent call last):
ValueError: negative amount for apple
My code is giving either an unexpected EOF error or invalid syntax depending on if I include the last print line. It is definitely not currently accomplishing the goal but I believe this is the format and somewhat the logic I'll need to solve this. I need the function to print 'negative amount for x' where x is the fruit that is negative. Any help on this is appreciated
Code:
def shelve(inventory,product_list):
count = 0
try:
for x in product_list:
if x == True:
product_list.append(x)
count += key
else:
return product_list
except ValueError:
print ('negative amount for (product)')
print "hello program starts here"
d = {"apple":50, "pear":30, "orange":25}
ps = [("apple",20),("pear",-10),("grape",18)]
shelve(d,ps)
the important part of your task is to split your problem in sub problems. Using the dict and list data structure is mainly based on iterating over those data structures. Start simple and do one step at a time.So one way to solve the problem could be:
1.) Iterate over the product list (you can print the items to see what is happening). This will be the product loop.
for x in ps:
print x
Check how you can access the lists elements with e.g. changing print x to print x[0] or x[1]
2.) Now for every product in the product loop, you need to iterate the inventory and set the inventory to the corresponding values. Start by just iterating the inventory and print its contents. Check out how it works before doing more complicated stuff, play around with it. ^^-d
(I just noticed there is a simpler solution than iterating, since its a dict, you will know what to do)
3.) Now add the Value error and Exception stuff
Hope this helps

python: badly behaving dict inside a function- erroneous TypeError

I have dicts that I need to clean, e.g.
dict = {
'sensor1': [list of numbers from sensor 1 pertaining to measurements on different days],
'sensor2': [list of numbers from from sensor 2 pertaining to measurements from different days],
etc. }
Some days have bad values, and I would like to generate a new dict with the all the sensor values from that bad day to be erased by using an upper limit on the values of one of the keys:
def clean_high(dict_name,key_string,limit):
'''clean all the keys to eliminate the bad values from the arrays'''
new_dict = dict_name
for key in new_dict: new_dict[key] = new_dict[key][new_dict[key_string]<limit]
return new_dict
If I run all the lines separately in IPython, it works. The bad days are eliminated, and the good ones are kept. These are both type numpy.ndarray: new_dict[key] and new_dict[key][new_dict[key_string]<limit]
But, when I run clean_high(), I get the error:
TypeError: only integer arrays with one element can be converted to an index
What?
Inside of clean_high(), the type for new_dict[key] is a string, not an array.
Why would the type change? Is there a better way to modify my dictionary?
Do not modify a dictionary while iterating over it. According to the python documentation: "Iterating views while adding or deleting entries in the dictionary may raise a RuntimeError or fail to iterate over all entries". Instead, create a new dictionary and modify it while iterating over the old one.
def clean_high(dict_name,key_string,limit):
'''clean all the keys to eliminate the bad values from the arrays'''
new_dict = {}
for key in dict_name:
new_dict[key] = dict_name[key][dict_name[key_string]<limit]
return new_dict

Dynamic Python Lists

In the below Python Code, am dynamically create Lists.
g['quest_{0}'.format(random(x))] = []
where random(x) is a random number, how to print the List(get the name of the dynamically created List name?)
To get a list of all the keys of your dictionary :
list(g.keys())
There is nothing different with a regular dictionary because you generate the key dynamically.
Note that you can also put any type of hashable object as a key, such as a tuple :
g[('quest', random(x))] = []
Which will let you get a list of all your quest numbers easily :
[number for tag, number in g.keys() if tag == "quest"]
With this technic, you can actually loop through the tag ('quest'), the number and the value in one loop :
for (tag, number), value in g.items():
# do somthing
Unpacking is your best friend in Python.
You can iterate over the g dictionary with a for loop, like this
for key, value in g.items():
print key, value
This will print all the keys and their corresponding lists.

Categories

Resources