I have the follow two queryset:
opus = Work_Music.objects.filter(composerwork__person=self.kwargs['pk'], level=0).order_by('date_completed')
event = LifeEvent.objects.filter(person=self.kwargs['pk']).order_by('date_end')
The first pulls the work of a composer and the second pulls his life events.
I want to create a nested dictionary: The first level is keyed by year. The second level has two keys 'work' and 'life'. It should be a list of values because there could be multiple work and events in a given year.
I have written following:
# timeline = defaultdict(list)
timeline = dict()
for o in opus:
if o.date_comp_f not in timeline:
timeline[o.date_comp_f] = {}
timeline[o.date_comp_f]['work'] = {}
timeline[o.date_comp_f]['work'].append(o)
else:
timeline[o.date_comp_f]['work'].append(o)
for e in event:
if e.date_end_y not in timeline:
timeline[e.date_end_y] = {}
timeline[e.date_end_y]['life'] = {}
timeline[e.date_end_y]['life'].append(e)
else:
timeline[e.date_end_y]['life'].append(e)
timeline = dict(timeline)
I also want to sort the first level key in chronological order. How do I do this? I keep getting Key errors.
You were using {} when you wanted to use a list? I'm guessing this was a typo, but here is the fix (with a few simplifications):
# timeline = defaultdict(list)
timeline = dict()
for o in opus:
if o.date_comp_f not in timeline:
timeline[o.date_comp_f] = {}
timeline[o.date_comp_f]['work'] = []
timeline[o.date_comp_f]['work'].append(o)
for e in event:
if e.date_end_y not in timeline:
timeline[e.date_end_y] = {}
timeline[e.date_end_y]['life'] = []
timeline[e.date_end_y]['life'].append(e)
timeline = dict(timeline)
If this doesn't work, (which I assume it doesn't) can you please provide the Work_Music and LifeEvents models?
Related
I would like to define an object and check if it is a
duplicate before creating it,as shown below.
if data['title'] in videos:
I'm hoping I can determine it this way.
How can I determine duplicates?
videos = []
throughs = []
for datas in files:
for data in datas:
tags = data["tags"].split()
tag_pks = list(
set([Tag.objects.get_or_create(name=tag)[0].pk for tag in tags])
)
#Around here, we want to make sure that the list called videos already contains data['title'].
video = Video(
title=data["title"],
thumbnail_url=data["thumbnail_url"],
preview_url=data["preview_url"],
embed_url=data["embed_url"],
embed_source=data["embed_source"],
duration=data["duration"],
published_at=data["published_at"],
)
for tag_pk in tag_pks:
throughs.append(
Video.tags.through(video_id=video.pk, tag_id=tag_pk)
)
videos.append(video)
Video.objects.bulk_create(videos)
Video.tags.through.objects.bulk_create(throughs)
Like you said if the title and the thumbnail_url are unique, do it like this:
videos = []
throughs = []
for datas in files:
for data in datas:
tags = data["tags"].split()
tag_pks = list(
set([Tag.objects.get_or_create(name=tag)[0].pk for tag in tags])
)
#Around here, we want to make sure that the list called videos already contains data['title'].
video = Video(
title=data["title"],
thumbnail_url=data["thumbnail_url"],
preview_url=data["preview_url"],
embed_url=data["embed_url"],
embed_source=data["embed_source"],
duration=data["duration"],
published_at=data["published_at"],
)
for tag_pk in tag_pks:
throughs.append(
Video.tags.through(video_id=video.pk, tag_id=tag_pk)
)
# before you put it in the list check if this obj is in the list already
# since it is empty for the first loop we will jump to the else and add the first one
if videos:
# then loop that list
for vid in videos:
# and check if the new obj is in that list
if vid.title != video.title and vid.thumbnail_url != video.thumbnail_url:
# if the condition is true that means it is not in the list so we can add
# otherwise we will skip
videos.append(video)
else:
videos.append(video)
Video.objects.bulk_create(videos)
Video.tags.through.objects.bulk_create(throughs)
I don't know if it's possible. Hopefully you guys knows what I try to do. I want to do the model changes in a FOR loop cause the keys of the values have always the same name as the model columns.
My current code:
sites = DataModel.objects.all()
for site in sites:
d = self.getDataBySoup(soup)
site.title = d['title']
site.text = d['text']
site.facebook = d['facebook']
site.twitter = d['twitter']
site.save()
As you can see, the keys are always the same as the django columns. So I thought its maybe possible to do it with less code.
What I tried (but it's not working):
sites = DataModel.objects.all()
for site in sites:
d = self.getDataBySoup(soup)
for key, value in d.items():
site.key = value
site.save()
I use Python 3.6
getDataBySoup Method is just returning a dict/array:
def getContentDataBySoup(self, soup):
data = {}
data['title'] = 'some text'
# etc
return data
etc.
sites = DataModel.objects.all()
for site in sites:
d = self.getDataBySoup(soup)
DataModel.objects.filter(id=site.pk).update(**d)
The code above would update each site entry with the data in the dictionary d. If you're using the update method it's important that you also specify the id, otherwise it won't know what entry to update.
I have this firebase data structure
I want to print all the keys under the firebase generated keys (i.e from 3030-00-809-7702 to newNSN) so I use this code
Inventory = db.child("Inventories").get()
for business in Inventory.each():
businessid = business.key()
productdb = db.child("Inventories").child(businessid).get()
for product in productdb.each():
productid = product.key()
print(businessid)
print(productid)
but I what I get is this
so only the last keys are being printed instead of all the keys. What am I doing wrongly and how can I get it to print all the keys ?
Just print the value at the current tree to get the whole thing
inventory = db.child("Inventories").get()
for business in inventory.each():
print(business.val())
Or you go iterate it, which is really inefficient to request N items from Firebase for N children.
inventorydb = db.child("Inventories")
for businessid in inventorydb.shallow().get().each():
productdb = inventory.child(businessid)
# print the ids
print([id for id in productdb.shallow().get()])
I have a list of country names in different languages that I am attempting to sort by their country name. Currently, the sort is based on the index value.
Here is my truncated list of country names:
ADDRESS_COUNTRY_STYLE_TYPES = {}
for language_code in LANGUAGES.iterkeys():
ADDRESS_COUNTRY_STYLE_TYPES[language_code] = OrderedDict()
if 'af' in LANGUAGES.iterkeys():
ADDRESS_COUNTRY_STYLE_TYPES['af'][0] = " Kies 'n land of gebied" # Select a country or territory
ADDRESS_COUNTRY_STYLE_TYPES['af'][1] = "Afganistan" #Afghanistan
ADDRESS_COUNTRY_STYLE_TYPES['af'][2] = "Åland" #Aland
ADDRESS_COUNTRY_STYLE_TYPES['af'][3] = "Albanië" #Albania
....
ADDRESS_COUNTRY_STYLE_TYPES['af'][14] = "Australië" #Australia
ADDRESS_COUNTRY_STYLE_TYPES['af'][15] = "Oostenryk" #Austria
ADDRESS_COUNTRY_STYLE_TYPES['af'][16] = "Aserbeidjan" #Azerbaijan
ADDRESS_COUNTRY_STYLE_TYPES['af'][17] = "Bahamas" #Bahamas
ADDRESS_COUNTRY_STYLE_TYPES['af'][18] = "Bahrein" #Bahrain
ADDRESS_COUNTRY_STYLE_TYPES['af'][19] = "Bangladesj" #Bangladesh
ADDRESS_COUNTRY_STYLE_TYPES['af'][20] = "Barbados" #Barbados
ADDRESS_COUNTRY_STYLE_TYPES['af'][21] = "Wit-Rusland" #Belarus
ADDRESS_COUNTRY_STYLE_TYPES['af'][22] = "België" #Belgium
....
Here is my code I have in my views.py file that calls the country names:
def get_address_country_style_types(available_languages, with_country_style_zero=True):
address_country_style_types = {}
preview_labels = {}
for code, name in available_languages:
address_country_style_types[code] = ADDRESS_COUNTRY_STYLE_TYPES[code].copy()
if not with_country_style_zero:
address_country_style_types[code].pop(0)
preview_labels[code] = ADDRESS_DETAILS_LIVE_PREVIEW_LABELS[code]
# in case preview labels are not defined for the language code
# fall back to 'en', which should always be there
if len(preview_labels[code]) == 0:
preview_labels[code] = ADDRESS_DETAILS_LIVE_PREVIEW_LABELS['en']
address_country_style_types = sorted(address_country_style_types, key=lambda x:x[1])
return address_country_style_types, preview_labels
The above code only returns the index number in the html drop down list. The issue is with the following line of code (or more to the point my lack of knowledge of how to get it working):
address_country_style_types = sorted(address_country_style_types, key=lambda x:x[1])
How do I return the sorted country list ? Am I using lambda in the correct way here? Should I be using lambda here?
I have been working on this over several days, my coding skills are not very strong, and I have read many related posts to no avail, so any help is appreciated.
I have read this blog about sorting a list of multilingual country names that appear in a form HTML select drop down list - which is essentially what I am attempting to do.
EDIT
Commenting out the line of code below in the code above does return a list of country names, but the country names are sorted by the index value not the country name.
address_country_style_types = sorted(address_country_style_types, key=lambda x:x[1])
I have failed to sort the multi-language country names programatically.
Instead, I copied the list into excel and hit the sort button (based on the translated country name - the index value stays uniform), then copied the data back to the file. Works as expected - just a lot of work.
I hope that this helps someone.
im creating a function that will handle xml data, the data can vary but the structure is the same :
events ( list like )
event
info
additional info
the function needs to create a dictionary that contains a mapping in which if the data being looped is not 0 then the data needs to be mapped in a dictionary, heres my solution:
def parse_items(self, xml):
""" Builds a dynamic dictionary tree wich holds each event in a dictionary
that can be accessed by number of event """
parsed_items = {}
parsed_item = {}
sub_info = {}
for num, item in enumerate(xml):
for tag in item:
if len(tag) != 0:
for info in tag:
sub_info[info.tag] = info.text
parsed_item[tag.tag] = sub_info
# Need to flush the dictionary else it will repeat info
sub_info = {}
else:
parsed_item[tag.tag] = tag.text
parsed_items[num] = parsed_item
# Need to flush the dictionary else it will repeat info
parsed_item = {}
return parsed_items
my question is, is there a way to make this dynamically without having to make for loops for every level of data ?
(Reposting as an answer, because the questioner intends to use the idea)
In the latest versions of Python, there are dict comprehensions as well as list comprehensions. Like this:
sub_info = {i.tag: i.text for i in tag}