this program needs a album file which can be downloaded
from udemy and place it in the appropriate working folder
this program explains how the class ,fields,methods can be used to store the set of
info with the same format(like artist,album,song)
class Song:
"""Class to represent a song
Attributes:
title (str): The title of the song
artist (Artist): An artist object representing the songs creator.
duration (int): The duration of the song in seconds. May be zero
"""
def __init__(self, title, artist, duration=0):
self.title = title
self.artist = artist
self.duration = duration
class Album:
""" Class to represent an Album, using it's track list
Attributes:
name (str): The name of the album.
year (int): The year was album was released.
artist: (Artist): The artist responsible for the album. If not specified,
the artist will default to an artist with the name "Various Artists".
tracks (List[Song]): A list of the songs on the album.
Methods:
add_song: Used to add a new song to the album's track list.
"""
def __init__(self, name, year, artist=None):
self.name = name
self.year = year
if artist is None:
self.artist = Artist("Various Artists")
else:
self.artist = artist
self.tracks = []
def add_song(self, song, position=None):
"""Adds a song to the track list
Args:
song (Song): A song to add.
position (Optional[int]): If specified, the song will be added to that position
in the track list - inserting it between other songs if necessary.
Otherwise, the song will be added to the end of the list.
"""
if position is None:
self.tracks.append(song)
else:
self.tracks.insert(position, song)
class Artist:
"""Basic class to store artist details.
Attributes:
name (str): The name of the artist.
albums (List[Album]): A list of the albums by this artist.
The list includes only those albums in this collection, it is
not an exhaustive list of the artist's published albums.
Methods:
add_album: Use to add a new album to the artist's albums list
"""
def __init__(self, name):
self.name = name
self.albums = []
def add_album(self, album):
"""Add a new album to the list.
Args:
album (Album): Album object to add to the list.
If the album is already present, it will not added again (although this is yet to implemented).
"""
self.albums.append(album)
def load_data():
new_artist = None
new_album = None
artist_list = []
with open("albums.txt", "r") as albums:
for line in albums:
# data row should consist of (artist, album, year, song)
artist_field, album_field, year_field, song_field = tuple(line.strip('\n').split('\t'))
year_field = int(year_field)
# print("{}:{}:{}:{}".format(artist_field, album_field, year_field, song_field))
if new_artist is None:
new_artist = Artist(artist_field)
elif new_artist.name != artist_field:
# We've just read details for a new artist
# store the current album in the currents artists collection then create a new artist object
new_artist.add_album(new_album)
artist_list.append(new_artist)
new_artist = Artist(artist_field)
new_album = None
if new_album is None:
new_album = Album(album_field, year_field, new_artist)
elif new_album.name != album_field:
# We've just read a new album for the current artist
# store the current album in the artist's collection then create a new album object
new_artist.add_album(new_album)
new_album = Album(album_field, year_field, new_artist)
# create a new song object and add it to the current album's collection
new_song = Song(song_field, new_artist)
new_album.add_song(new_song)
# After read the last line of the text file, we will have an artist and album that haven't
# been store - process them now
if new_artist is not None:
if new_album is not None:
new_artist.add_album(new_album)
artist_list.append(new_artist)
return artist_list
# print(artist_list)
def create_checkfile(artist_list):
"""Create a check file from the object data for comparison with the original file"""
with open("checkfile.txt", 'w') as checkfile:
for new_artist in artist_list:
for new_album in new_artist.albums:
for new_song in new_album.tracks:
print("{0.name}\t{1.name}\t{1.year}\t{2.title}".format(new_artist, new_album, new_song),
file=checkfile)
if __name__ == '__main__':
artists = load_data()
print("There are {} artists".format(len(artists)))
#
# create_checkfile(artists)
#In the previous program if the sort order of the artsist and album is ascending it will work properly,
but if it is changed ,then it will show the wrong count,this is because
the artsist object is created based oh the last inserted artist album..ie
if the 2 nd inserted object repeats again at the last line then it will be treated as
new artist again which is not the case
this problem will be solved if look at the object list ,whether the
artist or album list is already created or not ,if it
created we can simply get the name and make use of,this is explained in the nex example program
class Song:
"""
class to represent a song
Attributes:
title():The tile of the song
artist(Artist):An artist object representing the songs creator
duration (int):The duration of the song in seconds.May be Zero
"""
def __init__(self,title,artist,duration=0):
"""song init method
Args:
title(str):Initialises the 'title' attribute
artist(Artist):An artist object representing the songs creator
duration (optional int):initialise value to 'duration' attribute
will be defaulted to zero if not specified.
"""
self.title = title
self.artist = artist
self.duration = duration
class Album:
""" class to represent a album,using its track list
Attributes:
name (str):The name of the album.
year (int):The year the album was released.
artist :(Artist):The artist responsible for the album.If not specified,
the artist will default to an artist with the name "Various Artists".
tracks (List[Song]):A List of songs on the album
Methods:
add_song:used to add a new song to the albums track list
"""
def __init__(self,name,year,artist =None):
self.name = name
self.year = year
if artist is None:
self.artist = Artist("Various artists")
else:
self.artist = artist
self.tracks = []
def add_song(self,song,position = None):
"""Adds a song to the track list
Args:
song(Song):A song to add.
position (optional[int]):If specified,the song will be added to that position
in the track list - inserting it between other songs if necessary.
Otherwise,the song will be added to the end of tthe list
"""
if position is None:
self.tracks.append(song)
else:
self.tracks.insert(position,song)
class Artist:
"""Basic class to store artist details
Attributes:
name(str):The name of the artist
albums (List[Album]):A list of albums by this artist.
The list includes only those albums in this collection,it is
not an exhaustive list of the artist's published albums
Methods:
add_album:used to add a new album to the artists's album list
"""
def __init__(self,name):
self.name = name
self.albums = []
def add_album(self,album):
"""
Add a new album to the list.
Args:
album(Album):Album object to add to the list.
If the album is already present,it will not be added again (although it is yet to be implemented).
"""
self.albums.append(album)
def checkobjectexist (field,object_list):
for item in object_list:
if item.name == field:
return item
return None
def load_data():
new_artist = None
new_album = None
artist_list = []
with open("albums.txt","r") as albums:
for line in albums:
#data row should consist of (artist,album,year,song)
artist_field,album_field,year_field,song_field = tuple(line.strip('\n').split('\t'))
year_field = int(year_field)
if new_artist is None:
new_artist = Artist(artist_field)
artist_list.append(new_artist)
elif new_artist.name != artist_field:
#we have just read details for new artist
#check for the existence of the object
new_artist = checkobjectexist(artist_field,artist_list)
if new_artist is None:
new_artist = Artist(artist_field)
artist_list.append(new_artist)
new_album = None
if new_album is None:
new_album = Album(album_field,year_field,new_artist)
new_artist.add_album(new_album)
elif new_album.name != album_field:
#we have just read details for new album for the current artist
#check whether the album already exists in the list
new_album = checkobjectexist(album_field,new_artist.albums)
if new_album is None:
new_album = Album(album_field,year_field,new_artist)
new_artist.add_album(new_album)
#create a new song object and add it to the current album's collection
new_song = Song(song_field,new_artist)
new_album.add_song(new_song)
return artist_list
# def create_checkfile(artist_list):
# """Create a check file from the object data for comparison with the original file"""
# with open("checkfile.txt", 'w') as checkfile:
# for new_artist in artist_list:
# for new_album in new_artist.albums:
# for new_song in new_album.tracks:
# print("{0.name}\t{1.name}\t{1.year}\t{2.title}".format(new_artist, new_album, new_song),
# file=checkfile)
if __name__ == '__main__':
artists = load_data()
print(len(artists))
# for new_artist in artists:
# for new_album in new_artist.albums:
# print(new_album.name,new_album.tracks)
# create_checkfile(artists)
The below program produces the same result,except that the concepts that are used like checking the existence
of the artist and album are done inside the class
class Song:
"""
class to represent a song
Attributes:
title():The tile of the song
artist(Artist):An artist object representing the songs creator
duration (int):The duration of the song in seconds.May be Zero
"""
def __init__(self,title,artist,duration=0):
"""song init method
Args:
title(str):Initialises the 'title' attribute
artist(Artist):An artist object representing the songs creator
duration (optional int):initialise value to 'duration' attribute
will be defaulted to zero if not specified.
"""
self.name = title
self.artist = artist
self.duration = duration
class Album:
""" class to represent a album,using its track list
Attributes:
name (str):The name of the album.
year (int):The year the album was released.
artist :(Artist):The artist responsible for the album.If not specified,
the artist will default to an artist with the name "Various Artists".
tracks (List[Song]):A List of songs on the album
Methods:
add_song:used to add a new song to the albums track list
"""
def __init__(self,name,year,artist =None):
self.name = name
self.year = year
if artist is None:
self.artist = Artist("Various artists")
else:
self.artist = artist
self.tracks = []
def add_song(self,songname,position = None):
"""Adds a song to the track list
Args:
song(Song):A song to add.
position (optional[int]):If specified,the song will be added to that position
in the track list - inserting it between other songs if necessary.
Otherwise,the song will be added to the end of tthe list
"""
# print(self.name,self.tracks)
# print('***')
song_found = checkobjectexist(songname,self.tracks)
# print('***')
if song_found is None:
song_found = Song(songname,self.artist)
# print("Song Not Found")
if position is None:
self.tracks.append(song_found)
else:
self.tracks.insert(position,song_found)
class Artist:
"""Basic class to store artist details
Attributes:
name(str):The name of the artist
albums (List[Album]):A list of albums by this artist.
The list includes only those albums in this collection,it is
not an exhaustive list of the artist's published albums
Methods:
add_album:used to add a new album to the artists's album list
"""
def __init__(self,name):
self.name = name
self.albums = []
def add_album(self,album):
"""
Add a new album to the list.
Args:
album(Album):Album object to add to the list.
If the album is already present,it will not be added again (although it is yet to be implemented).
"""
self.albums.append(album)
def add_song(self,album_name,year,song_name):
album_found = checkobjectexist(album_name,self.albums)
if album_found is None:
# print("Album Not Found")
album_found = Album(album_name,year,self)
self.add_album(album_found)
else:
print("Found Album")
album_found.add_song(song_name)
def checkobjectexist (field,object_list):
for item in object_list:
if item.name == field:
return item
return None
def load_data():
artist_list = []
with open("albums.txt","r") as albums:
for line in albums:
#data row should consist of (artist,album,year,song)
artist_field,album_field,year_field,song_field = tuple(line.strip('\n').split('\t'))
year_field = int(year_field)
new_artist = checkobjectexist(artist_field,artist_list)
if new_artist is None:
new_artist = Artist(artist_field)
artist_list.append(new_artist)
new_artist.add_song(album_field,year_field,song_field)
return artist_list
# def create_checkfile(artist_list):
# """Create a check file from the object data for comparison with the original file"""
# with open("checkfile.txt", 'w') as checkfile:
# for new_artist in artist_list:
# for new_album in new_artist.albums:
# for new_song in new_album.tracks:
# print("{0.name}\t{1.name}\t{1.year}\t{2.title}".format(new_artist, new_album, new_song),
# file=checkfile)
if __name__ == '__main__':
artists = load_data()
print(len(artists))
# for new_artist in artists:
# for new_album in new_artist.albums:
# print(new_album.name,new_album.tracks)
# create_checkfile(artists)