Reputation: 45
Here is my code:
from mutagen.easyid3 import EasyID3
from mutagen import File
class MusicFile:
"""A class representing a particular music file.
Children that are intended to be instantiated must initialize fields for
the getters that exist in this class.
"""
def __init__(self, location):
self.location = location
def getLocation():
return self.location
def getArtist():
return self.artist
def getAlbum():
return self.album
def getTitle():
return self.title
###############################################################################
class LossyMusicFile(MusicFile):
"""A class representing a lossy music file.
Contains all functionality required by only lossy music files. To date, that
is processing bitrates into a standard number and returning format with
bitrate.
"""
def __init__(self, location):
super().__init__(location)
def parseBitrate(br):
"""Takes a given precise bitrate value and rounds it to the closest
standard bitrate.
Standard bitrate varies by specific filetype and is to be set by the
child.
"""
prevDiff=999999999
for std in self.bitrates:
# As we iterate through the ordered list, difference should be
# getting smaller and smaller as we tend towards the best rounding
# value. When the difference gets bigger, we know the previous one
# was the closest.
diff = abs(br-std)
if diff>prevDiff:
return prev
prevDiff = diff
prev = std
def getFormat():
"""Return the format as a string.
look like the format name (a class variable in the children), followed
by a slash, followed by the bitrate in kbps (an instance variable in the
children). a 320kbps mp3 would be 'mp3/320'.
"""
return self.format + '/' + self.bitrate
###############################################################################
class Mp3File(LossyMusicFile):
"""A class representing an mp3 file."""
format = "mp3"
# Threw a large value on the end so parseBitrate() can iterate after the end
bitrates = (32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000,
128000, 160000, 192000, 224000, 256000, 320000, 999999)
def __init__(self, location):
super().__init__(location)
id3Info = EasyID3(location)
self.artist = id3Info['artist'][0]
self.album = id3Info['album'][0]
self.title = id3Info['title'][0]
# Once we set it here, bitrate shall be known in kbps
self.bitrate = (self.parseBitrate(File(location).info.bitrate))/1000
Now, when I try to instantiate an Mp3File
, it gives me an error on the last line of Mp3File.__init__()
:
line 113, in __init__
self.bitrate = (self.parseBitrate(File(location).info.bitrate))/1000
NameError: name 'parseBitrate' is not defined
However, it seems to me that it should be failing to find the method in Mp3File
, and then looking for the method in the parent class, LossyMusicFile
, where it does exist.
I tried changing that line to self.bitrate = (super().parseBitrate(File(location).info.bitrate))/1000
so that it would be explicitly using the parent class's method, but I get the same error. What's going on?
Apologies if this has been asked before or is a dumb question, but I couldn't find it when I searched and I am, in fact, dumb.
Upvotes: 1
Views: 1746
Reputation: 10647
All of your instance methods must have self as the first parameter. What's happening here is that in parseBitrate()
you renamed self
to br
. You need parseBitrate(self, br)
in order to accept a bitrate. You need to add self
to the argument list in other methods like getFormat()
too.
thisVariableNamingStyle
it's against Python's offical style document, PEP 8.MusicFile
doesn't inherit off of object
. You can only call methods inherited from a a higher class in "new-style classes". In order to make your class "new-style", you must inherit off of object
.In addition, get an IDE like PyCharm that can automatically warn you of these errors in the future.
Upvotes: 2