2
\$\begingroup\$

I created a computer program which takes a list of names and dishes chosen. The program then counts how many dishes and which dish are ordered. The result is then returned from a function. The algorithm is currently a brute force O(N*M) where N is the number of dishes and M is the number of people. Below is the code.


def count_items(rows, orders):
    counted = []
    has_found = False
    
    for row, order in enumerate(orders):
        has_found = False 
        for col, count in enumerate(counted):
            if count[0] == order[1]:
                has_found = True 
                counted[col] = (order[1], counted[col][1] + 1)  
        if not has_found:
            counted.append((order[1], 1))
    return counted 
                

def test_count_matching():
    assert count_items(0, []) == []
    assert count_items(1, [("Bob", "apple")]) == [("apple", 1)]
    assert count_items(2, [("Bob", "apple"), ("John", "apple")]) == [( "apple", 2)]
    assert count_items(2, [("Bob", "apple"), ("Bob", "apple")]) == [("apple", 2)]
    assert count_items(2, [("Bob", "apple"), ("John", "pear")]) == [("apple", 1), ("pear", 1)] 
   
def tests():
    test_count_matching()  

if __name__ == "__main__":
    tests() 
    

\$\endgroup\$

1 Answer 1

3
\$\begingroup\$
  • Add PEP484 typehints
  • Don't count things yourself when Counter exists and is more suitable for the task
  • rows is ignored, so drop it from your arguments list
  • Your assertions, main guard and function structure are pretty good; keep it up!

Suggested

from typing import Tuple, Iterable, Counter


def count_items(orders: Iterable[Tuple[str, str]]) -> Counter[str]:
    return Counter(order for user, order in orders)


def test_count_matching():
    assert count_items([]) == Counter()
    assert count_items([("Bob", "apple")]) == Counter({"apple": 1})
    assert count_items([("Bob", "apple"), ("John", "apple")]) == Counter({"apple": 2})
    assert count_items([("Bob", "apple"), ("Bob", "apple")]) == Counter({"apple": 2})
    assert count_items([("Bob", "apple"), ("John", "pear")]) == Counter({"apple": 1, "pear": 1})


def tests():
    test_count_matching()


if __name__ == "__main__":
    tests()
\$\endgroup\$
3
  • \$\begingroup\$ The counter's keys need to be the last part of the tuple and not include the person's name. The reason is that the kitchen knows the order and needs to know how many times to cook that dish to complete the order for a group of people. \$\endgroup\$ Oct 2, 2021 at 20:18
  • \$\begingroup\$ @AkashPatel The counter's keys need to be the last part of the tuple and not include the person's name - right... which is what's happening here. \$\endgroup\$
    – Reinderien
    Oct 2, 2021 at 20:30
  • \$\begingroup\$ Sorry, I think misinterpreted the order variable as having both. \$\endgroup\$ Oct 2, 2021 at 20:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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