Guided Project: Profitable App exercise - dictionary to keep only max reviews

https://app.dataquest.io/m/350/guided-project%3A-profitable-app-profiles-for-the-app-store-and-google-play-markets/5/removing-duplicate-entries-part-two

Everything is fine until I reached this point:

If name already exists as a key in the reviews_max dictionary and reviews_max[name] < n_reviews , update the number of reviews for that entry in the reviews_max dictionary.

I do not understand this line of code :

  if name in reviews_max and reviews_max[name] < n_reviews:
        reviews_max[name] = n_reviews

It seems as if the name variable - a string datatype, is being compared to the number of reviews - an integer datatype, which does not make sense for comparison purpose and should result in a type mismatch.

I know a dictionary has a key:value pair and the key is a text string here and value an integer - number of reviews so how can instagram < 900000 this be done without causing error ? It does not make sense to me.

I do not see how this is being used to find out the app with the maximum number of reviews and thereby only keep the dictionary key with its corresponding value being the maximum reviews of integer type.

{Instagram: 100, Instagram: 1000, Instagram: 10000}

` ``
reviews_max[name] = n_reviews
This line seems to be assigning a float to a string? I.e replacing Instagram with its number of reviews. Which I also do not understand. I think my comprehension is wrong.

Please advise?

Thanks

reviews_max = {}

for app in android:
    name = app[0]
    n_reviews = float(app[3])
    
    if name in reviews_max and reviews_max[name] < n_reviews:
        reviews_max[name] = n_reviews
        
    elif name not in reviews_max:
        reviews_max[name] = n_reviews

Hi @jamesberentsen

I am not sure I completely understand your question but I think you’re wondering how reviews_max[name] is being compared to n_reviews? If yes, then you just have to think of ‘keys’ as an index to the ‘values’ in the dictionary. That means reviews_max[‘instagram’] stores an ‘int’ value in the memory which is being accessed when you type reviews_max[‘instagram’].

It the same way if you had a list and you wanted to access its fourth element, you’d type list_name[4]. It is not the value 4 that is stored in the list but some other value (string/int etc) that you had assigned to it.

So just as lists are indexed by numbers, dictionaries are indexed by keys.

Hope I was able to help clear up your confusion.

Hi plasmagirl,

Yes that is correct.

Many thanks for your reply. I think I understand now thanks to your explanation.

I was able to picture it when I read this part:

If yes, then you just have to think of ‘ keys ’ as an index to the ‘ values ’ in the dictionary. That means reviews_max[‘instagram’] stores an ‘ int ’ value in the memory which is being accessed when you type reviews_max[‘instagram’]

This was the exercise:

Create a dictionary where each key is a unique app name and the corresponding dictionary value is the highest number of reviews of that app.

Thanks,

Regards,
JB

Great @jamesberentsen. Happy to help!

Hi there,

I just wondered this checks if the existing review number(the one added in a previous loop iteration) is less than the one being looked at for the present iteration for the app of the same name and if so replace it with the present as it is a greater number?

  if name in reviews_max and reviews_max[name] < n_reviews:
        reviews_max[name] = n_reviews

Also I am not sure of the reasoning for this statement:

Make sure you don’t use an else clause here, otherwise the number of reviews will be incorrectly updated whenever reviews_max[name] < n_reviews evaluates to False .

I read that the difference between elif and else is that elif allows you to evaluate multiple statements before closing the loop,
but still I am not sure of causality/ why the wrong result would happen if ‘elif’ were replaced by ‘else’ in this context.

    if name in reviews_max and reviews_max[name] < n_reviews:
            reviews_max[name] = n_reviews
            
        elif name not in reviews_max:
            reviews_max[name] = n_reviews
    ```

Yes, you got the first part right! If the name already exists in the ‘key’ and if the value stored in the key is less than the value being looked at, it will be updated to the present value.


I think the basic difference between else and elif is that you can put a condition after elif and not after else. So in this case reviews_max[name] = n_reviews will only be executed if the condition name not in reviews_max is True.

If instead you had used

if name in reviews_max and reviews_max[name] < n_reviews:
    reviews_max[name] = n_reviews
else: 
    reviews_max[name] = n_reviews

it would always execute the ‘else’ statement when the ‘if’ statement was False. So if you already have a high value stored in the key reviews_max[‘Instagram’], then the else statement would overwrite it - giving us the wrong answer.

You can try it yourself by changing elif name not in reviews_max to just else and using the following dictionary

{Instagram: 100, Instagram: 10000, Instagram: 1000}

Hope this helps!

Many thanks, I get it now . That is a brilliant explanation.

@jamesberentsen

Thank you! :smile: