Home > OS >  Categorize a tuple from a list of tuples based on conditional statements
Categorize a tuple from a list of tuples based on conditional statements

Time:08-11

I hope you can help me with my logic conditions that i have been struggling with.

I have a list of tuples in the following format:

[(2, 1), (2, 2), (3, 1)]

Each tuple (person) contains two numbers. The first number is e.g. number of apples (a) and the second number is the number of bananas (b).

What I want is to find two tuples in the list of tuples and characterize them into two categories, let us say evil and good.

So the rule are in general: The person with most apples is good if the person has no bananas The person with most bananas is evil if the person has no apples

Example 1:

[(3, 0), (2, 1), (0, 3)]

Result

  • tuple with index 0 is good as it has the most apples
  • tuple with index 2 is evil as it has the most bananas

If a person has both apples and bananas, then I want the following: The person is good with the most apples and fewest bananas. However, if there is a person who has fewer bananas than the person with the most apples, then this person is the good person, as in these examples:

Example 2:

[(1, 0), (2, 1)]

Result

  • tuple with index 0 is good as it has an apple
  • tuple with index 1 is evil as it has a banana

Example 3:

[(2, 1), (2, 2), (3, 1)]

Result

  • tuple with index 1 is evil as it has the most bananas
  • tuple with index 2 has the good as it has the most apples and less than most bananas

Example 4:

[(2, 1), (2, 2), (2, 2)]

Result

  • tuple with index 1 and 2 is evil as it has the most bananas
  • tuple with index 0 has the good as it has the most apples and less than most bananas

What I have tried so far is to split the list of tuples into two lists, e.g.:

  • len_apples_per_person = (2, 2, 2)
  • len_bananas_per_person = (1, 2, 2)

But as the relationship between apples and bananas determines if a person is good or evil I don’t think it is the right way.

If a tuple in a list of tuples has (0,0) is should be ignored. I have a workaround for that but it is a bit clumsy so if anyone could come up with an idea on how to solve my issues, I will be so happy.

Below is a code example. I realize that I should have the min an max values outside the loop for efficiency and it doesn't change over. Anyway, this code example does not catch everything.

#Here we check which person is the good and evil
for idx in range(len(len_apples_per_person)):
    if len_apples_per_person[idx] == min(len_apples_per_person) and 
       len_bananas_per_person[idx]!=0:
        idx_evil = idx
    if len_apples_per_person[idx] ==  max(len_apples_per_person):
        idx_good = idx

print(idx_good, idx_evil)

I hope someone can help me with the logic.

CodePudding user response:

I managed to solve my own question after a very long time.

I ended up looking at the relationship between the apples and bananas which simplified the code quite a lot.

However, there was still some exceptions where I needed to add more code to get the correct index.

Below is a working code example where I go through 9 examples.

def retrieve_good_evil_idx(listoftuples=None):
"""
Retrieves the index of the good and evil in a list of tuples

"""
start_apple_to_banana = -1
start_banana_to_apple = -1
store_banana = 0
store_apple = 0

for idx, (apple, banana) in enumerate(listoftuples):
    try:
        apple_to_banana = apple/banana
        banana_to_apple = banana/apple
    except ZeroDivisionError:
        apple_to_banana = apple
        banana_to_apple = banana

    if apple_to_banana > start_apple_to_banana:
        idx_good = idx
        if banana_to_apple > start_banana_to_apple and idx != 0:
            idx_good = idx-1
        if store_apple == 0 and idx != 0:
            idx_good = idx

    if banana_to_apple > start_banana_to_apple:
        idx_evil = idx
        if store_apple == 0 and idx != 0:
            idx_evil = idx-1
    
    start_apple_to_banana = apple_to_banana
    start_banana_to_apple = banana_to_apple
    store_apple = apple
    store_banana = banana
    
return idx_good, idx_evil

apples_bananas = (
            [(2, 1), (2, 2), (3, 1)], 
            [(3, 0), (2, 1), (0, 3)], 
            [(1, 0), (2, 1)], 
            [(2, 1), (2, 2), (3, 1)], 
            [(2, 1), (2, 2), (2, 2)],
            [(1, 1), (1, 1)],
            [(1, 2), (1, 0)],
            [(0, 1), (1, 2)],
            [(1, 2), (2, 1)]
            )
print('(good index, evil index)')
for i in apples_bananas:
    print(retrieve_good_evil_idx(listoftuples=i))

(good index, evil index)
(2, 1)
(0, 2)
(0, 1)
(2, 1)
(0, 1)
(0, 0)
(1, 0)
(1, 0)
(1, 0)

I know the code is suboptimal so if you would help me optimizing the code and come up with feedback, I would be more than happy.

  • Related