Evan Cooper
Evan Cooper

Reputation: 146

'Merge' two objects in python

I'm trying to figure out how to 'merge' two objects together. My goal here is to merge two Album objects (code below). I need to be able to merge the tracks argument (which are lists) of multiple Album objects, only if the 'title' argument of the Album object is the same.

Basically, if I have an Album object where the length of the tracks argument is 1 and another album object where the length of the tracks argument is also 1, the new, or updated singular Album object needs to have a tracks argument with a length of 2.

I've posted my code to show how the objects are defined.

Thanks in advance!

Edit : Since each element in the tracks argument list are names of songs, I would like to keep the same elements and put them in the new or updated tracks argument. Rather than just changing the amount of elements, I need to have the exact elements from each object put into this 'new' object.

class Album(object) :
    def __init__(self, artist, title, tracks = None) :
        tracks = []
        self.artist = artist
        self.title = title
        self.tracks = tracks

    def add_track(self, track) :
        self.track = track
        (self.tracks).append(track)
        print "The track %s was added." % (track)

    def __str__(self) :
        if len(self.tracks) == 1 :
            return "Artist: %s, Album: %s [" % (self.artist, self.title) + "1 Track]"
        return "Artist: %s, Album: %s [" % (self.artist, self.title) + str(len(self.tracks)) + " Tracks]"

Upvotes: 4

Views: 11493

Answers (4)

user3885927
user3885927

Reputation: 3503

I am assuming that you will be merging the tracks of the albums only if artist and the title are same. One way to do this is by defining your own merge function as below:

class Album(object) :
    def __init__(self, artist, title, tracks = None) :
        tracks = []
        self.artist = artist
        self.title = title
        self.tracks = tracks

    def add_track(self, track) :
        self.track = track
        (self.tracks).append(track)
        print "The track %s was added." % (track)

    def merge(self, album):
        if (type(self)==type(album)):
            if self.artist == album.artist and self.title==album.title:
                self.tracks.extend(album.tracks)
            else:
                print "cannot merge albums, artists or titles are not same"
        else:
            print "Invalid object types, cannot merge"
    def __str__(self) :
        if len(self.tracks) == 1 :
            return "Artist: %s, Album: %s [" % (self.artist, self.title) + "1 Track]"
        return "Artist: %s, Album: %s [" % (self.artist, self.title) + \
               str(len(self.tracks)) + " Tracks]"

Then if you have album a, you can call a.merge(b) After merge a.tracks should contain merged tracks. You need to make other changes as desired.

Upvotes: 0

John1024
John1024

Reputation: 113834

The merge algorithm has to know the internal data structure of the class. So, it seems logical to put the merge code inside the class. The code below does that and allows two albums to be merged simply adding them (album1 + album2):

class Album(object) :
    def __init__(self, artist, title, tracks = None) :
        self.artist = artist
        self.title = title
        self.tracks = tracks

    def add_track(self, track) :
        self.track = track
        (self.tracks).append(track)
        print "The track %s was added." % (track)

    def __str__(self) :
        if len(self.tracks) == 1 :
            return "Artist: %s, Album: %s [" % (self.artist, self.title) + "1 Track]"
        return "Artist: %s, Album: %s [" % (self.artist, self.title) + str(len(self.tracks)) + " Tracks]"

    def __add__(self, other):
        if self.artist != other.artist or self.title != other.title:
            raise ValueError("Albums are incommensurable")
        return Album(self.artist, self.title, self.tracks + other.tracks)

This is used as follows:

>>> a = Album('Joe', "Joe's First", tracks=['Beer', 'Trucks'])
>>> b = Album('Joe', "Joe's First", tracks=['Bourbon', 'Tequila'])
>>> complete = a + b
>>> print complete
Artist: Joe, Album: Joe's First [4 Tracks]
>>> complete.tracks
['Beer', 'Trucks', 'Bourbon', 'Tequila']

Upvotes: 7

wrgrs
wrgrs

Reputation: 2569

def merge_albums(album1, album2):
    if not album1.artist == album2.artist and \
            album1.title == album2.title:
        raise SomeException("Albums don't match")
    new_tracks = list(set(album1.tracks + album2.tracks))
    return Album(album1.artist, album1.title, new_tracks)

Upvotes: 0

Kasravnd
Kasravnd

Reputation: 107287

About keeping the same elements you don't need that you just need if condition to check before add tracks :

def add_track(self, track) :
    self.track = track
    if track not in (self.tracks) :
         (self.tracks).append(track)
    else :
         raise ValueError("duplicate track")
    print "The track %s was added." % (track)

Upvotes: 0

Related Questions