I am creating a vote system to pick a team, butI have hit a wall. The code works fine up until the point of decision2. Any ideas?
Please remember this code is a work-in-progress.
teamNames = []
teams = {}
easy = [0, 1, 2, 3, 4, 5]
NoVotes1 = {'first' : 0, 'second' : 0, 'third' : 0, 'fourth' : 0, 'fifth' : 0}
NoVotes2 = {'first' : 0, 'second' : 0, 'third' : 0, 'fourth' : 0, 'fifth' : 0}
NoVotes3 = {'first' : 0, 'second' : 0, 'third' : 0, 'fourth' : 0, 'fifth' : 0}
NoVotes4 = {'first' : 0, 'second' : 0, 'third' : 0, 'fourth' : 0, 'fifth' : 0}
NoVotes5 = {'first' : 0, 'second' : 0, 'third' : 0, 'fourth' : 0, 'fifth' : 0}
while True:
print("Enter team name " + str(len(teamNames) + 1) + (" or press enter to stop."))
name = input()
if name == "":
break
teamNames = teamNames + [name]
print("The team names are ")
for name in teamNames:
print(" " + name)
for name in teamNames:
teams[name] = 0
teamNames.sort()
print("In alphabetical order the team names are ")
print()
print(str(teamNames))
y = 0
decision1 = input("Would you like to enter a vote? (1 = yes, 2 = no)")
while decision1 == "1":
print("ok great, where did " + teamNames[y] + " come")
decision2 = input()
if decision2 == "1":
teams[easy[y]] = teams[easy[y]] + 1
y = y + 1
if decision1 == "2":
break
elif n == "6":
break
I think I see what you've misunderstood. Standard dictionaries, unlike lists, have no concept of order or the nth (e.g. first) item. They are just associations between keys and values. When you say teams[key] = value you are setting the value at key, when you say value = teams[key] you are getting the value at key. It's possible that key is a number but it doesn't have to be, and if key is 1 then that doesn't mean the second value in the dictionary, or the first, or any other position. Perhaps this example interactive session will help you understand:
>>> dictionary = {"a": "b", "c": "d"}
>>> dictionary = {"a": "b", "c": "d", 5: "e"}
>>> dictionary[1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 1
>>> dictionary["c"]
'd'
>>> dictionary[5]
'e'
What you want is teams[teamNames[y]] = teams[teamNames[y]] + 1, which by the way can be shortened to teams[teamNames[y]] += 1.
Does all that make sense? If not I suggest doing some simple experiments with dictionaries until you understand them better. Play around with the in the shell. Write some small programs using dictionaries to see what they do.
Related
So I have this document called new.txt which contains many digits of pi (see https://www.piday.org/million/) and I want to split the number into a list made out of all these digits in order. My code works but it's extremely slow, (I have tried with a less digits of pi).
def sort(stuff):
for iter_num in range(len(stuff)-1,0,-1):
for idx in range(iter_num):
if stuff[idx]>stuff[idx+1]:
temp = stuff[idx]
stuff[idx] = stuff[idx+1]
stuff[idx+1] = temp
return stuff
a = []
with open("/Users/serax/desktop/new.txt", "r") as r:
for line in r.readlines():
for char in line:
text = a.append(char)
print(sort(a))
thanks to the comments i have edited my code, here's the result.
thisdict = {
".": 0,
"0": 0,
"1": 0,
"2": 0,
"3": 0,
"4": 0,
"5": 0,
"6": 0,
"7": 0,
"8": 0,
"9": 0,
}
with open("/Users/serax/documents/new.txt", "r") as r:
for line in r.readlines():
# print(sorted(line)) # built in function that can sort str/list/tuple (works)
for char in line:
for key in thisdict:
if char == key:
thisdict[key] += 1
ordered = ""
for i in thisdict:
ordered = ordered + i*thisdict[i]
print(ordered)
Please consider the below Python code:
def allot():
dict2 = {'1': 1, '2': 1, '3': 0, '4': , '5': 1}
allotted_id = None
for k in dict2:
usr_id = 3
if (str(usr_id) != k):
continue;
if ((str(usr_id) == k) and (dict2[str(usr_id)] == 1)):
print("\n user Requested Id : ", usr_id)
print("\n user Requested Id is available ! ")
allotted_id = k
break;
else:
print("\n user Requested Id : ", usr_id)
print("\n user Requested Id is not available ! ")
usr_id = usr_id + 1
if (dict2[str(usr_id)] == 1):
allotted_id = usr_id
break;
print('So allotted dict2 Id', allotted_id)
allot()
In the "dict2", if values == 1 then it is active or if values == 0 then it is inactive. Here, match the usr_id with key id in dict2.
Case 1: dict2 = {'1': 1, '2': 1, '3': 1, '4': 1, '5': 1}. Now usr_id==3 and dict2 key '3'==1. so allotted id=3.
Case 2: dict2 = {'1': 1, '2': 1, '3': 0, '4': 1, '5': 1}. Now usr_id==3 and dict2 key '3'==0 . Then next active id is allotted.So allotted id=4.
Case 3: dict2 = {'1': 1, '2': 1, '3': 0, '4': 0, '5': 1}. Now usr_id==3 and dict2 key '3' & '4'==0 . So the next nearest active id to the usr_id want allocate (is nothing but key id '2').How to do it?
Guide me for my case 3 scenario. Thanks in advance.
Assuming you want no efficiency changes to the code, you're overwriting the usr_id in the for k in dict2 loop.
def allot():
dict2 = {'1': 1, '2': 1, '3': 0, '4': , '5': 1}
allotted_id = None
usr_id = 3 # Move this out of the loop
for k in dict2:
if (str(usr_id) != k):
continue;
if ((str(usr_id) == k) and (dict2[str(usr_id)] == 1)):
print("\n user Requested Id : ", usr_id)
print("\n user Requested Id is available ! ")
allotted_id = k
break;
else:
print("\n user Requested Id : ", usr_id)
print("\n user Requested Id is not available ! ")
usr_id = usr_id + 1
if (dict2[str(usr_id)] == 1):
allotted_id = usr_id
break;
print('So allotted dict2 Id', allotted_id)
allot()
You can write this code to do more checks and utilise the dictionary structure a bit more...
def allot():
# Variables to Enter
dict2 = {1: 1, 2: 1, 3: 0, 4: 0, 5: 1}
usr_id = 3
# Boolean Variables
allotted_id = None
upper_exhausted = False
lower_exhausted = False
# Need to calculate the min and max to know when to stop searching
max_id = max(dict2.keys())
min_id = min(dict2.keys())
# Check the initial ID
if dict2[usr_id] == 0:
print("ID {} inactive. Continuing search.".format(usr_id))
else:
allotted_id = usr_id
# Run two searches - one increasing through the dictionary
# and one decreasing through the dictionary
upper_usr_id = usr_id + 1
lower_usr_id = usr_id - 1
# Run loop whilst the max and min dict key haven't been reached
# AND there's no allotted ID.
while not allotted_id:
if not upper_exhausted:
if dict2[upper_usr_id] == 0:
print("ID {} inactive. Continuing search.".format(upper_usr_id))
if upper_usr_id < max_id:
upper_usr_id += 1
else:
upper_exhausted = True # Maximum has been reached
else:
allotted_id = upper_usr_id
if not lower_exhausted:
if dict2[lower_usr_id] == 0:
print("ID {} inactive. Continuing search.".format(lower_usr_id))
if lower_usr_id > min_id:
lower_usr_id -= 1
else:
lower_exhausted = True # Minimum has been reached
else:
allotted_id = lower_usr_id
# Exhausted all values - No Data value
if upper_exhausted and lower_exhausted:
allotted_id = -999
if allotted_id == -999:
print("Couldn't allot an ID")
else:
print("Allotted ID is: {}".format(allotted_id))
allot()
I would use numpy:
user_ids = np.array(range(5))
valid_user = np.array([1, 1, 0, 0, 1])
anchor_id = 2
dist_from_anchor = np.abs(user_ids - anchor_id)
dist_from_anchor[valid_user == 0] = len(user_ids) +1 #will not be the min
print(np.argmin(dist_from_anchor))
I used the minimum user_id as 0 (just a cs thing...) but you can easily change it to be 1...
I suggest a different approach (Dont know how flexible you are with your approach)-
Store your data like this
dict2 = {"1": {1, 2, 5}, "0": {3, 4}} # 1 for available Ids and 0 for allocated
Now for any incoming user id
if usr_id in dict2["1"]:
allotted_id = usr_id
elif usr_id in dict2["0"]:
# either return the first available Or
# traverse and return the next higher user id available
else:
# exception
I need to write a code, where for every time someone buys a product, the key in the demand dictionary increases by 1.
I couldn't figure out how to increase a key in a dictionary byknowing the value.
This is what I tried:
demand = {"bread":0,"butter":0,"cheese":0, "water":0,"ice cream":0}
# bread is the value and 0 is the key, which I want to increase every time
def bill(buy_lst):
for item in buy_lst:
demand[demand.get(item)] += 1
When I run it says:
demand[demand.get(item)] += 1
KeyError: 0
Thank you!
Your issue is how you are adding to the dictionary. Notice the following:
demand = {"bread": 0, "butter": 0, "cheese": 0, "water": 0, "ice cream": 0}
buy_lst = ["bread", "butter", "bread"]
def bill(buy_lst):
for item in buy_lst:
print(demand.get(item))
#demand[demand.get(item)] += 1
bill(buy_lst)
This outputs:
0
0
0
So in other words, in your:
demand[demand.get(item)] += 1
You are doing:
demand[0] += 1
Which will return the error:
Traceback (most recent call last):
File "/Users/felipefaria/Desktop/test/main.py", line 11, in <module>
bill(buy_lst)
File "/Users/felipefaria/Desktop/test/main.py", line 8, in bill
demand[demand.get(item)] += 1
KeyError: 0
Instead, you should be simply referring to the item itself within the brackets, like so:
demand = {"bread": 0, "butter": 0, "cheese": 0, "water": 0, "ice cream": 0}
buy_lst = ["bread", "butter", "bread"]
def bill(buy_lst):
for item in buy_lst:
demand[item] += 1
bill(buy_lst)
print(demand)
Which will output:
{'bread': 2, 'butter': 1, 'cheese': 0, 'water': 0, 'ice cream': 0}
I think you tried to mean was 'increasing value of a key that I know'. Because only values are ints so only they can be incremented. So incrementing value would be:
demand = {"bread":0,"butter":0,"cheese":0, "water":0,"ice cream":0}
def bill(buy_lst):
for item in buy_lst:
demand[item] += 1
For clarifying, dictionary item's first part is key and second part is value.
You seems to misunderstand key and value, in your case the string are the keys and their quantity is the value
demand = {"bread": 0, "butter": 0, "cheese": 0, "water": 0, "ice cream": 0}
So what you want is increase value given a key
buy_lst[item] += 1
To use it, you need something that ask the user one product like
def bill(buy_lst):
item = None
while not item:
item = input("Please select in " + str(list(buy_lst.keys())))
item = item if item in buy_lst else None
buy_lst[item] += 1
if __name__ == '__main__':
demand = {"bread": 0, "butter": 0, "cheese": 0, "water": 0, "ice cream": 0}
bill(demand)
print(demand)
You might be confusing key and value. In demand, the keys are the items and the values are the counts.
#!/usr/bin/env python
demand = {"bread":0, "butter":0, "cheese":0, "water":0, "ice cream":0}
def bill(buy_list):
for item in buy_list:
demand[item] += 1
buy_list = ["bread", "water"]
print("Before billing:")
print(demand)
bill(buy_list)
print("After billing")
print(demand)
This prints:
Before billing:
{'bread': 0, 'butter': 0, 'cheese': 0, 'water': 0, 'ice cream': 0}
After billing
{'bread': 1, 'butter': 0, 'cheese': 0, 'water': 1, 'ice cream': 0}
Your problem is really simple. You just have to add the operator * in front of the function parameter buy_lst, so you will have *buylst. See the below code:
demand = {"bread":0,"butter":0,"cheese":0, "water":0,"ice cream":0}
# bread is the value and 0 is the key, which I want to increase every time
def bill(*buy_lst): # see this line
for item in buy_lst:
demand[item] += 1 # see this line
bill("bread", "cheese") # The client buys the products `bread` and `cheese`
print(demand)
bill("bread", "cheese", "water", "butter")
print(demand)
Output
{'bread': 1, 'butter': 0, 'cheese': 1, 'water': 0, 'ice cream': 0}
{'bread': 2, 'butter': 1, 'cheese': 2, 'water': 1, 'ice cream': 0}
I am very new to python and looking for a way to simplify the following:
if atotal == ainitial:
print: "The population of A has not changed"
if btotal == binitial:
print: "The population of B has not changed"
if ctotal == cinitial:
print: "The population of C has not changed"
if dtotal == dinitial:
print: "The population of D has not changed"
Obviously _total and _initial are predefined.
Thanks in advance for any help.
You can use two dictionaries:
totals = {'A' : 0, 'B' : 0, 'C' : 0, 'D' : 0}
initials = {'A' : 0, 'B' : 0, 'C' : 0, 'D' : 0}
for k in initials:
if initials[k] == totals[k]:
print "The population of {} has not changed".format(k)
A similar way is first determining not changed populations:
not_changed = [ k for k in initials if initials[k] == totals[k] ]
for k in not_changed:
print "The population of {} has not changed".format(k)
Or, you can have a single structure:
info = {'A' : [0, 0], 'B' : [0, 0], 'C' : [0, 0], 'D' : [0, 0]}
for k, (total, initial) in info.items():
if total == initial:
print "The population of {} has not changed".format(k)
You could organize all the pairs into a dictionary and cycle though all the elements:
populations = { 'a':[10,80], 'b':[10,56], 'c':[90,90] }
for i in populations:
if populations[i][1] == populations[i][0]:
print(i + '\'s population has not changed')
Another way (2.7) using an ordered dictionary:
from collections import OrderedDict
a = OrderedDict((var_name,eval(var_name))
for var_name in sorted(['atotal','ainitial','btotal','binitial']))
while True:
try:
init_value = a.popitem(last=False)
total_value = a.popitem(last=False)
if init_value[1] == total_value[1]:
print ("The population of {0} has "
"not changed".format(init_value[0][0].upper()))
except:
break
I'm writing the following code and I'm trying not to add ' ' (a single space character) to my dictionary. I thought the following would work for my function. Do I need to write a more in-depth try and except statement? I get a KeyError when I run the code as is.
score = {"a": 1, "c":3, "b":3, "e": 1, "d": 2, "g": 2, "f": 4, "i" : 1, "h" : 4, "k": 5, "j" : 8, "m": 3, "l":1, "o": 1, "n":1,
"q":10, "p": 3, "s": 1, "r": 1, "u":1, "t": 1, "w": 4, "v": 4,"y": 4, "x": 8, "z": 10,}
def scrabble_score(word):
total = 0
for i in word:
total += score[i.lower()]
if i == ' ':
continue
return total
print scrabble_score('ten')
print scrabble_score('i like chicken')
In my opinion it would be better to ignore any char that is not in the table, not just spaces.
For this you can use
for c in word:
total += score.get(c, 0)
the second parameter of dict.get is the value to use if the value is not present in the dictionary.
Just change the if-statement with the previous line:
total += score[i.lower()]
if i == ' ':
continue
Id est, use:
if i == ' ':
continue
total += score[i.lower()]
edit: removed wrong explanation, see comments.