Advertisement
Guest User

Untitled

a guest
Nov 26th, 2014
363
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.63 KB | None | 0 0
  1. ## James Nguyen 36686189
  2.  
  3. #
  4. ## ICStunes: A Music Manager
  5. ##
  6. ## Original version ("InfxTunes") in Scheme by Alex Thornton,
  7. ## modified 2007 and 2008 by David G. Kay
  8. ## Python version by David G. Kay, 2012
  9.  
  10. from collections import namedtuple
  11. #######################################
  12. # Album, Song
  13. #######################################
  14.  
  15. Album = namedtuple('Album', 'id artist title year songs')
  16. # id is a unique ID number; artist and title are strings; year is a number,
  17. # the year the song was released; songs is a list of Songs
  18.  
  19. Song = namedtuple('Song', 'track title length play_count')
  20. # track is the track number; title is a string; length is the number of
  21. # seconds long the song is; play_count is the number of times the user
  22. # has listened to the song
  23.  
  24. MUSIC = [
  25. Album(1, "Peter Gabriel", "Up", 2002,
  26. [Song(1, "Darkness", 411, 5),
  27. Song(2, "Growing Up", 453, 5),
  28. Song(3, "Sky Blue", 397, 2),
  29. Song(4, "No Way Out", 473, 2),
  30. Song(5, "I Grieve", 444, 2),
  31. Song(6, "The Barry Williams Show", 735, 1),
  32. Song(7, "My Head Sounds Like That", 389, 1),
  33. Song(8, "More Than This", 362, 1),
  34. Song(9, "Signal to Noise", 456, 2),
  35. Song(10, "The Drop", 179, 1)]),
  36. Album(2, "Simple Minds", "Once Upon a Time", 1985,
  37. [Song(1, "Once Upon a Time", 345, 9),
  38. Song(2, "All the Things She Said", 256, 10),
  39. Song(3, "Ghost Dancing", 285, 7),
  40. Song(4, "Alive and Kicking", 326, 26),
  41. Song(5, "Oh Jungleland", 314, 13),
  42. Song(6, "I Wish You Were Here", 282, 12),
  43. Song(7, "Sanctify Yourself", 297, 7),
  44. Song(8, "Come a Long Way", 307, 5)]),
  45. Album(3, "The Postal Service", "Give Up", 2003,
  46. [Song(1, "The District Sleeps Alone", 284, 13),
  47. Song(2, "Such Great Heights", 266, 13),
  48. Song(3, "Sleeping In", 261, 12),
  49. Song(4, "Nothing Better", 226, 18),
  50. Song(5, "Recycled Air", 269, 13),
  51. Song(6, "Clark Gable", 294, 12),
  52. Song(7, "We Will Become Silhouettes", 300, 11),
  53. Song(8, "This Place is a Prison", 234, 9),
  54. Song(9, "Brand New Colony", 252, 9),
  55. Song(10, "Natural Anthem", 307, 7)]),
  56. Album(4, "Midnight Oil", "Blue Sky Mining", 1989,
  57. [Song(1, "Blue Sky Mine", 258, 12),
  58. Song(2, "Stars of Warburton", 294, 11),
  59. Song(3, "Bedlam Bridge", 266, 11),
  60. Song(4, "Forgotten Years", 266, 8),
  61. Song(5, "Mountains of Burma", 296, 9),
  62. Song(6, "King of the Mountain", 231, 8),
  63. Song(7, "River Runs Red", 322, 9),
  64. Song(8, "Shakers and Movers", 268, 9),
  65. Song(9, "One Country", 353, 7),
  66. Song(10, "Antarctica", 258, 6)]),
  67. Album(5, "The Rolling Stones", "Let It Bleed", 1969,
  68. [Song(1, "Gimme Shelter", 272, 3),
  69. Song(2, "Love In Vain", 259, 2),
  70. Song(3, "Country Honk", 187, 0),
  71. Song(4, "Live With Me", 213, 2),
  72. Song(5, "Let It Bleed", 327, 2),
  73. Song(6, "Midnight Rambler", 412, 1),
  74. Song(7, "You Got the Silver", 170, 0),
  75. Song(8, "Monkey Man", 251, 13),
  76. Song(9, "You Can't Always Get What You Want", 448, 10)])
  77. ]
  78. #######################################
  79. # Sorting the collection
  80. #######################################
  81.  
  82. # Sort the collection into chronological order
  83. # The 'key=' argument of sort() takes a function---that function
  84. # takes an album and produces the value that will be used for
  85. # comparisons in the sort.
  86. # So first we define that function
  87.  
  88. def Album_year(A: Album) -> int:
  89. ''' Return the album's year
  90. '''
  91. return A.year
  92.  
  93. MUSIC.sort(key=Album_year) # Oldest to newest
  94. assert(MUSIC[0].title == "Let It Bleed") # Kind of a half-hearted test
  95. assert(MUSIC[-1].title == "Give Up")
  96.  
  97. MUSIC.sort(key=Album_year, reverse=True) # Newest to oldest
  98. assert(MUSIC[0].title == "Give Up") # Kind of a half-hearted test
  99. assert(MUSIC[-1].title == "Let It Bleed")
  100.  
  101. # Sort the collection by Album title
  102. def Album_title(A: Album) -> str:
  103. ''' Return the album's title
  104. '''
  105. return A.title
  106.  
  107. MUSIC.sort(key=Album_title)
  108. assert(MUSIC[0].title == "Blue Sky Mining") # Kind of a half-hearted test
  109. assert(MUSIC[-1].title == "Up")
  110.  
  111. # Sort the collection by length (playing time) of album
  112. def Album_length(a: Album) -> int:
  113. ''' Return the total length of all the songs in the album
  114. '''
  115. total_length = 0
  116. for s in a.songs:
  117. total_length += s.length
  118. return total_length
  119.  
  120. MUSIC.sort(key=Album_length)
  121. assert(MUSIC[0].title == "Once Upon a Time") # Kind of a half-hearted test
  122. assert(MUSIC[-1].title == "Up")
  123.  
  124. # Sort the collection by Album id (as above)
  125. def Album_id(A: Album) -> str:
  126. ''' Return the album's number
  127. '''
  128. return A.id
  129.  
  130. MUSIC.sort(key=Album_id)
  131.  
  132. ## We can also write a conventional function to sort a collection, so
  133. ## we could say collection_sort(MUSIC, Album_length) instead of using
  134. ## the method notation MUSIC.sort(key=Album_length). We do this by
  135. ## PASSING A FUNCTION AS A PARAMETER (like the interchangeable
  136. ## attachment on a robot arm).
  137.  
  138. def collection_sort(C: 'list of Album', keyfunction: 'Function on Albums') -> None:
  139. ''' Sort collection according to specified key function
  140. Note that this function, like the sort() method, sorts the collection
  141. IN PLACE (by reference), so it changes the argument it was called with.
  142. That's why it doesn't RETURN anything.
  143. '''
  144. C.sort(key=keyfunction)
  145. return
  146.  
  147. collection_sort(MUSIC, Album_title)
  148. assert(MUSIC[0].title == "Blue Sky Mining") # Kind of a half-hearted test
  149. assert(MUSIC[-1].title == "Up")
  150.  
  151. collection_sort(MUSIC, Album_id) # Just to put it back in the original order
  152.  
  153.  
  154. #######################################
  155. # Top 10 most frequently played songs
  156. #######################################
  157.  
  158. # Collect all the songs out of all the albums.
  159. # To find the MOST frequent, just use the find-largest (king-of-the-hill) algorithm
  160. # To find the top N is hard to code that way.
  161. # Better: Take the list of songs, sort by play_count, take first 10 -- songlist[:10]
  162.  
  163. def Song_play_count(s: Song) -> int:
  164. ''' Return the number of times this song has been played
  165. '''
  166. return s.play_count
  167.  
  168. def all_songs(MC: 'list of Album') -> 'list of Song':
  169. ''' Return a list of all the Songs in a music collection (list of Album)
  170. '''
  171. result = [ ]
  172. for a in MC:
  173. result.extend(a.songs)
  174. return result
  175.  
  176. Songlist = all_songs(MUSIC)
  177. assert(Songlist[0] == Song(1, "Darkness", 411, 5))
  178. assert(Songlist[1] == Song(2, "Growing Up", 453, 5))
  179. assert(Songlist[-1] == Song(9, "You Can't Always Get What You Want", 448, 10))
  180.  
  181. def top_n_played_songs(MC: 'list of Album', n: int) -> 'list of Song':
  182. ''' Return a list of the n most frequently played songs in MC
  183. '''
  184. Songlist = all_songs(MC)
  185. Songlist.sort(key=Song_play_count, reverse=True)
  186. return Songlist[:n]
  187.  
  188. assert(top_n_played_songs(MUSIC, 5) ==
  189. [Song(4, "Alive and Kicking", 326, 26),
  190. Song(4, "Nothing Better", 226, 18),
  191. Song(5, "Oh Jungleland", 314, 13),
  192. Song(1, "The District Sleeps Alone", 284, 13),
  193. Song(2, "Such Great Heights", 266, 13)])
  194.  
  195.  
  196. ###################################
  197. # Song-displays
  198. ###################################
  199. # But these songs don't have their album information! We removed it when we created
  200. # the list of all songs. If we want to display selected songs on our iPod screen,
  201. # we'd want to have the album information along with the song information.
  202.  
  203. # We could flatten out our data structure, storing a copy of the album
  204. # information with each song:
  205. # 1 Up Peter Gabriel 2002 1 Darkness 411 5
  206. # 1 Up Peter Gabriel 2002 2 Growing Up 453 8
  207. # 1 Up Peter Gabriel 2002 3 Sky Blue 397 2
  208. # ...
  209. # This would work, but there's a lot of duplicate data---it would be wasteful of storage
  210. # and error-prone to store our music data this way permanently.
  211.  
  212. # Instead, let's just get the album info that goes with a song WHEN WE NEED IT,
  213. # during the computation. To do this, we define a structure that contains the
  214. # info we need to display a song (on our iPod screen, e.g.)---song details plus
  215. # the info we need from that song's album:
  216.  
  217. Songdisplay = namedtuple('Songdisplay', 'artist a_title year track s_title length play_count')
  218.  
  219. # We'll create these structures as we need them during the computation,
  220. # discarding them as we're done; this doesn't affect the main, permanent
  221. # list of albums (like the one we defined as MUSIC above).
  222.  
  223. def all_Songdisplays(MC: 'list of Album') -> 'list of Songdisplay':
  224. ''' Return a list of all the songs in the collection MC, in Songdisplay form
  225. '''
  226. result = [ ]
  227. for a in MC:
  228. result.extend(Album_to_Songdisplays(a))
  229. return result
  230.  
  231. def Album_to_Songdisplays(a: Album) -> 'list of Songdisplay':
  232. ''' Return a list of Songdisplays, one for each song in the album
  233. '''
  234. result = [ ]
  235. for s in a.songs:
  236. result.append(Songdisplay(a.artist, a.title, a.year,
  237. s.track, s.title, s.length, s.play_count))
  238. return result
  239.  
  240. def play_count_from_songdisplay(sd: Songdisplay) -> int:
  241. ''' Return the play_count from a Songdisplay
  242. '''
  243. return sd.play_count
  244.  
  245. def top_n_played(MC: 'list of Album', n: int) -> 'list of Songdisplay':
  246. ''' Return the top n most frequently played songs in MC
  247. '''
  248. list_of_Songdisplays = all_Songdisplays(MC)
  249. list_of_Songdisplays.sort(key=play_count_from_songdisplay, reverse=True)
  250. return list_of_Songdisplays[:n]
  251.  
  252. test_list = top_n_played(MUSIC, 3)
  253. assert(test_list[0].s_title == "Alive and Kicking")
  254. assert(test_list[0].a_title == "Once Upon a Time")
  255. assert(test_list[-1].s_title == "Oh Jungleland")
  256. assert(test_list[-1].a_title == "Once Upon a Time")
  257.  
  258. print()
  259. print("---Part E---")
  260. print()
  261.  
  262. #E.1
  263.  
  264. def Song_str(s:Song)->str:
  265. '''Takes a song and returns str containing song info'''
  266. format_str = "Track{:}\t Title: {:25} \tLength{:5}\tPlayCount{:5}\n"
  267. return(format_str.format(s.track, s.title, s.length, s.play_count))
  268.  
  269. def Album_str(a:Album)->str:
  270. '''Takes in an album and returns str containing album info'''
  271. format_str = "Album: ID {:}\tArtist: {:}\tTitle: {:}\tYear: {:}\n\n"
  272. result = ''
  273.  
  274. b = format_str.format(a.id,a.artist,a.title,a.year)
  275.  
  276. for i in a.songs:
  277. d = Song_str(i)
  278. result+=d
  279. return b + result
  280.  
  281.  
  282. def Songdisplay_str(sd:Songdisplay)->str:
  283. ''' Takes in a song display and returns a str containing display info '''
  284. result1 = ""
  285. result = []
  286. """
  287. format_str = "Artist: {:5}, Title:{:25}, Year:{:5}, track:{:},+\
  288. song title: {:}, length:{:}, playcount:{:}"
  289. result+= format_str.format(i.artist,i.title,i.year)
  290. """
  291. for i in sd:
  292. result.append(i)
  293. return result1
  294.  
  295. #print(Songdisplay_str(top_n_played(MUSIC, 3)))
  296.  
  297. #E2
  298.  
  299. def Album_tracknum(a:Album)->int:
  300. '''Return # of tracks'''
  301. trackcount = 0
  302. for s in a.songs:
  303. trackcount+=1
  304. return trackcount
  305.  
  306. collection_sort(MUSIC,Album_tracknum)
  307. for i in MUSIC:
  308. print(Album_str(i))
  309.  
  310. MUSIC.sort(key = Album_id)
  311. print(collection_sort(MUSIC,Album_tracknum))
  312.  
  313. #E3
  314.  
  315. def unplayed_songs(MC:'List of Albums')->list:
  316. '''Takes in a music collection and returns list of Songdisplays'''
  317. result = []
  318. for album in MC:
  319. for song in album.songs:
  320. if Song_play_count(song) == 0:
  321. result.append(song)
  322. return result
  323.  
  324. print(Songdisplay_str(unplayed_songs(MUSIC)))
  325.  
  326. #E4
  327. def length_from_songdisplay(sd:Songdisplay)->int:
  328. ''' returns length '''
  329. return sd.length
  330.  
  331. #E5
  332.  
  333. def Song_listening_time(s:Song)->int:
  334. '''Returns total listening time'''
  335. return s.play_count * s.length
  336.  
  337. def Album_listening_time(a:Album)->int:
  338. '''Returns total time'''
  339. totaltime = 0
  340. for i in a.songs:
  341. totaltime += Song_listening_time(i)
  342. return totaltime
  343.  
  344. def favorite_album(MC:'List of Albums')->list:
  345. '''Returns favorite album'''
  346. fav_album = []
  347. collection_sort(MC,Album_listening_time)
  348. fav_album.append(MC[-1])
  349. return fav_album
  350.  
  351. for i in favorite_album(MUSIC):
  352. print("Favorite Album:\n" , Album_str(i))
  353.  
  354. #E6
  355.  
  356. def top_n(MC: 'list of Album', n:int, funcname,Bool)->'list of Songdisplay':
  357. '''Takes in three parameters and returns a list'''
  358.  
  359. list_of_Songdisplays = all_Songdisplays(MC)
  360. list_of_Songdisplays.sort(key = funcname, reverse = Bool)
  361.  
  362. return list_of_Songdisplays[:n]
  363.  
  364.  
  365. Songdisplay_str(top_n(MUSIC, 3, play_count_from_songdisplay, True))
  366.  
  367. #E7
  368.  
  369. def favorite_album2(MC:'List of album',fav_measure)->list:
  370. '''Takes in two parameters and returns a list according to 2nd param'''
  371. newlist = []
  372.  
  373. collection_sort(MC,fav_measure)
  374. newlist.append(MC[-1])
  375. return(newlist)
  376.  
  377. def Song_count(s:Song)->int:
  378. return s.play_count
  379.  
  380. def Album_count(a:Album)->int:
  381. totalcount = 0
  382. for i in a.songs:
  383. totalcount += Song_count(i)
  384. return totalcount
  385.  
  386. for i in (favorite_album2(MUSIC,Album_count)):
  387. print(Album_str(i))
  388.  
  389. #E8
  390. def collection_search(C:list,str1:str)-> "list of Songdisplay":
  391. '''Takes in a collection and a string and returns a list of
  392. Songdisplays of songs'''
  393.  
  394. newlist = []
  395. for x in C:
  396. if (x.artist or x.a_title) == str1:
  397. newlist.append(x)
  398. for a in x.songs:
  399. if (a.title) == str1:
  400. newlist.append(a)
  401.  
  402. return newlist
  403.  
  404. print(collection_search(MUSIC,"Darkness"))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement