Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Download the ICStunes program (http://www.ics.uci.edu/~harris/python/ICStunes0.p

ID: 666781 • Letter: D

Question

Download the ICStunes program (http://www.ics.uci.edu/~harris/python/ICStunes0.py) on the lab machine (or whatever machine you and your partner are using) and run it to make sure it works. As you work on this part, make your changes in (copies of) the ICStunes.py file you downloaded; use your lab8.py file for the other parts of this assignment.

(2) As we did previously with the albums' year, title, length, and ID, write a key function and a call to the sort() method to sort the collection MUSIC by the number of tracks on each album, lowest to highest; then print the resulting collection using Album_str.

Next, sort the collection MUSIC by some other key to rearrange it. Then perform the number-oftracks sorting task by calling collection_sort and then printing the resulting sorted collection

(3) Write a function called unplayed_songs that takes a music collection (a list of albums) and returns a list of Songdisplays, one for each song that has never been played. Print the resulting list using Songdisplay_str. [Please note: At this point it should be clear to everyone that the print statement does not go inside the unplayed_songs function. That function, as specified above, returns a list of Songdisplays; you print that result in the calling program—where you call the function. That's what this problem specifies.]

(4) Write a function called length_from_songdisplay that takes a Songdisplay and returns the length of the song. (This is quick and easy.)

(5) Write a function called favorite_album that takes a list of albums and returns the album that is the "favorite." We'll define the favorite album as the one that the user has spent the most time listening to. [The total time the user has spent listening to an album is computed from the play counts and the song lengths.]

Figure out by hand which album in the collection MUSIC has the greatest listening time (it's okay to collaborate with your classmates outside of your partnership on this specific fact); then print (using Album_str, of course) the result of calling favorite_album on the collection MUSIC and see if it matches. [Hint: Songdisplays aren't involved in this part.]

Explanation / Answer

Note:

Solution:

from collections import namedtuple

#######################################

# Album, Song

#######################################

Album = namedtuple('Album', 'id artist title year songs')

# id is a unique ID number; artist and title are strings; year is a number,

#   the year the song was released; songs is a list of Songs

Song = namedtuple('Song', 'track title length play_count')

# track is the track number; title is a string; length is the number of

#   seconds long the song is; play_count is the number of times the user

#   has listened to the song

MUSIC = [

    Album(1, "Peter Gabriel", "Up", 2002,

        [Song(1, "Darkness", 411, 5),

         Song(2, "Growing Up", 453, 5),

         Song(3, "Sky Blue", 397, 2),

         Song(4, "No Way Out", 473, 2),

         Song(5, "I Grieve", 444, 2),

         Song(6, "The Barry Williams Show", 735, 1),

         Song(7, "My Head Sounds Like That", 389, 1),

         Song(8, "More Than This", 362, 1),

         Song(9, "Signal to Noise", 456, 2),

         Song(10, "The Drop", 179, 1)]),

    Album(2, "Simple Minds", "Once Upon a Time", 1985,

        [Song(1, "Once Upon a Time", 345, 9),

         Song(2, "All the Things She Said", 256, 10),

         Song(3, "Ghost Dancing", 285, 7),

         Song(4, "Alive and Kicking", 326, 26),

         Song(5, "Oh Jungleland", 314, 13),

         Song(6, "I Wish You Were Here", 282, 12),

         Song(7, "Sanctify Yourself", 297, 7),

         Song(8, "Come a Long Way", 307, 5)]),

    Album(3, "The Postal Service", "Give Up", 2003,

        [Song(1, "The District Sleeps Alone", 284, 13),

         Song(2, "Such Great Heights", 266, 13),

         Song(3, "Sleeping In", 261, 12),

         Song(4, "Nothing Better", 226, 18),

         Song(5, "Recycled Air", 269, 13),

         Song(6, "Clark Gable", 294, 12),

         Song(7, "We Will Become Silhouettes", 300, 11),

         Song(8, "This Place is a Prison", 234, 9),

         Song(9, "Brand New Colony", 252, 9),

         Song(10, "Natural Anthem", 307, 7)]),

    Album(4, "Midnight Oil", "Blue Sky Mining", 1989,

        [Song(1, "Blue Sky Mine", 258, 12),

         Song(2, "Stars of Warburton", 294, 11),

         Song(3, "Bedlam Bridge", 266, 11),

         Song(4, "Forgotten Years", 266, 8),

         Song(5, "Mountains of Burma", 296, 9),

         Song(6, "King of the Mountain", 231, 8),

         Song(7, "River Runs Red", 322, 9),

         Song(8, "Shakers and Movers", 268, 9),

         Song(9, "One Country", 353, 7),

         Song(10, "Antarctica", 258, 6)]),

  Album(5, "The Rolling Stones", "Let It Bleed", 1969,

        [Song(1, "Gimme Shelter", 272, 3),

         Song(2, "Love In Vain", 259, 2),

         Song(3, "Country Honk", 187, 0),

         Song(4, "Live With Me", 213, 2),

         Song(5, "Let It Bleed", 327, 2),

         Song(6, "Midnight Rambler", 412, 1),

         Song(7, "You Got the Silver", 170, 0),

         Song(8, "Monkey Man", 251, 13),

         Song(9, "You Can't Always Get What You Want", 448, 10)])

]

#######################################

# Sorting the collection

#######################################

# Sort the collection into chronological order

# The 'key=' argument of sort() takes a function---that function

#   takes an album and produces the value that will be used for

#   comparisons in the sort.

# So first we define that function

def Album_year(A: Album) -> int:

    ''' Return the album's year

    '''

    return A.year

MUSIC.sort(key=Album_year) # Oldest to newest

assert(MUSIC[0].title == "Let It Bleed") # Kind of a half-hearted test

assert(MUSIC[-1].title == "Give Up")

MUSIC.sort(key=Album_year, reverse=True) # Newest to oldest

assert(MUSIC[0].title == "Give Up") # Kind of a half-hearted test

assert(MUSIC[-1].title == "Let It Bleed")

# Sort the collection by Album title

def Album_title(A: Album) -> str:

    ''' Return the album's title

    '''

    return A.title

MUSIC.sort(key=Album_title)

assert(MUSIC[0].title == "Blue Sky Mining") # Kind of a half-hearted test

assert(MUSIC[-1].title == "Up")

# Sort the collection by length (playing time) of album

def Album_length(a: Album) -> int:

    ''' Return the total length of all the songs in the album

    '''

    total_length = 0

    for s in a.songs:

        total_length += s.length

    return total_length

MUSIC.sort(key=Album_length)

assert(MUSIC[0].title == "Once Upon a Time") # Kind of a half-hearted test

assert(MUSIC[-1].title == "Up")

# Sort the collection by Album id (as above)

def Album_id(A: Album) -> str:

    ''' Return the album's number

    '''

    return A.id

MUSIC.sort(key=Album_id)

## We can also write a conventional function to sort a collection, so

## we could say collection_sort(MUSIC, Album_length) instead of using

## the method notation MUSIC.sort(key=Album_length). We do this by

## PASSING A FUNCTION AS A PARAMETER (like the interchangeable

## attachment on a robot arm).

def collection_sort(C: 'list of Album', keyfunction: 'Function on Albums') -> None:

    ''' Sort collection according to specified key function

        Note that this function, like the sort() method, sorts the collection

        IN PLACE (by reference), so it changes the argument it was called with.

        That's why it doesn't RETURN anything.

    '''

    C.sort(key=keyfunction)

    return

collection_sort(MUSIC, Album_title)

assert(MUSIC[0].title == "Blue Sky Mining") # Kind of a half-hearted test

assert(MUSIC[-1].title == "Up")

collection_sort(MUSIC, Album_id) # Just to put it back in the original order

#######################################

# Top 10 most frequently played songs

#######################################

# Collect all the songs out of all the albums.

# To find the MOST frequent, just use the find-largest (king-of-the-hill) algorithm

# To find the top N is hard to code that way.

# Better: Take the list of songs, sort by play_count, take first 10 -- songlist[:10]

def Song_play_count(s: Song) -> int:

    ''' Return the number of times this song has been played

    '''

    return s.play_count

def all_songs(MC: 'list of Album') -> 'list of Song':

    ''' Return a list of all the Songs in a music collection (list of Album)

    '''

    result = [ ]

    for a in MC:

        result.extend(a.songs)

    return result

Songlist = all_songs(MUSIC)

assert(Songlist[0] == Song(1, "Darkness", 411, 5))

assert(Songlist[1] == Song(2, "Growing Up", 453, 5))

assert(Songlist[-1] == Song(9, "You Can't Always Get What You Want", 448, 10))

def top_n_played_songs(MC: 'list of Album', n: int) -> 'list of Song':

    ''' Return a list of the n most frequently played songs in MC

    '''

    Songlist = all_songs(MC)

    Songlist.sort(key=Song_play_count, reverse=True)

    return Songlist[:n]

assert(top_n_played_songs(MUSIC, 5) ==

       [Song(4, "Alive and Kicking", 326, 26),

        Song(4, "Nothing Better", 226, 18),

        Song(5, "Oh Jungleland", 314, 13),

        Song(1, "The District Sleeps Alone", 284, 13),

        Song(2, "Such Great Heights", 266, 13)])

###################################

# Song-displays

###################################

# But these songs don't have their album information! We removed it when we created

# the list of all songs. If we want to display selected songs on our iPod screen,

# we'd want to have the album information along with the song information.

# We could flatten out our data structure, storing a copy of the album

# information with each song:

#       1   Up Peter Gabriel 2002 1 Darkness   411   5

#       1   Up Peter Gabriel 2002 2 Growing Up   453 8

#       1   Up Peter Gabriel 2002 3 Sky Blue    397 2

#            ...

# This would work, but there's a lot of duplicate data---it would be wasteful of storage

# and error-prone to store our music data this way permanently.

# Instead, let's just get the album info that goes with a song WHEN WE NEED IT,

# during the computation. To do this, we define a structure that contains the

# info we need to display a song (on our iPod screen, e.g.)---song details plus

# the info we need from that song's album:

Songdisplay = namedtuple('Songdisplay', 'artist a_title year track s_title length play_count')

# We'll create these structures as we need them during the computation,

# discarding them as we're done; this doesn't affect the main, permanent

# list of albums (like the one we defined as MUSIC above).

def all_Songdisplays(MC: 'list of Album') -> 'list of Songdisplay':

    ''' Return a list of all the songs in the collection MC, in Songdisplay form

    '''

    result = [ ]

    for a in MC:

        result.extend(Album_to_Songdisplays(a))

    return result

def Album_to_Songdisplays(a: Album) -> 'list of Songdisplay':

    ''' Return a list of Songdisplays, one for each song in the album

    '''

    result = [ ]

    for s in a.songs:

        result.append(Songdisplay(a.artist, a.title, a.year,

            s.track, s.title, s.length, s.play_count))

    return result

def play_count_from_songdisplay(sd: Songdisplay) -> int:

    ''' Return the play_count from a Songdisplay

    '''

    return sd.play_count

def top_n_played(MC: 'list of Album', n: int) -> 'list of Songdisplay':

    ''' Return the top n most frequently played songs in MC

    '''

    list_of_Songdisplays = all_Songdisplays(MC)

    list_of_Songdisplays.sort(key=play_count_from_songdisplay, reverse=True)

    return list_of_Songdisplays[:n]

test_list = top_n_played(MUSIC, 3)

assert(test_list[0].s_title == "Alive and Kicking")

assert(test_list[0].a_title == "Once Upon a Time")

assert(test_list[-1].s_title == "Oh Jungleland")

assert(test_list[-1].a_title == "Once Upon a Time")

#Q2

'''Method to return number of tracks'''

def Album_tracknum(al:Album)->int:

   

    counttrack = 0

    for s in al.songs:

        counttrack+=1

    return counttrack

collection_sort(mu,Album_tracknum)               

for in in mu:

    print(Album_str(in))

mu.sort(key = Album_id)

print(collection_sort(MUSIC,Album_tracknum))

#Q3

'''Method to returns list of Song displays'''

def unplayed_songs(mic:'List of Albums')->list:

        tre = []

    for album in mic:

        for song in album.songs:

            if Song_play_count(song) == 0:

                tre.append(song)

    return tre

print(Songdisplay_str(unplayed_songs(MUSIC)))

#Q4

''' Method to return the length '''

def length_from_songdisplay(sd:Songdisplay)->int:

        return sd.length

#Q5

'''Method to returns total time of listening '''

def Song_listening_time(s:Song)->int:

        return s.play_count * s.length

'''Method to returns total time'''

def Album_listening_time(al:Album)->int:   

    tottime = 0

    for in in al.songs:

        tottime += Song_listening_time(in)

        return tottime

''' Method to Returns favorite album'''

def favorite_album(mic:'List of Albums')->list:

        f_albm = []

    collection_sort(mic,Album_listening_time)

    f_albm.append(mic[-1])

    return f_albm

for in in favorite_album(mu):

    print("Favorite Album: " , Album_str(in))

#Q6

'''Method to returns a list'''

def top_n(mic: 'list of Album', n:int, funcname,Bool)->'list of Songdisplay':

    lstsng_dsply = all_Songdisplays(mic)

    lstsng_dsply.sort(key = funcname, reverse = Bool)

    return lstsng_dsply[:n]

Songdisplay_str(top_n(mu, 3, play_count_from_songdisplay, True))

#Q7

'''Method to returns a list'''

def favorite_album2(mic:'List of album',fav_measure)->list:

    nwlst = []

    collection_sort(mic,fav_measure)

    nwlst.append(mic[-1])

    return(nwlst)

def Song_count(s:Song)->int:

    return s.play_count

def Album_count(al:Album)->int:

    totcnt = 0

    for in in al.songs:

        totcnt += Song_count(in)

    return totcnt

for in in (favorite_album2(mu,Album_count)):

    print(Album_str(in))

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote