Home > OS >  How to reference a dictionary values from a Class to a method in another class in Python?
How to reference a dictionary values from a Class to a method in another class in Python?

Time:10-10

I'm currently learning Python and have the following 2 classes. I'm wondering if it is possible for the getGolfSetDetails method to reference the dictionary values from GolfSet class to the getDetails method from the Club class?

The data is as follows:

{'Wood': [['DRIVER', 'Wood', '10.5', '203', '450', '44.25', '68', 'Graphite', 'R', '0.6', '62', 'Rubber'],['5-WOOD', 'Wood', '17.5', '240', '280', '41.5', '85', 'Graphite', 'R', '0.6', '62', 'Rubber']],
'Iron': [['8-IRON', 'Iron', '37.0', '268', 'Cast', '36.5', '108', 'Steel', 'S', '0.6', '62', 'Rubber']],
'Putter': [['SUNSET', 'Putter', '3.0', '365', 'Mallet', '33.5', '120', 'Steel', 'S', '0.6', '62', 'Rubber']]}

getDetails from Club class will display the following which I would like to incorporate in the getGolfSetDetails in the GolfSet class

Club:  DRIVER     Loft:  10.5   Length:  46.12in   Flex:  S    Weight:  333g
Club:  8-IRON     Loft:  34.5   Length:  36.50in   Flex:  R    Weight:  439g
Club:  SUNSET     Loft:   3.0   Length:  33.50in   Flex:  S    Weight:  562g
class Club:

    def __init__(self, label, head, shaft, grip):
        self._label = label.upper()
        self._head = head
        self._shaft = shaft
        self._grip = grip

    def getDetails(self):
        return f'Club:  {self._label : ^5}     Loft:  {self.loft:>4.1f}   Length:  {self.length:>5.2f}in   Flex:  {self.flex}    Weight:  {self.weight}g'

class GolfSet():

    def __init__(self, ownerID, owner, newSet):
        #initialise attributes
        self._ownerID = ownerID.upper()
        self._owner = owner.title()
        self._clubs = {}

    if newSet == False:
        f = open(f'{self._ownerID}-{self._owner}.txt','r')
        lines = f.read().splitlines()
        f.close()
        for line in lines:
             index = line.split(',') [1] 
             if index in self._clubs.keys():
                 values = line.split(',')
                 self._clubs [index].append(values)

    def getGolfSetDetails(self):
        ????

CodePudding user response:

It is not only possible, it's the basis of object oriented programming. The best approach will depend on how you want to use your object. In this case it seems like a GolfSet is basically a collection of Clubs: if this is the case you can just create and manage your Club objects inside their respective GolfSet: change the line

self._clubs [index].append(values)

to

self._clubs [index].Club(*values)

and then you can do

def getGolfSetDetails(self):
    for c in self._clubs.values():
        c.getDetails()

Side note: why a dictionary? If you just use a meaningless index as the key then a list will probably be enough.

CodePudding user response:

I made a few changes to your code, commented below. The main issue here is that while you have defined the Club class, you haven't actually created objects/instances of it. Like gimix, I also recommend using a word other than "index" because dicts are not ordered - at least not in the exact same way that a tuple and list are. Thus, I encourage you to instead call the key a different name, such as club_num.

class Club:

    def __init__(self, label, head, shaft, grip):
        self._label = label.upper()
        self._head = head
        self._shaft = shaft
        self._grip = grip

    def getDetails(self):
        return f'Club:  {self._label : ^5}     Loft:  {self.loft:>4.1f}   Length:  {self.length:>5.2f}in   Flex:  {self.flex}    Weight:  {self.weight}g'

class GolfSet():

    def __init__(self, ownerID, owner, newSet):
        #initialise attributes
        self._ownerID = ownerID.upper()
        self._owner = owner.title()
        self._clubs = {}

        if newSet == False:
            f = open(f'{self._ownerID}-{self._owner}.txt','r')
            lines = f.read().splitlines()
            f.close()
            for line_num, line in enumerate(lines):
                club_num = line.split(',')[1]
                # only add this club if it is NOT already in _clubs
                if club_num not in self._clubs.keys():
                    values = line.split(',')

                    # make sure we have 4 items (label, head, shaft, grip) per line
                    if len(values) == 4:
                        label, head, shaft, grip = values
                    else:
                        raise ValueError(f"Expected 4 values on line {line_num}, got {len(values)}!")
                        
                    # create an instance of Club using the values
                    club_obj = Club(label, head, shaft, grip)

                    # add the new instance to the _clubs dict
                    self._clubs[club_num] = club_obj

    def getGolfSetDetails(self):
        # iterate over self._clubs and call the methods of each Club instance it contains
        for club_num in self._clubs.keys():
            club = self._clubs[club_num]
            print(club.getDetails())
  • Related