0
\$\begingroup\$

I want to create a program that can print the number of movies that was watched by more than 3 people (data stored in a nested list as below ).

list_movies = [('Spiderman 3', ['John', 'jake','Ronald']),('Gravity',['james','jake','john','gerald']),
               ('Terminator',['Anne','Johnny','Peter','Ronald','Neville'])]



count2 = 0
for (movie,name) in list_movies:
    count = 0
    for (name) in list_movies:
        if name != '':
            count += 1
    if count > 3:
        count2 += 1

print(count)
print(count2)
\$\endgroup\$

closed as off-topic by 409_Conflict, t3chb0t, 200_success, Vogel612 Oct 23 '18 at 11:25

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Code not implemented or not working as intended: Code Review is a community where programmers peer-review your working code to address issues such as security, maintainability, performance, and scalability. We require that the code be working correctly, to the best of the author's knowledge, before proceeding with a review." – 409_Conflict, t3chb0t, 200_success, Vogel612
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 4
    \$\begingroup\$ What happens if you use list_movies = [('Gravity',['james','jake','john','gerald']), ('Terminator',['Anne','Johnny','Peter','Ronald','Neville'])]? Can you understand why? \$\endgroup\$ – 409_Conflict Oct 22 '18 at 7:38
  • \$\begingroup\$ Would you care to explain \$\endgroup\$ – Nisan Abeywickrama Oct 22 '18 at 11:40
  • \$\begingroup\$ Why are you using a tuple over a dict? \$\endgroup\$ – Fendec Oct 22 '18 at 11:44
  • \$\begingroup\$ Well, removing the spiderman movie will print 2 and 0 instead of the (I guess) expected 5 and 2. This means the code is not working as intended. \$\endgroup\$ – 409_Conflict Oct 22 '18 at 11:47
  • 2
    \$\begingroup\$ @MathiasEttinger To the best of the authors knowledge. I'm not sure if it falls in that category, else I'll make my answer a community answer.... \$\endgroup\$ – Ludisposed Oct 22 '18 at 11:56
2
\$\begingroup\$
  1. Make it a function

    This should really be a function for test ability, reuse ability

    It would need to be a function which accepts 2 parameters (The list we want to query, the amount of people have had to watch it)

    And it will return the amount of times this happened

    • Add doc strings to said function, so after a while when you come back to this code, you still understand what you have written

    For example:

    def list_movies(movie_list, n):
        """
        a method what returns the count of movies watched by more then n people
    
        args:
            movie_list (list): The list of movies in [(movie, [names]), ..]
            n (int): The amount of times the movies has need to be watched
    
        returns:
           The count of movies that has been watched by more then n people
        """
    
  2. Make proper tests

    if you had properly tested this code, @Mathias's comment would probably not be necessary

    There are a few good modules to test functionality doctest or unittests

    Let's use doctest and add some tests to the docstring:

    >>> count_movies_watched([('Spiderman 3', ['John', 'jake','Ronald']),('Gravity',['james','jake','john','gerald'])], 3)
    1
    
    >>> count_movies_watched([('Spiderman 3', ['John', 'jake','Ronald']),('Gravity',['james','jake','john','gerald'])], 4)
    0
    

Without even writing a single line of code, it's already more clear, what this function will do and what a correct answer will be.

Improving Code

  • You can use list comprehension and the built in sum to get a count of movies
  • Use _ for variables you don;t use later on

Netting me:

sum([1 if len(names) > n else 0 for _, names in movie_list])

But this can also be improved, as @Mathias correctly states

  • sum will accept any iterable there is no need for the list comprehension
  • sum can add bools as well so no need for the awkward ternary

Netting me:

sum(len(names) > n for _, names in movie_list)

Putting it all together

import doctest

def count_movies_watched(movie_list, n):
    """
    a method what returns the count of movies watched by more then n people

    args:
        movie_list (list): The list of movies in [(movie, [names]), ..]
        n (int): The amount of times the movies has need to be watched

    returns:
        The count of movies that has been watched by more then n people

    >>> count_movies_watched([('Spiderman 3', ['John', 'jake','Ronald']),('Gravity',['james','jake','john','gerald'])], 3)
    1

    >>> count_movies_watched([('Spiderman 3', ['John', 'jake','Ronald']),('Gravity',['james','jake','john','gerald'])], 4)
    0
    """
    return sum(len(names) > n for _, names in movie_list)

if __name__ == '__main__':
    doctest.testmod()
\$\endgroup\$
  • \$\begingroup\$ It would be great if i get a detailed code. This seems quite complicated as a I'm a beginner. \$\endgroup\$ – Nisan Abeywickrama Oct 31 '18 at 5:20
  • \$\begingroup\$ @NisanAbeywickrama As your questions is off topic, I'm afraid I won't be able to add much more to this answer. What is complicated for you, I might shed some light on it \$\endgroup\$ – Ludisposed Oct 31 '18 at 8:59

Not the answer you're looking for? Browse other questions tagged or ask your own question.