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.
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'])
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.