python, django, sending data to a template - python

EDIT: Updated code, im trying to create a new nested dictionary from the orginal results.
however the dictionary is currently not updating, its only adding/editing the last value
so my current context just has greg on it and no one else
my current code is as below
# Create your views here.
def index(request):
### Get all the Polices ###
context = {}
for objPolicy in objPolicyData['escalation_policies']:
strPolicyName = objPolicy['name']
if strPolicyName.lower().find('test') == -1:
context['strPolicyName'] = strPolicyName
obj = {}
for objOnCall in objPolicy['on_call']:
obj['strLevel'] = objOnCall['level']
obj['strStartDate'] = getDate(objOnCall['start'])
obj['strStartTime'] = getTime(objOnCall['start'])
obj['strEndDate'] = getDate(objOnCall['end'])
obj['strEndTime'] = getTime(objOnCall['end'])
objUser = objOnCall['user']
obj['strUsername'] = objUser['name']
obj['strUserMobile'] = getUserMobile(objUser['id'])
context['objUsers'] = obj
return render(request, 'oncall/rota.html', context)
sample data would be
Network Policy
Level 1: John Smith
Start date: 27 April
Start time: 8am
end Date: 05 May
end time: 8am
Level 2: Bob Smith
Start date: 27 April
Start time: 8am
end Date: 05 May
end time: 8am
Server Policy
Level 1: Jane Doe
Start date: 23 April
Start time: 8am
end Date: 02 May
end time: 8am
Level 2: Greg Brad
Start date: 23 April
Start time: 8am
end Date: 02 May
end time: 8am
and so on...
Update:
#Alix, your current solution gives me the below, i think i need nested lists? as the level 2 engineer gets posted twice instead of level 1 and level 2, also missing the policy names for each one
#!/usr/bin/python
# -*- coding: utf-8 -*-
{'policies': [{
'strStartTime': '09:00AM',
'strEndTime': '09:00AM',
'strLevel': 2,
'strUserMobile': u'01234 5678',
'strEndDate': 'Monday 02 May',
'strUsername': u'John Smith',
'strStartDate': 'Monday 25 April',
}, {
'strStartTime': '09:00AM',
'strEndTime': '09:00AM',
'strLevel': 2,
'strUserMobile': u'01234 5678'',
'strEndDate': 'Monday 02 May',
'strUsername': u'John Smith',
'strStartDate': 'Monday 25 April',
}, {
'strStartTime': '09:00AM',
'strEndTime': '05:00PM',
'strLevel': 1,
'strUserMobile': u'011151588',
'strEndDate': 'Thursday 28 April',
'strUsername': u'Jane Doe',
'strStartDate': 'Thursday 28 April',
}, {
'strStartTime': '05:00PM',
'strEndTime': '03:30PM',
'strLevel': 1,
'strUserMobile': 'User does not have a company phone no',
'strEndDate': 'Thursday 28 April',
'strUsername': u'Fred Perry',
'strStartDate': 'Wednesday 27 April',
}, {
'strStartTime': '09:00AM',
'strEndTime': '07:00AM',
'strLevel': 1,
'strUserMobile': 'User does not have a company phone no',
'strEndDate': 'Tuesday 03 May',
'strUsername': u'Sally Cinomon',
'strStartDate': 'Monday 25 April',
}]}

Just expanding my comment above with how to use the data in template:
You can send your data within render:
return render(request, "oncall/rota.html", {"policies": objPolicyData['escalation_policies'])
Then, in your template file, you can do something like this:
{% for policy in policies %}
{% for objOnCall in policy.on_call %}
<p> Level: {{ objOnCall.level }} </p>
<p> Start Time: {{ objOnCall.start }} </p>
{% endfor %}
{% endfor %}
UPDATE
According to the your last update to the question;
You said,
however the dictionary is currently not updating, its only
adding/editing the last value
This is right, because you don't have an array contains your policy objects. You only set the last value in the loop to the dictionary. This is why you are getting only last object.
This should do the work;
# Create your views here.
def index(request):
### Get all the Polices ###
policies = []
for objPolicy in objPolicyData['escalation_policies']:
strPolicyName = objPolicy['name']
policy = {}
policy['name'] = strPolicyName
if strPolicyName.lower().find('test') == -1:
policy = {}
policy['strPolicyName'] = strPolicyName # add policy name here
policy['objUsers'] = [] # define an empty array for users
for objOnCall in objPolicy['on_call']:
obj['strLevel'] = objOnCall['level']
obj['strStartDate'] = getDate(objOnCall['start'])
obj['strStartTime'] = getTime(objOnCall['start'])
obj['strEndDate'] = getDate(objOnCall['end'])
obj['strEndTime'] = getTime(objOnCall['end'])
objUser = objOnCall['user']
obj['strUsername'] = objUser['name']
obj['strUserMobile'] = getUserMobile(objUser['id'])
policy['objUsers'].append(obj) # add each user to the users array belongs to this policy object
policies.append(policy) # and finally append final and prepared policy object to our main policies array.
context = {"policies": policies}
return render(request, 'oncall/rota.html', context)
Now you can do anything you want with this array inside a for loop in template. (see my above example)

I think, this question is not good.
there are many kind of solution for your goal.
even, django documents.
this is just sample.
context = dict()
for objOnCall in objPolicy['on_call']:
obj = dict()
obj['strLevel'] = objOnCall['level']
obj['strStartDate'] = getDate(objOnCall['start'])
obj['strStartTime'] = getTime(objOnCall['start'])
obj['strEndDate'] = getDate(objOnCall['end'])
obj['strEndTime'] = getTime(objOnCall['end'])
obj['objUser'] = objOnCall['user']
obj['strUsername'] = objUser['name']
obj['strUserMobile'] = getUserMobile(objUser['id'])
context[objUser['name']] = obj
return render(request, 'oncall/rota.html', context)

Related

How to cycle through a defined list of elements

I have a large dictionary of lists which is generated dynamically as part of a larger python program. This is an example of what the dictionary looks like
params = {
'output': ['quantity_tot_1m', 'quantity_tot_3m', 'quantity_tot_6m',
'quantity_tot_12m', 'quantity_tot_full', 'cost_tot_1m', 'cost_tot_3m', 'cost_tot_6m', 'cost_tot_12m', 'cost_tot_full', 'selling_tot_1m',
'selling_tot_3m', 'selling_tot_6m', 'selling_tot_12m', 'selling_tot_full', 'profit_tot_1m', 'profit_tot_3m', 'profit_tot_6m', 'profit_tot_12m', 'profit_tot_full'],
'agg_types': ['By SKU - 01 Month','By SKU - 03 Months','By SKU - 06 Months','By SKU - 12 Months']
}
I need assistance being able to cycle over these lists
I have tried the below
from jinjasql import JinjaSql
j = JinjaSql(param_style='pyformat')
QUERY_TEMPLATE = """
{% set mix_agg = agg_types|replace("[","")|replace("]","") %}
{% set mix_agg2 = cycler(mix_agg) %}
{% for o in output %}
ROUND(CAST(SUM(CASE WHEN agg_type = '{{ mix_agg2.next() | sqlsafe }}' THEN profit_tot ELSE 0 END ) AS NUMERIC),2) AS {{o | sqlsafe}} {% endfor%}
"""
query, bind_params = j.prepare_query(QUERY_TEMPLATE, params)
print(query)
This doesn't cycle over the list, it merely outputs the list as is. Of course I cannot explicitly type the list into the cycler because this has to be dynamic.
Perhaps a cycler() isn't the best approach but I need an output like the below:
ROUND(CAST(SUM(CASE WHEN agg_type = 'By SKU - 01 Month' THEN profit_tot ELSE 0 END ) AS NUMERIC),2) AS profit_tot_1m,
ROUND(CAST(SUM(CASE WHEN agg_type = 'By SKU - 03 Months' THEN profit_tot ELSE 0 END ) AS NUMERIC),2) AS profit_tot_3m,
ROUND(CAST(SUM(CASE WHEN agg_type = 'By SKU - 06 Months' THEN profit_tot ELSE 0 END ) AS NUMERIC),2) AS profit_tot_6m,
ROUND(CAST(SUM(CASE WHEN agg_type = 'By SKU - 12 Months' THEN profit_tot ELSE 0 END ) AS NUMERIC),2) AS profit_tot_12m
not like this:
ROUND(CAST(SUM(CASE WHEN agg_type = 'By SKU - 01 Month', 'By SKU - 03 Months', 'By SKU - 06 Months', 'By SKU - 12 Months' THEN profit_tot ELSE 0 END ) AS NUMERIC),2) AS profit_tot_1m,
ROUND(CAST(SUM(CASE WHEN agg_type = 'By SKU - 01 Month', 'By SKU - 03 Months', 'By SKU - 06 Months', 'By SKU - 12 Months' THEN profit_tot ELSE 0 END ) AS NUMERIC),2) AS profit_tot_3m,
ROUND(CAST(SUM(CASE WHEN agg_type = 'By SKU - 01 Month', 'By SKU - 03 Months', 'By SKU - 06 Months', 'By SKU - 12 Months' THEN profit_tot ELSE 0 END ) AS NUMERIC),2) AS profit_tot_6m,
ROUND(CAST(SUM(CASE WHEN agg_type = 'By SKU - 01 Month', 'By SKU - 03 Months', 'By SKU - 06 Months', 'By SKU - 12 Months' THEN profit_tot ELSE 0 END ) AS NUMERIC),2) AS profit_tot_12m
There are a total of 20 output columns {{o | sqlsafe}}
The line
{% set mix_agg = agg_types|replace("[","")|replace("]","") %}
turns what was an array type into a string which just makes it harder to use later, and is probably not what you want.
The line
{% set mix_agg2 = cycler(mix_agg) %}
then creates a cycler with a single sting to cycle through - so it will repeatadly return this single string.
To cycle through an array use the python * operator - which turns an array into function arguments:
{% set mix_agg2 = cycler(*agg_types) %}
Putting this together we have:
QUERY_TEMPLATE = """
{% set mix_agg2 = cycler(*agg_types) %}
{% for o in output %}
ROUND(CAST(SUM(CASE WHEN agg_type = '{{ mix_agg2.next() | sqlsafe }}' THEN profit_tot ELSE 0 END ) AS NUMERIC),2) AS {{o | sqlsafe}}
{% endfor %}
"""
Furthermore: output includes _tot_full which is missing from agg_types. You can fix this by adding it to agg_types or removing it from output when they are defined, or adding a if to skip it in the loop.

Convert string to date using datefinder

An issue occurs when I try to find a date in a .txt file using datefinder. I have the feeling I am unnecessarily switching between data types to obtain the result I desire.
Underneath is a MWE which results in generator object, which in turn is empty when changed to a list. I would like to obtain a datetime in the format %d-%m-%Y.
MWE:
import datefinder
f = ['this is text', 'this is a date', '* Model creation date: Sun Apr 25 08:52:06 2021']
for line in f:
if "creation date" in line:
date_line = str(line)
rev_date = datefinder.find_dates(_date_line)
dateutil's parser seems to do a better job:
import dateutil
f = ['this is text', 'this is a date', '* Model creation date: Sun Apr 25 08:52:06 2021']
dates = []
for line in f:
try:
dates.append(dateutil.parser.parse(line, fuzzy=True))
except dateutil.parser.ParserError:
pass
print(dates)
# [datetime.datetime(2021, 4, 25, 8, 52, 6)]
For the specific use-case:
for line in f:
if "* Model creation date:" in line:
rev_date = dateutil.parser.parse(line, fuzzy=True)
break
print(rev_date)
# 2021-04-25 08:52:06
Seems datefinder.find_dates works based on :. If you can remove : character after creation date get right result.
If always your string include creation date: you can remove this substring after if statement:
import datefinder
f = ['this is text', 'this is a date', '* Model creation date: Sun Apr 25 08:52:06 2021']
for line in f:
if "creation date" in line:
date_line = line.replace('creattion date:', '')
rev_date = datefinder.find_dates(date_line)

For loop on a dictionary giving out of range error

I'm having troubles understanding dictionaries and for loop.
I have this example that takes a nested dictionary representing a playlist of songs. On the first example the code runs just fine, but when I try to create a function and try to clean up the code. It keeps saying index out of range. Can anybody throw their 2 cents.
Example playlist from a JSON file:
playlist = {
'title': 'faves',
' author': 'Me',
'songs': [
{
'title': 'song1',
'artist': ['john', 'smith'],
'genre': 'Pop',
'duration' : 3.23
},
{
'title': 'song2',
'artist': ['john2'],
'genre': 'Rock',
'duration' : 3.45
},
{
'title': 'song3',
'artist': ['john3', 'smith3'],
'genre': 'Jazz',
'duration' : 2.45
}
]
}
This first code byte works well and print the right strings.
sa = f" and {song['artist'][1]}"
for song in playlist['songs']:
print(f"{song['title']} by {song['artist'][0]}{sa if len(song['artist']) >= 2 else ''}, runtime: {song['duration']}, genre: {song['genre']}")
song1 by john and smith3, runtime: 3.23, genre: Pop
song2 by john2, runtime: 3.45, genre: Rock
song3 by john3 and smith3, runtime: 2.45, genre: Jazz
But here when I try to run this it says index out of range. It's calling artist_two, but is not supposed to do that unless there is more than one artist for a song.
def print_playlist(songs):
print(songs)
for song in songs:
title = song['title']
duration = song['duration']
genre = song['genre']
artists = song['artist']
artist_one = song['artist'][0]
artist_two = song['artist'][1]
sa = f" and {artist_two}"
print(f"{title} by {artist_one}{sa if len(artists) >=2 else ''}, runtime: {duration}, genre: {genre}")
print_playlist(playlist['songs'])
You can use this method to make a string of the names with " and " in between them.
artist_list=["John","Smith"]
y=" and ".join(str(x) for x in artist_list)
print(y)
This give the output of John and Smith
And if you make the artist list: ["John","Smith","Dave"]
Your output will look like John and Smith and Dave
As mentioned in the comment above, you are assuming there are always at least 2 elements in the artist_list. You should rather use an approach like mine that I found from Concatenate item in list to strings
Thank you Zack Tarr
final code looks like
def print_playlist(songs):
for song in songs:
title = song['title']
duration = song['duration']
genre = song['genre']
artists = song['artist']
artist_plus = " and ".join( artist for artist in artists)
print(f" {title} by {artist_plus if len(artists) >= 2 else artists[0]}, runtime: {duration}, genre: {genre}")
print_playlist(playlist['songs'])

Exception/Error Handling in Python

I have a class that I created, at the end of the task I have to create two lists: one for tweets and the other for tweet labels.
After initiation, I want to load the tweets from a file and from another file their labels. After loading I want to check that each tweet is a json object and that it has no error, if it does, then I want to remove it and remove the associated label if provided. Labels are either 'pos' or 'neg'.
class flu_tweets:
def __init__(self):
self.tweets = [] #init create empty tweet list
self.labels = [] #init create empty label list
def load(self, tweets_filename, labels_filename = ''):
open_tweet_file = open(tweets_filename, 'r')
for tweet in open_tweet_file:
if tweet !='\n' and tweet != '\r\n':
self.tweets.extend([tweet])
if labels_filename != '':
open_label_file = open(labels_filename, 'r')
for label in open_label_file:
if label != '\n' and label != '\r\n':
if label[3:] != '\n':
self.labels.extend([label[:3]])
else:
self.labels.extend([label])
open_label_file.close()
index_tweet = 0
for tweet in self.tweets:
try:
json.loads(tweet)
index_tweet += 1
break
except:
print(index_tweet-1)
self.tweets.pop(index_tweet-1)
if self.labels != []:
self.labels.pop(index_tweet-1)
open_tweet_file.close()
Right now the method doesn't do that, and upon checking the list it does contain non-json objects.
Below is a copy of text file used that has tweets in it:
{"created_at":"Fri Oct 20 14:35:19 +0000 2017","id":921384339421745153,"id_str":"921384339421745153","text":"RT #alvindchipmunk: Dont let the DNC slide with no handcuffs. https://t.co/h72q7lGAHF","source":"\u003ca href=\"http://twitter.com/download/iphone\" rel=\"nofollow\"\u003eTwitter for iPhone\u003c/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":3435638633,"id_str":"3435638633","name":"alwaystrump","screen_name":"rodilosso_patty","location":"New Jersey, USA","url":null,"description":"Let's not give the media the Race war they want. POTUS we have your back! MAGA","translator_type":"none","protected":false,"verified":false,"followers_count":2770,"friends_count":2048,"listed_count":183,"favourites_count":85745,"statuses_count":152520,"created_at":"Sat Aug 22 16:27:18 +0000 2015","utc_offset":null,"time_zone":null,"geo_enabled":true,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"C0DEED","profile_background_image_url":"http://abs.twimg.com/images/themes/theme1/bg.png","profile_background_image_url_https":"https://abs.twimg.com/images/themes/theme1/bg.png","profile_background_tile":false,"profile_link_color":"1DA1F2","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"profile_image_url":"http://pbs.twimg.com/profile_images/773719268026257410/AuXU_l-D_normal.jpg","profile_image_url_https":"https://pbs.twimg.com/profile_images/773719268026257410/AuXU_l-D_normal.jpg","profile_banner_url":"https://pbs.twimg.com/profile_banners/3435638633/1461499638","default_profile":true,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweeted_status":{"created_at":"Fri Oct 20 12:27:04 +0000 2017","id":921352064160034816,"id_str":"921352064160034816","text":"Dont let the DNC slide with no handcuffs. https://t.co/h72q7lGAHF","display_text_range":[0,41],"source":"\u003ca href=\"http://twitter.com\" rel=\"nofollow\"\u003eTwitter Web Client\u003c/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":35962023,"id_str":"35962023","name":"alvin maldonado","screen_name":"alvindchipmunk","location":"Bunnell, FL","url":"http://alvindchipmunk-theconservativecomet.blogspot.com/","description":"Artist-musician-Medical Professional-Patriot-Guns-God-Country & 2Unite with others of like mind 2 re-elect Trump, redecorate DC making d USA gr8 as it still is","translator_type":"none","protected":false,"verified":false,"followers_count":1660,"friends_count":2051,"listed_count":43,"favourites_count":2001,"statuses_count":16294,"created_at":"Tue Apr 28 02:43:18 +0000 2009","utc_offset":-14400,"time_zone":"Eastern Time (US & Canada)","geo_enabled":true,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"9818A1","profile_background_image_url":"http://pbs.twimg.com/profile_background_images/627772771741732864/MHLgViA4.jpg","profile_background_image_url_https":"https://pbs.twimg.com/profile_background_images/627772771741732864/MHLgViA4.jpg","profile_background_tile":true,"profile_link_color":"981CEB","profile_sidebar_border_color":"DE3C88","profile_sidebar_fill_color":"E887E8","profile_text_color":"333333","profile_use_background_image":true,"profile_image_url":"http://pbs.twimg.com/profile_images/542852260422639616/75bqMWY3_normal.jpeg","profile_image_url_https":"https://pbs.twimg.com/profile_images/542852260422639616/75bqMWY3_normal.jpeg","profile_banner_url":"https://pbs.twimg.com/profile_banners/35962023/1481464103","default_profile":false,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"quoted_status_id":920847040132792320,"quoted_status_id_str":"920847040132792320","quoted_status":{"created_at":"Thu Oct 19 03:00:17 +0000 2017","id":920847040132792320,"id_str":"920847040132792320","text":"I'm sick of all the evidence against the Democrats and no handcuffs. Retweet-\nif you agree!\n\n#realDonaldTrump \ud83c\uddfa\ud83c\uddf8","source":"\u003ca href=\"http://twitter.com/download/android\" rel=\"nofollow\"\u003eTwitter for Android\u003c/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":889982846428782592,"id_str":"889982846428782592","name":"c\u2113\u03b9\u03b7\u0442\u03c3\u03b7 \u043c\u03b9c\u043d\u03b1\u03b5\u2113","screen_name":"crusher614","location":"*not of this world","url":"https://www.youtube.com/channel/UCthNh_qChVqAh_zamo0IQxQ","description":"FMR U.S. Border Patrol | New Mexico SWAT Operator | Legend Who Lives Rent Free In The Minds of Liberals World Wide. #MAGA \u03bc\u03bf\u03bb\u1f7c\u03bd \u03bb\u03b1\u03b2\u03ad III","translator_type":"none","protected":false,"verified":false,"followers_count":19821,"friends_count":135,"listed_count":73,"favourites_count":16032,"statuses_count":7708,"created_at":"Tue Jul 25 22:57:00 +0000 2017","utc_offset":-25200,"time_zone":"America/Phoenix","geo_enabled":false,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"000000","profile_background_image_url":"http://abs.twimg.com/images/themes/theme1/bg.png","profile_background_image_url_https":"https://abs.twimg.com/images/themes/theme1/bg.png","profile_background_tile":false,"profile_link_color":"19CF86","profile_sidebar_border_color":"000000","profile_sidebar_fill_color":"000000","profile_text_color":"000000","profile_use_background_image":false,"profile_image_url":"http://pbs.twimg.com/profile_images/916414292882219008/fvSIJCC6_normal.jpg","profile_image_url_https":"https://pbs.twimg.com/profile_images/916414292882219008/fvSIJCC6_normal.jpg","profile_banner_url":"https://pbs.twimg.com/profile_banners/889982846428782592/1506312325","default_profile":false,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"is_quote_status":false,"quote_count":551,"reply_count":703,"retweet_count":15439,"favorite_count":13676,"entities":{"hashtags":[],"urls":[],"user_mentions":[{"screen_name":"realDonaldTrump","name":"Donald J. Trump","id":25073877,"id_str":"25073877","indices":[93,109]}],"symbols":[]},"favorited":false,"retweeted":false,"filter_level":"low","lang":"en"},"is_quote_status":true,"quote_count":0,"reply_count":0,"retweet_count":1,"favorite_count":0,"entities":{"hashtags":[],"urls":[{"url":"https://t.co/h72q7lGAHF","expanded_url":"https://twitter.com/crusher614/status/920847040132792320","display_url":"twitter.com/crusher614/sta\u2026","indices":[42,65]}],"user_mentions":[],"symbols":[]},"favorited":false,"retweeted":false,"possibly_sensitive":false,"filter_level":"low","lang":"en"},"quoted_status_id":920847040132792320,"quoted_status_id_str":"920847040132792320","quoted_status":{"created_at":"Thu Oct 19 03:00:17 +0000 2017","id":920847040132792320,"id_str":"920847040132792320","text":"I'm sick of all the evidence against the Democrats and no handcuffs. Retweet-\nif you agree!\n\n#realDonaldTrump \ud83c\uddfa\ud83c\uddf8","source":"\u003ca href=\"http://twitter.com/download/android\" rel=\"nofollow\"\u003eTwitter for Android\u003c/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":889982846428782592,"id_str":"889982846428782592","name":"c\u2113\u03b9\u03b7\u0442\u03c3\u03b7 \u043c\u03b9c\u043d\u03b1\u03b5\u2113","screen_name":"crusher614","location":"*not of this world","url":"https://www.youtube.com/channel/UCthNh_qChVqAh_zamo0IQxQ","description":"FMR U.S. Border Patrol | New Mexico SWAT Operator | Legend Who Lives Rent Free In The Minds of Liberals World Wide. #MAGA \u03bc\u03bf\u03bb\u1f7c\u03bd \u03bb\u03b1\u03b2\u03ad III","translator_type":"none","protected":false,"verified":false,"followers_count":19821,"friends_count":135,"listed_count":73,"favourites_count":16032,"statuses_count":7708,"created_at":"Tue Jul 25 22:57:00 +0000 2017","utc_offset":-25200,"time_zone":"America/Phoenix","geo_enabled":false,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"000000","profile_background_image_url":"http://abs.twimg.com/images/themes/theme1/bg.png","profile_background_image_url_https":"https://abs.twimg.com/images/themes/theme1/bg.png","profile_background_tile":false,"profile_link_color":"19CF86","profile_sidebar_border_color":"000000","profile_sidebar_fill_color":"000000","profile_text_color":"000000","profile_use_background_image":false,"profile_image_url":"http://pbs.twimg.com/profile_images/916414292882219008/fvSIJCC6_normal.jpg","profile_image_url_https":"https://pbs.twimg.com/profile_images/916414292882219008/fvSIJCC6_normal.jpg","profile_banner_url":"https://pbs.twimg.com/profile_banners/889982846428782592/1506312325","default_profile":false,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"is_quote_status":false,"quote_count":551,"reply_count":703,"retweet_count":15439,"favorite_count":13676,"entities":{"hashtags":[],"urls":[],"user_mentions":[{"screen_name":"realDonaldTrump","name":"Donald J. Trump","id":25073877,"id_str":"25073877","indices":[93,109]}],"symbols":[]},"favorited":false,"retweeted":false,"filter_level":"low","lang":"en"},"is_quote_status":true,"quote_count":0,"reply_count":0,"retweet_count":0,"favorite_count":0,"entities":{"hashtags":[],"urls":[{"url":"https://t.co/h72q7lGAHF","expanded_url":"https://twitter.com/crusher614/status/920847040132792320","display_url":"twitter.com/crusher614/sta\u2026","indices":[62,85]}],"user_mentions":[{"screen_name":"alvindchipmunk","name":"alvin maldonado","id":35962023,"id_str":"35962023","indices":[3,18]}],"symbols":[]},"favorited":false,"retweeted":false,"possibly_sensitive":false,"filter_level":"low","lang":"en","timestamp_ms":"1508510119668"}
{"created_at":"Fri Oct 20 14:35:19 +0000 2017","id":921384340113670149,"id_str":"921384340113670149","text":"RT #mitchelmusso: My girl is so fine! but gaw}
Now that last tweet is incomplete,I expect that my function should raise an error and eliminate it.

Optimal, pythonic way to match days of week with list of dicts

I got following piece of code:
mon = tue = wed = thu = fri = sat = sun = bh = None
for ot in shop_data['opening_time']:
if ot['day'] == 'Monday':
mon = ot
elif ot['day'] == 'Tuesday':
tue = ot
elif ot['day'] == 'Wednesday':
wed = ot
elif ot['day'] == 'Thursday':
thu = ot
elif ot['day'] == 'Friday':
fri = ot
elif ot['day'] == 'Saturday':
sat = ot
elif ot['day'] == 'Sunday':
sun = ot
elif ot['day'] == 'Bank holidays':
bh = ot
The structure of ot variable is either:
ot = {'day': 'Monday', 'closed': True}
or
ot = {
'day': choices.get(operating_time.day),
'open_time': operating_time.open_time,
'close_time': operating_time.close_time
}
and are used to describe opening hours of the shop, rendered in template
I would like to assign correct ot from a list to correct day of week in a better way
What is the python way to do that?
EDIT
That's the piece of code before "day of week" matching
shop_operating_time = OperatingTime.objects.filter(
place=place).order_by('day')
shop_operating_time_list = []
choices = dict((x, y) for x, y in DAY_CHOICES)
days = choices.itervalues()
operating_time_day = set()
for operating_time in shop_operating_time:
data = {
'day': choices.get(operating_time.day),
'open_time': operating_time.open_time,
'close_time': operating_time.close_time,
}
shop_operating_time_list.append(data)
operating_time_day.add(choices.get(operating_time.day))
remaing_days = set(days) - operating_time_day
for day in remaing_days:
data = {
'day': day,
'closed': True
}
shop_operating_time_list.append(data)
shop_data = {
'opening_time': shop_operating_time_list
}
I'd create a dictionary instead of 8 variables:
opening_times = {'mon': None, 'tue': None, ...}
Then you can easily assign based on the key. You can also use a class and setattr:
day = 'bh' if ot['day'] == 'Bank Holidays' else ot['day'].lower()[:3]
setattr(opening_times, day, ot)
Finally, you might even use exec (only in Python 2, and it's slow!):
exec("%s = ot" % var_name)
Modifying locals is not a good idea (thanks DSM!), even if it seems to work (sometimes).

Categories