Leo Leo - 6 months ago 10
Python Question

Some questions on a function

def get_party_stats(families, table_size=6):

"""To calculate the number of attendees and tables needed.

Args:
families(list): a list of members.
table_size(int): table size of 6.

Returns:
mixed: people count & table count.

Examples:

>>> get_party_stats([['Jan'], ['Jen', 'Jess'], ['Jem', 'Jack',
'Janis']])
'(6, 3)'
"""
table_num = 0
people_num = 0

for people in families:
table_num += -(-len(people)//table_size)
people_num += len(people)
return people_num, table_num


How do you get
people_num
to return
6
, if
len(people)
is only
3
. For
table_num
, having the negative signs in
-(-len(people)//table_size)
, what does that achieve? Is there another way to count for number of attendees and tables, using some simple examples? Thank you.

Answer

Since you sum over the sizes of each family people_num will come out as len(['Jan']) + len(['Jen', 'Jess']) + len(['Jem', 'Jack', 'Janis']) = 1 + 2 + 3 = 6.

The -(-len(people)//table_size) term is a bit sneaky but you will realize what it does by noting that a // b == floor(a / b). Integer division c = a // b is defined such that c is the biggest integer number such that c <= a / b (note that / means float-division here). This makes abs(a) // abs(b) != abs(a // b) when a / b < 0 but is exactly what you want when calculating the number of tables necessary in your function.

The following results may illustrate that:

 -1 // 6 == -1           1 // 6 == 0
 -2 // 6 == -1           2 // 6 == 0 
      ...                    ...
 -6 // 6 == -1           6 // 6 == 1 
 -7 // 6 == -2           7 // 6 == 1 
 -8 // 6 == -2           8 // 6 == 1
      ...                    ...
-12 // 6 == -2          12 // 6 == 2 
-13 // 6 == -3          13 // 6 == 2 

Another (maybe less elegant) way of calculating the number of tables necessary given people would be 1 + (len(people) - 1) // table_size.

Finally, the whole function could be made a lot shorter using list-comprehensions:

def get_party_stats(families, table_size=6):
    return (sum([len(f) for f in families]),
            sum([-(-len(f) // table_size) for f in families]))
Comments