I have a simple function which should update a certain column for certain users:
for key, group in groupby(list_i):
print key, type(key), len(list(group)), type(len(list(group)))
setattr(User.query.filter_by(id=key).first(), "number_of_rooms", len(list(group)))
db_session.commit()
I have a list (list_i) which has the data, simply look at the print:
The data is correct, the first number is the id of the user and the second is the value which should be assign to column number_of_rooms
The problem is it sets all values of the users to 0. I assume it is somehow an override issue of the last user, I dont know. The thing is if I change it to:
setattr(User.query.filter_by(id=key).first(), "number_of_rooms", 2)
It will change the value to 2 for all users with id=key so the function works. I am here very confused, because len(list(group)) is a simple integer and it should work.
EDIT:
I double checked everything, I also made an other test with a variable (t) which increments by 1 and added an onther print to check everything, with the variable it also works, how is that possible?
t = 0
for key, group in groupby(list_i):
print key, type(key), len(list(group)), type(len(list(group)))
my_user = User.query.filter_by(id=key).first()
setattr(my_user, "number_of_rooms", t)
print my_user.number_of_rooms
t+=1
db_session.commit()
The value of number_of_rooms changes:
As Roman Mindlin and glibdud have specified, list(group) can only be used once. Since group is of type <type 'itertools._grouper'>, after you iterate over group once (e.g. by calling list() on it), it's exhausted. The key is to save the list(group) inside a variable.
Here is the code that fixes the issue:
for key, group in groupby(list_i):
l_group = list(group)
print(l_group)
my_user = User.query.filter_by(id=key).first()
setattr(my_user, "number_of_rooms", len(l_group))
db_session.commit()
Related
Good morning,
I am having trouble pulling the correct value from my dictionary because there are similar keys. I believe I need to use the == instead of in however when I try to change if key in c_item_number_one: to if key == c_item_number_one: it just returns my if not_found: print("Specify Size One") however I know 12" is in the dictionary.
c_item_number_one = ('12", Pipe,, SA-106 GR. B,, SCH 40, WALL smls'.upper())
print(c_item_number_one)
My formula is as follows:
def item_one_size_one():
not_found = True
for key in size_one_dict:
if key in c_item_number_one:
item_number_one_size = size_one_dict[key]
print(item_number_one_size)
not_found = False
break
if not_found:
print("Specify Size One")
item_one_size_one()
The current result is:
12", PIPE,, SA-106 GR. B,, SCH 40, WALL SMLS
Specify Size One
To split the user input into fields, use re.split
>>> userin
'12", PIPE,, SA-106 GR. B,, SCH 40, WALL SMLS'
>>> import re
>>> fields = re.split('[ ,]*',userin)
>>> fields
['12"', 'PIPE', 'SA-106', 'GR.', 'B', 'SCH', '40', 'WALL', 'SMLS']
Then compare the key to the first field, or to all fields:
if key == fields[0]:
There are two usages of the word in here - the first is in the context of a for loop, and the second entirely distinct one is in the context of a comparison.
In the construction of a for loop, the in keyword connects the variable that will be used to hold the values extracted from the loop to the object containing values to be looped over.
e.g.
for x in list:
Meanwhile, the entirely distinct usage of the in keyword can be used to tell python to perform a collection test where the left-hand side item is tested to see whether it exists in the rhs-object's collection.
e.g.
if key in c_item_number_one:
So the meaning of the in keyword is somewhat contextual.
If your code is giving unexpected results then you should be able to replace the if-statement to use an == test, while keeping everything else the same.
e.g.
if key == c_item_number_one:
However, since the contents of c_item_number_one is a tuple, you might only want to test equality for the first item in that tuple - the number 12 for example. You should do this by indexing the element in the tuple for which you want to do the comparison:
if key == c_item_number_one[0]:
Here the [0] is telling python to extract only the first element from the tuple to perform the == test.
[edit] Sorry, your c_item_number_one isn't a tuple, it's a long string. What you need is a way of clearly identifying each item to be looked up, using a unique code or value that the user can enter that will uniquely identify each thing. Doing a string-match like this is always going to throw up problems.
There's potential then for a bit of added nuance, the 1st key in your example tuple is a string of '12'. If the key in your == test is a numeric value of 12 (i.e. an integer) then the test 12 == '12' will return false and you won't extract the value you're after. That your existing in test succeeds currently suggests though that this isn't a problem here, but might be something to be aware of later.
We are using a helpdesksystem which has an API and alot tickets created come from monitoring solutions like Nagios. The format is always the same, the problem is reported with "PROBLEM: description of the problem" and the Resolvement is reported with "OK: description of the problem". I now want to merge those two tickets where a problem and ok message have been posted in a specific timeframe (5minutes). Therefor:
I create a dictionary with the values of tickets from a helpdesk system.
The structure looks like this:
dictTickets[IssueID] = Subject, Date
IssueID = the unique identifier of the ticket.
I then check all Subjects from the "OK"-Messages and iterate through the dictionary to see if there was a PROBLEM-Message with the same Subject:
if any(tickets['Subject'][len(TermOk):] == first for first, second in dictProblems.values()):
Now comes the question:
If the same message is identified, i would need the key from the tickets-dictionary to identify the Ticket ID. I have the ticket ID from the OK-Message since i iterate through all of them, but i don't know how to get to the key from the dictionary where the value was matched.
Can you help?
any will stop at the first match, and won't tell you which one it is.
It's better to build a list comprehension with the matches and loop on dictionary key+values to test the values and yield the corresponding keys
search_for = tickets['Subject'][len(TermOk):]
result = [ticket_id for ticket_id,(first, second) in dictProblems.items() if search_for == first]
if result:
# there are matches
# print them or whatever
You can use next() with a generator expression:
next(ticket_id for ticket_id, (subject, _) in dictProblems.items() if tickets['Subject'][len(TermOk):] == subject)
You can also specify a default value for next() as the second argument so that if a ticket is not found with the given subject, it will return None, so that you can use it as your if condition as well, in place of any():
ticket_id = next((ticket_id for ticket_id, (subject, _) in dictProblems.items() if tickets['Subject'][len(TermOk):] == subject), None)
if ticket_id:
do_something(ticket_id)
Since a ticket ID is likely to be unique, next() is a good fit as it will return the value of the first match it finds.
I'm learning python and I'm trying to use this function I built and its not working. The function is not changing a single value in the dictionary as it is working now, although it should. I'd like to get some help
def delete_product(diction):
product_to_delete = raw_input()
for key,value in diction.items():
if key == product_to_delete:
value = value - 1
if (value == 0):
del diction[key]
print "removed"
raw_input()
print "we couldnt remove the product because it does not exist"
raw_input()
Mistake in this code snippet:
value = value - 1
if (value == 0):
del diction[key]
Instead of modifying value in the dictionary, you are only modifying local value. So, this function will delete the required entry only when value happens to be 1.
You can modify it as follows or any variation of it:
if value == 1:
del diction[key]
break
else:
diction[key] = value - 1
Moreover, please note that you have to break out of the for loop once the entry is deleted from the dictionary. If you modify the dictionary while you are iterating it, the iterator will not work after that. If you want to delete multiple keys in one iteration, first get list of all keys to be deleted within the loop and delete after the loop.
Im trying to do a simple check if there is 3 specific value in a string. If there is, the statement should return nothing, instead of save.
Here is my code, but I think the syntax is wrong:
if not ('2239687' or '2238484' or '2239440') in user_id:
#The user is not admin, save the user
web_user.save()
To elaborate, I want it to test if user_id is "2239687" or "2238484" or "2239440" (and not, for example, "002239440"). If the user_id is one of those three values (and ONLY those three values), the statement should return false.
if not any(x in user_id for x in ('2239687', '2238484', '2239440')):
#The user is not admin, save the user
web_user.save()
This checks whether none of the three string is present within user_id.
One more option:
if not any(idx in user_id for idx in ('2239687' ,'2238484' , '2239440')):
# do something
Try like this
if user_id not in ('2239687' ,'2238484' , '2239440'):
Or
if not user_id in ('2239687' ,'2238484' , '2239440'):
I want to assign key to dict without value. So i want to assign date to the dict
here my current code
desc_date = {}
date = ' '.join(line_of_list[0:2])
if desc_date.has_key(date):
# Not sure how to assign date to desc_date now
Checking for the existence of a key is really simple:
if date in desc_date:
# Yep, the key exists
You'd have to use a placeholder value if you want to make it "look" empty:
desc_date[date] = None # Or [] if you'll be storing multiple items per key.
You can't. Either use a set instead, or use a "fake" value such as None.