Saturday, 21 April 2018

Python - OOPS--getter,setter -- Day 26

  • this explains setter ,getter and decorator
  • https://www.udemy.com/python-the-complete-python-developer-course/learn/v4/t/lecture/6022196?start=0
  •   
    #getter and setter
    #this program explains about the use of get and set methods and property keyword
    #this class will be imported in the getsetmain.py,there is no need of importing this class
    #but for the clarity and navigation purpose written as 2 programs
    
    #set and get nethods can be used to set as well as check certain conditions
    #the return variables and the assignment variable name s/b different ie..level:_lvel and lives:_lives
    #if not it will result in error due to recursive
    
    #few simple objectives like lives cannot be less than 0
    #and score multiplied by 1000 for each level are achieved
    class Player:
        def __init__(self,name):
            self.name = name
            self._lives=3
            self._level = 1
            self._score=0
    
        def _setlife(self,live):
            if live>=0:
                self._lives = live
            else:
                print('live cannot be negative')
                self._lives=0
    
        def _getlife(self):
            return self._lives
    
        def _setlevel(self,level):
            if level>=1:
                delta = level-self._level
                self._score += delta * 1000
                self._level = level
            else:
                print('level cannot be less than 1 ')
    
        def _getlevel(self):
            return self._level
    
        lives = property(_getlife,_setlife)
        level = property(_getlevel,_setlevel)
    
    ####decorator
    #this is similar to the property but with different syntax
    
    #getter
        @property
        def score(self):
            return self._score
    
    #setter
        @score.setter
        def score(self,score):
            self._score = score
    
    
        def __str__(self):
            return("{0.name};lives:{0.lives};level:{0.level};score:{0.score}".format(self))
     
    
  • main program using the above imported class
  •   
    #we can use getsetplayer.Player, but since it is tedious
    #we have used the from and import like below
    
    
    
    
    from getsetplayer import Player
    
    tim = Player('tim')
    # print(tim.name)
    # print(tim.lives)
    # print(tim.score)
    # print(tim.level)
    
    print(tim)
    tim.lives-=1
    print(tim)
    tim.lives-=1
    print(tim)
    tim.lives-=1
    print(tim)
    tim.lives-=1
    print(tim)
    tim.lives=3
    tim.level+=1
    print('*********')
    print(tim)
    tim.level+=1
    print(tim)
    print('*********')
    tim.score = 500
    print(tim)
     
    

    Python - OOPS Basics-avoid circular reference- Day 26(5 days later)

  • there is circular reference in this example ie the song class has the artist object referred in it , similarly album also has artist object reference,we can remove by using their name alone instead of the whole object
  • 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 (str): An artist name representing the songs creator.
            duration (int): The duration of the song in seconds.  May be zero
        """
    
        def __init__(self, title, artist, duration=0):
            self.name = 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: (str): The name of 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=""):
            self.name = name
            self.year = year
            if artist is None:
                self.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 the list.
            """
            song_found = find_object(songname,self.tracks)
            if song_found is None:
                song_found = Song(songname,self.artist)
                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 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 add_song(self, album_name, year, song_name):
            """Add a new song to the collection of albums
    
            This method will add the song to an album in the collection.
            A new album will be created in the collection if it doesn't already exist.
    
            Args:
                name (str): The name of the album
                year (int): The year the album was produced
                title (str): The title of the song
            """
            album_found = find_object(album_name, self.albums)
            if album_found is None:
                # print(name + " not found")
                album_found = Album(album_name, year, self.name)
                self.add_album(album_found)
            else:
                print("Found album " + album_name)
    
            album_found.add_song(song_name)
    
    
    def find_object(field, object_list):
        """Check 'object_list' to see if an object with a 'name' attribute equal to 'field' exists, return it if so."""
        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)
                # print("{}:{}:{}:{}".format(artist_field, album_field, year_field, song_field))
    
                new_artist = find_object(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.name}".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)
    
    
     
    

    Python - OOPS Basics-eg2 - artist,album,song - Day 26(5 days later)

  • 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)