SortStuff
SortStuff

Reputation: 3

Sort tuple inside tuple inside Dictionary?

I'm stuck on this Hackerrank question that I'm doing for practice and for the life of me can't seem to figure out how to sort a tuple inside a tuple?

For example, this is the input

2015-08, 2016-04

2015-08-15, clicks, 635
2016-03-24, app_installs, 683
2015-04-05, favorites, 763
2016-01-22, favorites, 788
2015-12-26, clicks, 525
2016-06-03, retweets, 101
2015-12-02, app_installs, 982
2016-09-17, app_installs, 770
2015-11-07, impressions, 245
2016-10-16, impressions, 567

And the output that I'm supposed to be getting is...

2016-03, app_installs, 683
2016-01, favorites, 788
2015-12, app_installs, 982, clicks, 525
2015-11, impressions, 245
2015-08, clicks, 635

But what I'm getting instead is

2016-03, app_installs, 683
2016-01, favorites, 788
2015-12, ('clicks', '525'), app_installs, 982
2015-11, impressions, 245
2015-08, clicks, 635

My issue is with the line that says 2015-12. I'm having a hard time arranging that alphabetically when there is more than one tuple.

This is my code

# Enter your code here. Read input from STDIN. Print output to STDOUT
from datetime import date

line = input()

startDate = line.split(',')[0]
startYear, startMonth = startDate.split('-')
startDate = date(int(startYear), int(startMonth), 1)

endDate = line.split(' ')[1]
endYear, endMonth = endDate.split('-')
endDate = date(int(endYear), int(endMonth), 1)

line = input()

d = {}
while True:
    try:
        line = input()
        currentDate = date(int(line.split('-')[0]), int(line.split('-')[1].split('-')[0]), 1)

        if startDate <= currentDate < endDate:
            engagement = line.split(',')[1].strip()
            totalEngage = line.split(',')[2].strip()
            correctDate = "{}-{}".format(currentDate.year, str(currentDate.month).zfill(2))
            if not correctDate in d:
                d[correctDate] = engagement, totalEngage
            else:
                d[correctDate] = d[correctDate], engagement, totalEngage
    except:
        break

for key in reversed(sorted(d)):
    fin = "{}, {}".format(key, ', '.join(map(str, d[key])))
    print(fin)

Any ideas what I'm doing wrong?

Thanks!

Upvotes: 0

Views: 136

Answers (1)

PodGen4
PodGen4

Reputation: 358

Before addressing the problem of sorting a one level deep nested tuple, I will show you an easier way to solve the Hackerrank problem itself.
The problem with your solution is this code segment.

if not correctDate in d:
    d[correctDate] = engagement, totalEngage
else:
    d[correctDate] = d[correctDate], engagement, totalEngage

Notice that this block of code that you wrote will produce a n level deep nested tuple if you you get n types of analytics in the same month. Here's a demonstration.

>>> d = {}
>>> d["2015-12"] = "clicks", 525
>>> d["2015-12"] = d["2015-12"], "app_installs", 982
>>> d
{'2015-12': (('clicks', 525), 'app_installs', 982)}
>>> d["2015-12"] = d["2015-12"], "downloads", 100
>>> d
{'2015-12': ((('clicks', 525), 'app_installs', 982), 'downloads', 100)}

You can use a list to store all types of analytics from the same month. Sorting that list with the first element in tuple being the key is much simpler.

Initialize your dictionary

d = collections.defaultdict(list)

Replace the problematic code segment with this-

d[correctDate].append( (engagement, totalEngage) )

Finally, you can display the output that is reverse chronologically sorted by date and alphabetically sorted within individual dates.

for key in reversed(sorted(d)):

    print("{}, {}".format(key,   ', '.join( [str(elem) for elem in sorted(a, key=lambda x: x[0])])))

Now, coming to the question of sorting a one level deep nested tuple. You will somehow have to flatten the nested tuples to sort them. Or you can bring all of the elements in the tuple to the same level.
A very clumsy way to do that would be-

nested_tuple = ( ("bar", 1), "foo", 3 )
result = []
for elem, i in enumerate(nested_tuple):
    if elem is tuple:
        result.append(elem)
    else:
        result.append( (elem, nested_tuple[i+1]) )
answer = sorted(result, key=lambda x: x[0])

Again, please note that using nested tuples is an unnecessarily complicated approach to solve this problem. But if you insist on using it, you can use recursion to sort arbitrary level deep nested tuples.

Upvotes: 2

Related Questions