Implementing 'delete' method syntax (and set) - python

I'm writing my first Python class and I was wondering if this was correct syntax to remove a particular 'song' from my dictionary.
I load data from a file onto a dictionary and store it.
Is this syntax correct?
def delete_song(id): #Do I need to do self_song(self, id) instead?
del self.song_names[id]
id is the song's ID, which is being passed. Does this delete a song from my dictionary? Earlier on in the code I had saved a song's name to self.song_names[id]= sname, which was from a component sname=components[1] from reading in the file.
Also, I'm having trouble understanding how to go about the set function. Is this start on the right track?
def set_song(id, list((title,genres))):
self.movie_names[id] = title
self.movie_genres[id] = genres
I figured out how to implement the get method and in it I use
self.song_names[id] = sname and
self.song_genres[id] = sgenre
Any tips?

You should read a chapter on classes here.
And, for deleting an entry from a dictionary, it is safer to use pop:
self.song_names.pop(id, None) <--- will not raise an error if id is not found
del self.song_names[id] <--- raises KeyError if id not found

Related

How to check if extended entity is present or not in tweepy response

I am able to fetch different tweet parameters from tweet.
keyword = tweepy.Cursor(api.search, val,tweet_mode='extended',lang='en').items(2)
tweetdone = 0
all_tweet = []
for tweet in keyword:
tweet_record = {}
tweet_record['tweet.text'] = tweet.full_text
tweet_record['tweet.user.name'] = tweet.user.name
tweet_record['tweet.user.location'] = tweet.user.location
tweet_record['tweet.user.verified'] = tweet.user.verified
tweet_record['tweet.lang'] = tweet.lang
tweet_record['tweet.created_at'] = tweet.created_at
tweet_record['tweet.user'] = tweet.user
tweet_record['tweet.retweet_count'] = tweet.retweet_count
tweet_record['tweet.favorite_count'] = tweet.favorite_count
I want to parse media objects from the tweet, but extended_entities in which media_url is present is not available in all tweets.
so if I try to fetch it like this:
tweet_record['media_url'] = tweet.extended_entities.media_url
It errors out because extended_entities may not be present in some tweets.
How to deal this issue and fetch media content correctly?
You have a couple of options here, you can check whether the key exists, or use some try/excepts.
Check whether key exists:
You can do this because tweepy returns a status object, which acts similarly to a json file, or python dictionary, and thus you essentially have a key:value pair. You should be able to use (going by your above code)
if 'extended_entities' in tweet:
tweet_record['media_url'] = tweet.extended_entities.media_url
of course, the reverse is also possible
if 'extended_entities' not in tweet:
#whatever you want to do
This could lead to problems though, what if the extended_entities exists, but for some reason media_url doesn't? And what if you want to get even more from within that (there isn't for a status object, but hey, I'm just trying to future proof here!) You'll have to do long, or multi nested if statements, which won't look the best
if 'extended_entities' in tweet:
if 'media_url' in tweet['extended_entities']
#etc
so it might be easier to just throw it in a try except...
try:
tweet_record['media_url'] = tweet.extended_entities.media_url
except AttributeError:
#etc
this means the program won't error when particular elements aren't found. AttributeError is for accessing an invalid attribute of an object. You of course may want to re-order this for readability. Keep in mind though, that while doing this is pythonic it can be a bit hard to read if used too often in my opinion.
I referred to this question when looking up things for this answer. Gives some good ideas for this sort of thing if you need further help.
Hope that helps.
Also, a good option is to use hasattr(Object, name) within an if-statement:
if hasattr(tweet, "extended_entities"):
\# do whatever

SmartSheet API python extended object

There are several objects in the SmartSheet SDK API which are extensions of objects. For instance, CellLink and ObjectValue are an extensions of the Cell object. I've done some reading and understand that these are parent/child classes and involve inheritance. However, this concept still escapes me and I cannot figure out the syntax for creating a CellLink object.
new_cell = ss.models.Cell()
linked_cell = ss.models.Cell()
linked_cell.column_id = int(columnid)
linked_cell.sheet_id = int(sheetid)
linked_cell.row_id = int(rowid)
new_cell.link_in_from_cell = linked_cell
The example above gives me the most informative error message therefore, I assume it is the closest to the correct syntax of all the variations I have tried. Any help with this example and possibly the underlying concept would be greatly appreciated.
raise ValueError("`{0}` invalid type for {1} value".format(value,
self.object_type))
ValueError: `{"columnId": 2068210422966148}` invalid type for <class
'smartsheet.models.cell_link.CellLink'> value
I believe I have found the answer to this question. It seems as though you just need to create a dictionary of the attributes like:
ex_dict = {sheet_id: 0974792938, column_id: 07263839242, row_id:
2632938474839}
new_cell.link_in_from_cell = ex_dict
The trick is later in the code. Instead of creating a new row like:
row = ss.models.Row()
You need to update an existing row like:
row = ss.Sheets.get_row(sheet_id, row_id)
However, I am still having a weird error of:
Field \"createdAt\" was of unexpected type.
You should be sending Row and Cell objects with only the properties that you wish to change. You do not want to attempt to modify an existing Row object (e.g. with the createdAt property, but rather allocate a new one with appropriate row id and cells to update.
See https://github.com/smartsheet-samples/python-snippets/blob/04951c2ca8ae1a97386bdd3fa6e010f2845e1421/samples.py#L45 for a complete example of creating a cell link.

Python dictionary append

I have trouble making my code work. I post only relevant part of the code.
File im using is in this page https://programmeerimine.cs.ut.ee/_downloads/lapsed.txt
First number is parent and 2nd his child. I also had different filed which translated numbers into name. (I made list ID_name it works fine i checked)
This other part of the code works fine except when I'm trying to add value to existing key.I get error AttributeError: 'str' object has no attribute 'append'
for line in f:
part=line.split(" ")
parent=part[0]
kid=part[1].strip()
for el in ID_name:
if parent == el[0]:
parent=el[1]
if kid == el[0]:
kid=el[1]
if parent not in parents.keys():
parents[parent]=kid
else:
parents[parent].append(kid)
The append function you're referencing only works for lists: https://docs.python.org/2/tutorial/datastructures.html
If you want to add a new key/value pair to a dictionary, use: dictionary['key'] = value .
You can also opt for: dictionary.update({'key': value}), which works well for adding multiple key/value pairs at once.
You need to initialize a list rather than just adding the object. Change this:
parents[parent]=kid
to this:
parents[parent] = [kid]
This will give you a list to which you can append() new objects, rather than just a string.

Get fields from a specific Jira issue

I'm trying to get all the fields and values from a specific issue my code:
authenticated_jira = JIRA(options={'server': self.jira_server}, basic_auth=(self.jira_username, self.jira_password))
issue = authenticated_jira.issue(self.id)
print issue.fields()
Instead of returning the list of fields it returns:
<jira.resources.PropertyHolder object at 0x108431390>
authenticated_jira = JIRA(options={'server': self.jira_server}, basic_auth=(self.jira_username, self.jira_password))
issue = authenticated_jira.issue(self.id)
for field_name in issue.raw['fields']:
print "Field:", field_name, "Value:", issue.raw['fields'][field_name]
Depends on field type, sometimes you get dictionary as a value and then you have to find the actual value you want.
Found using:
print self.issue_object.raw
which returns the raw json dictionary which can be iterate and manipulate.
You can use issue.raw['fields']['desired_field'], but this way is kind of indirectly accessing the field values, because what you get in return is not consistent. You get lists of strings, then just strings themselves, and then straight up values that don't have a key for you to access them with, so you'll have to iterate, count the location, and then parse to get value which is unreliable.
Best way is to use issue.fields.customfield_# This way you don't have to do any parsing through the .raw fields
Almost everything has a customfield associated with it. You can pull just issues from REST API to find customfield #'s, or some of the fields that you get from using .raw will have a customfield id that should look like "customfield_11111" and that's what you'll use.
Using Answer from #kobi-k but dumping in better format, I used following code:
with open("fields.txt", "w") as f:
json.dump(issue.raw, f, indent=4)
It dumped all the fields in a file with name "fields.txt"

Item won't update in database

I'm writing a method to update several fields in multiple instances in my database. For now, I'm trying to get it to work just for one.
My user uploads a CSV file with all the information to change (including the pk). I've written the function that parses all the information, and this all works fine. I can even assign the data to an item, and if I print it from that function, it comes out correctly. However, when I save the updates (using item.save()) nothing seems to change in the database.
Here's a very stripped down version of the method. I really don't know why it isn't working. I've done something very similar in other spots (getting data through a form, setting the field, calling save, and then displaying the changed information), and I've used a very similar CSV uploading technique to create new entries.
Small piece of relevant code:
reader = csv.reader(f)
for row in reader:
pk = row[0]
print(pk)
item = POObject.objects.get(pk=pk)
p2 = item.purchase2
print item.purchase.requested_start_date
print p2.requested_start_date
requested_start_date=row[6]
requested_start_date = datetime.datetime.strptime(requested_start_date, "%d %b %y")
print requested_start_date
p2.requested_start_date = requested_start_date
p2.save()
print p2.requested_start_date
item.purchase2 = p2
item.save()
print item.purchase.requested_start_date
return pk
Obviously I have lots of prints in there to find where stuff went wrong. Basically what I find is that if I look at item, it looks fine, but if I query the server again (after saving) i.e. dong item2=POObject.objects.get(pk=pk) it won't have had any updates. Does anyone have any idea why save() isn't doing anything?
UPDATE:
The mystery continues.
If I update a field that isn't contained within an FK relation (say, a text field or something), everything seems to work fine. However, what I really need to do is update an item, and then set that item as the fk relation to the main item in question. I'm not sure why this isn't working in the normal way (updating the internal item, saving it, and then setting the fk to that new, updated item).
Whoa. Feel a little ashamed that I didn't figure this out. I had forgotten exactly how I had designed one of my models, and there was another object within it that needed to be updated, but I wasn't saving it.

Categories