user14363905
user14363905

Reputation:

Given one element of tuple, return the other

I'm attempting to work through this list of tuples to be able to pass through the role of one of the band members and return their name. I'm having a hard time finding examples out there to work through this problem and have only played around with getting the first element of each tuple, but I need to be able to put in a role and get a name:

'b.name("drummer") = "Nick"'

class Band:

    def __init__(self):
        self.band = [
            ("Nick", "drummer"),
            ("Dave", "singer"),
            ("Gary", "bass"),
            ("Bill", "guitar")
            ]

    def name(self):
        names = []
        for role in self.band:
            names.append(role[0])
            return names

b = Band()
b.name()

Upvotes: 0

Views: 82

Answers (2)

Derek Brown
Derek Brown

Reputation: 4419

Let's break this problem down a bit:

1. What are the inputs to your name function? What are the outputs to your name function?

Right now, your def name(self) takes no input. We instead need to take some input (the name of the role) to compute a result. We also probably want to ask whether multiple people can have the same role, so we might want to return a list instead of a single value:

def name(self, role : str) -> List[str]:

2. How do we find all the people with a given role?

Well, we can walk through all of the given role assignments, and check to see if the role matches the one we are looking for. Kindof like this:

def name(self, role : str) -> List[str]:
   result = []
   for assignment in self.band:
     if assignment[1] == role:
       result.append(assignment[0])
   return result

The above solution is functional, but a bit verbose. As you get more experienced as a programmer, you will realize this is a pretty common pattern we can solve with something called a list comprehension. This is just a shorthand for the thing we wrote above:

def name(self, role : str) -> List[str]:
   return [p[0] for p in self.band if p[1] == role]

NB: Using Types/Interfaces

As you learn coding, I encourage you to think about and note the various types and interfaces used in your programs. This will help you reason about your code. For example, you might represent this problem like so:

from typing import List, Tuple

BandListT = List[Tuple[str, str]]

class Band:
  members : BandListT
  def __init__(self, members : BandListT) -> None:
      self.members = members

  def get_names_by_role(self, role : str) -> List[str]:
      names = []
      for member in self.members:
        if member[1] == role:
            names.append(member[0])
      return names

BAND_MEMBERS : BandListT = [
    ("Nick", "drummer"),
    ("Dave", "singer"),
    ("Gary", "bass"),
    ("Bill", "guitar")
    ]        
b = Band(BAND_MEMBERS)
print(b.get_names_by_role("drummer"))

You will notice a few changes from your partial solution:

  • I pass the band members in as a parameter to the constructor. This is because we might want to have different bands with different members.
  • I defined BandListT as a type alias, so we can use this throughout our code
  • I renamed name to get_names_by_role to be a little more clear about the function of this method.
  • I added type annotations (str, Tuple, List) to make it clear to other developers and the typechecker what each variable represents.

These skills will serve you well as you continue your developer journey! Cheers!

Repl: https://replit.com/@DerekTBrown/ScratchyJadedFilename#main.py

Upvotes: 1

Mikail Khan
Mikail Khan

Reputation: 129

It looks like you're trying to implement an association list: https://en.wikipedia.org/wiki/Association_list

def get_name(self, role):
    # tuple destructuring is useful here
    for (current_name, current_role) in self.band:
        if current_role == role:
            return current_name
    
    # role was not found
    return None

Upvotes: 1

Related Questions