473,657 Members | 2,700 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Abstract class

Hi,
I'm going to work on a project to represent some musical theory in
Python, in an object oriented way.

I have to manage many elements of music such as notes, intervals,
scales, chords and so on. All these elements share properties and
behavior, so what I want to do is an abstract class "Note" and other
subclasses, for example "NaturalNot e", "FlatNote", "SharpNote" etc.

The idea is not original, I read it in some papers where they talk
about an implementation in smalltalk.

I want to use Python (of course) and I'd like to know what is the
practice in such a case. I mean, in python there aren't abstract
classes, but I read about some way to emulate the same behavior.

What do you suggest me?

Thanks,
Carlo
Sep 14 '08 #1
21 3926
Mr.SpOOn wrote:
Hi,
I'm going to work on a project to represent some musical theory in
Python, in an object oriented way.

I have to manage many elements of music such as notes, intervals,
scales, chords and so on. All these elements share properties and
behavior, so what I want to do is an abstract class "Note" and other
subclasses, for example "NaturalNot e", "FlatNote", "SharpNote" etc.

The idea is not original, I read it in some papers where they talk
about an implementation in smalltalk.

I want to use Python (of course) and I'd like to know what is the
practice in such a case. I mean, in python there aren't abstract
classes, but I read about some way to emulate the same behavior.

What do you suggest me?

Thanks,
Carlo
I think the issue is one of terminology not features. Note would be a base
class and it can have attributes (properties) and behavior (methods).
NaturalNote, FlatNote, SharpNote would inherit from Note.

-Larry
Sep 14 '08 #2
In article <ma************ *************** ***********@pyt hon.org>,
Mr.SpOOn <mr********@gma il.comwrote:
I have to manage many elements of music such as notes, intervals,
scales, chords and so on. All these elements share properties and
behavior, so what I want to do is an abstract class "Note" and other
subclasses, for example "NaturalNot e", "FlatNote", "SharpNote" etc.
What properties or behaviors does SharpNote have which NaturalNote doesn't?
Unless there is some new behavior, you don't need subclasses.

Are you also going to have DoubleSharpNote and DoubleFlatNote?

Consider the following code:

note1 = SharpNote("E4")
note2 = NaturalNote("F4 ")
if note1 == note2:
print "the same note"
else
print "different notes"

what should it print?
Sep 14 '08 #3
Roy Smith wrote:
>Are you also going to have DoubleSharpNote and DoubleFlatNote?

Consider the following code:

note1 = SharpNote("E4")
note2 = NaturalNote("F4 ")
if note1 == note2:
print "the same note"
else
print "different notes"

what should it print?
Hehe, tricky question.

The answer depends on the music instrument and tuning. On a piano E# and
F are on the same key but other instruments (e.g. a violin) treat E# and
F as different notes. The enharmonic equivalent E# == F is only valid
for some instruments and tunes - noticeable for modern tunes like equal
temperament.

Christian

Sep 14 '08 #4
Gary Harron:
>I believe you are mixing up class *inheritance* and *abstract* classes.
>Class inheritance (with Python has has for years) is how one class inherits >behavior/properties/attributes from another class. The class being inherited from is >called the base class. This is probably what you want.
Well, I know the difference between an abstract class and an inherited
one. The idea was to create a main class Note, with abstract methods,
and implement these methods in the other classes.

On Sun, Sep 14, 2008 at 7:56 PM, Roy Smith <ro*@panix.comw rote:
What properties or behaviors does SharpNote have which NaturalNote doesn't?
Unless there is some new behavior, you don't need subclasses.
Well, from a SharpNote I can obtain the relative NaturalNote. So if I
have a C# I can call

natural('C#') and get 'C'

While in the class NaturalNote I don't need such a method, but I need
two methods to get the sharped and flatted version
Are you also going to have DoubleSharpNote and DoubleFlatNote?
Yes, that's an option.
Consider the following code:

note1 = SharpNote("E4")
note2 = NaturalNote("F4 ")
if note1 == note2:
print "the same note"
else
print "different notes"

what should it print?
Well, that's not so simple. The idea is that I use a notation (A, B,
C, D...) and an integer (a distance expressed in semitones) to
identify a note.

Anyway, I think I need an abstract class. Or not?
Sep 14 '08 #5
Mr.SpOOn wrote:
Gary Harron:
>I believe you are mixing up class *inheritance* and *abstract* classes.

>Class inheritance (with Python has has for years) is how one class inherits >behavior/properties/attributes from another class. The class being inherited from is >called the base class. This is probably what you want.

Well, I know the difference between an abstract class and an inherited
one. The idea was to create a main class Note, with abstract methods,
and implement these methods in the other classes.

On Sun, Sep 14, 2008 at 7:56 PM, Roy Smith <ro*@panix.comw rote:
>What properties or behaviors does SharpNote have which NaturalNote doesn't?
Unless there is some new behavior, you don't need subclasses.

Well, from a SharpNote I can obtain the relative NaturalNote. So if I
have a C# I can call

natural('C#') and get 'C'

While in the class NaturalNote I don't need such a method, but I need
two methods to get the sharped and flatted version

>Are you also going to have DoubleSharpNote and DoubleFlatNote?

Yes, that's an option.

>Consider the following code:

note1 = SharpNote("E4")
note2 = NaturalNote("F4 ")
if note1 == note2:
print "the same note"
else
print "different notes"

what should it print?

Well, that's not so simple. The idea is that I use a notation (A, B,
C, D...) and an integer (a distance expressed in semitones) to
identify a note.

Anyway, I think I need an abstract class. Or not?
No! Definitely not! You need inheritance of a class from a base
class.

Implement your base class with whatever shared methods you want.
Implement your derived class with methods (new, inherited or
reimplemented) as you like.
(If you wish to consider the base class "abstract", just agree with
yourself to not instantiate it.)

Please forget about Abstract Base Classes. They have nothing to do with
what you want, and are a *HUGE* overkill for your application. They
are not (yet) even part of standard Python, and are used primarily for a
class implementor to guarantee to a user of a class that it provides a
specific interface.

Gary Herron
--
http://mail.python.org/mailman/listinfo/python-list
Sep 14 '08 #6
On Sun, Sep 14, 2008 at 9:15 PM, Gary Herron <gh*****@island training.comwro te:
Please forget about Abstract Base Classes. They have nothing to do with
what you want, and are a *HUGE* overkill for your application. They are
not (yet) even part of standard Python, and are used primarily for a class
implementor to guarantee to a user of a class that it provides a specific
interface.
Ok :D
I started to think to abstract classes just because in the paper it
uses an abstract class in SmallTalk.

Anyway, thanks.
Sep 14 '08 #7
On Sep 14, 2:15*pm, Gary Herron <gher...@island training.comwro te:
Mr.SpOOn wrote:
Gary Harron:
I believe you are mixing up class *inheritance* and *abstract* classes..
Class inheritance (with Python has has for years) is how one class inherits >behavior/properties/attributes from another class. *The class being inherited from is >called the base class. *This is probably what you want.
Well, I know the difference between an abstract class and an inherited
one. The idea was to create a main class Note, with abstract methods,
and implement these methods in the other classes.
On Sun, Sep 14, 2008 at 7:56 PM, Roy Smith <r...@panix.com wrote:
What properties or behaviors does SharpNote have which NaturalNote doesn't?
Unless there is some new behavior, you don't need subclasses.
Well, from a SharpNote I can obtain the relative NaturalNote. So if I
have a C# I can call
natural('C#') *and get 'C'
While in the class NaturalNote I don't need such a method, but I need
two methods to get the sharped and flatted version
Are you also going to have DoubleSharpNote and DoubleFlatNote?
Yes, that's an option.
Consider the following code:
note1 = SharpNote("E4")
note2 = NaturalNote("F4 ")
if note1 == note2:
* print "the same note"
else
* print "different notes"
what should it print?
Well, that's not so simple. The idea is that I use a notation (A, B,
C, D...) and an integer (a distance expressed in semitones) to
identify a note.
Anyway, I think I need an abstract class. Or not?

No! *Definitely not! * *You need inheritance of a class from a base
class. *
Just brainstorming with you. You can support operations on the
objects: note minus note = interval, note plus interval = note, and so
on. (WARNING! Spoilers. Untested.)

note1 = NaturalNote("G" )
note2 = NaturalNote("C" )
interval= note1- note2
print interval
: <MajorInterva l '5th'>

note1 = SharpNote("G")
note2 = NaturalNote("C" )
interval= note1- note2
print interval
: <MinorInterva l '6th'>

WholeStep= MajorInterval( 2 )
print WholeStep
: <MajorInterva l '2nd'>
note1 = NaturalNote("C" )
print note1- WholeStep
: <FlatNote("B" )>

However, from what I understand (brass player), there are some cases
in which you'll want that to be:

print note1- WholeStep
: <SharpNote("A") >

What do you want to determine that? What about a KeyOf class?

key= KeyOf( NaturalNote( "F" ) )
#'key' has special subclasses
note1 = key.NaturalNote ("C")
print note1- WholeStep
: <FlatNote("B" )>

key= KeyOf( SharpNote( "G" ) )
note1 = key.NaturalNote ("C")
print note1- WholeStep
: <SharpNote("A") >

Further, perhaps you want a 'WrittenNote' class which refers to the
key signature it's written in:

key= KeyOf( NaturalNote( "F" ) )
note1 = key.WrittenNote ("B")
print note1
: <FlatNote("B" )>

I do not immediately see how to represent clefs and staves: whether
you'll need them at all, or whether they're just writing/rendering
techniques.

As for scales and chords, are there any special methods you want on
them, or would a tuple of Note instances suffice?

triad= ( NaturalNote( "C" ), NaturalNote( "E" ), NaturalNote( "G" ) )

One special method might be:

triad= Triad( NaturalNote( "C" ), NaturalNote( "E" ),
NaturalNote( "G" ) )
print triad
: <C-Major triad>
triad= Triad( NaturalNote( "E" ), NaturalNote( "G" ),
NaturalNote( "C" ) )
print triad
: <C-Major triad 1st inversion>

I forgot about octaves, which can complicate the constructors.

octave= Octave( 4 ) #middle C
triad= Triad( octave.NaturalN ote( "E" ), octave.NaturalN ote( "G" ),
octave.up.Natur alNote( "C" ) )
print triad
: <C-Major triad 1st inversion>

Or:

octave= Octave( 4 )
triad= Triad( NaturalNote( "E", octave ), NaturalNote( "G", octave ),
NaturalNote( "C", octave.up ) )
print triad
: <C-Major triad 1st inversion>

And abbreviate the name for the interval.

octaveint= MajorInterval( 8 )

Abstract scales can be a tuple of intervals, where concrete scales are
a tuple of notes.

majorscale= ( Tonic, WholeStep, WholeStep, HalfStep,
WholeStep, WholeStep, WholeStep, HalfStep )

majorCscale= [ NaturalNote( "C" )+ x for x in majorscale ]
majorDscale= [ NaturalNote( "D" )+ x for x in majorscale ]

To get a little more creative, you could just denote sharps and flats
with a parameter:

note1 = Note("G", sharp)
#Or: note1 = Note("G", Note.sharp)
note2 = Note("C")
interval= note1- note2
print interval
: <MinorInterva l '6th'>

It would just take some 'parameter magic' to interpret them right when
paired with octaves:

octave= Octave( 4 ) #middle C
note1= Note( "C", sharp, octave )
note2= Note( "C", octave )
note3= Note( "C", octave, sharp )
note4= Note( "C", sharp )

That part just takes a little untwisting. (Untested.)

class Note:
defaultoctave= 4
def __init__( self, *args ):
octave= Octave( self.defaultoct ave )
accidental= Natural( )
for arg in args:
if issubclass( arg, Accidental ):
accidental= arg
elif issubclass( arg, Octave ):
octave= arg
elif type( arg ) is str:
name= arg

Or use keywords to specify.

octave= Octave( 4 ) #middle C
note1= Note( "C", sharp, octave )
note2= Note( "C", octave= octave )
note3= Note( "C", octave= octave, accidental= sharp )
note4= Note( "C", sharp )

class Note:
defaultoctave= 4
def __init__( self, name, octave= None, accidental= Natural( ) ):
if octave is None:
octave= self.defaultoct ave

It's open to debate whether Natural is a subclass or instance of
Accidental.
Sep 14 '08 #8
Mr.SpOOn <mr********@gma il.comwrote:
Well, from a SharpNote I can obtain the relative NaturalNote. So if I
have a C# I can call

natural('C#') and get 'C'
And why should you not be allowed to apply natural() to a NaturalNote? I
would think it would just be an identity operator.
While in the class NaturalNote I don't need such a method, but I need
two methods to get the sharped and flatted version
Well, you may need sharp() and flat() methods on all notes. Can't you do
sharp('C#'), which should give you C double-sharp?
Consider the following code:

note1 = SharpNote("E4")
note2 = NaturalNote("F4 ")
if note1 == note2:
print "the same note"
else
print "different notes"

what should it print?

Well, that's not so simple.
I know it's not simple. I don't know what the correct answer is, or even
if the problem admits to having a single universally correct answer. I'm
just pointing out something you should probably think about.
Anyway, I think I need an abstract class. Or not?
Hard to tell. My advice would be to start out with a single Note class and
start writing code. If you get to the point where you're writing lots of
conditional logic in your methods (if sharp, do this, if flat, do that),
that's a hint that you may indeed need to refactor things into subclasses.

The next step would be to figure out what the right hierarchy is. Offhand,
I can think of three hierarchies which might be plausible:

------------------------------

Note
SharpNote(Note)
DoubleSharpNote (Note)
FlatNote(Note)
DoubleFlatNote( Note)

This is a relatively flat (sorry about that) hierarchy. Note (arghhh!!)
that there is no explicit NaturalNote class; notes which are not sharp or
flat are just instances of Note.

------------------------------

AbstractNote
NaturalNote(Abs tractNote)
SharpNote(Abstr actNote)
DoubleSharpNote (AbstractNote)
FlatNote(Abstra ctNote)
DoubleFlatNote( AbstractNote)

This one sounds like what I think you've currently got in mind.

------------------------------

AbstractNote
NaturalNote(Abs tractNote)
SharpNote(Abstr actNote)
DoubleSharpNote (SharpNote)
FlatNote(Abstra ctNote)
DoubleFlatNote( FlatNote)

This one is similar to the above, except that the double-{sharp,flat} note
are subclasses of their single versions.

------------------------------

I have no idea which is the right way to represent this. Some people would
agonize over the decision for days before writing a single piece of code.
My personal preference is to start small, get some code written, and let
the code teach you what makes sense. If things are flowing smoothly, you
probably picked a good way to organize your classes. If things are ugly
and you find yourself writing lots of gnarly conditional code, that's a
hint you're off on the wrong track. Don't be afraid to throw it away and
start from scratch.

BTW, here's another thing to think about. Is a C in a signature where C is
not sharp the same as a C in a signature where it is sharp but written with
a natural accidental? I have no clue, but when you figure out what answer
makes sense for you, that might help you decide how you're going to
organize your classes.
Sep 14 '08 #9
Mr.SpOOn wrote:
Well, I know the difference between an abstract class and an inherited
one. The idea was to create a main class Note, with abstract methods,
and implement these methods in the other classes.
The pragmatic way to implement abstract classes in Python is to define
an ordinary base class, and either just leave out the methods that must
be defined in subclasses, or provide stub methods that simply raise a
NotImplementedE rror exception:

class AbstractThing(o bject):
...
def some_method(sel f, args):
raise NotImplementedE rror

There are more "clever" ways to do things, but they're usually overkill.
Anyway, I think I need an abstract class. Or not?
Depends on how much generally useful functionality you can come up with
for the base class. It's not like Python prevents you from overriding a
non-abstract method, after all.

I suggest you skip further discussion and get to work. I'm sure you'll
figure out what works best for your specific case once you've written a
few classes.

</F>

Sep 14 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
2307
by: Tony Johansson | last post by:
Hello! Assume you have an abstract class called Body and a derived class called cylinder. When you have an abstract class you can't instansiate an object. As you can see in the abstract class there are one data member called density that you can't access because there will not be any object of class Body. The data member density will be inheritated and all the member functions. So when you have an instance of class Cylinder and you...
12
3082
by: Daedalus.OS | last post by:
Ok first I'm pretty new to OOP, so my question may sound stupid to some of you. If the only answer you can provide is "get a book about OOP" then don't loose your time and mine cause it's already ordered. I'm just too curious about this one to wait for the book. I would like to know is if it's good php programming practice to use abstract classes instead of singleton classes. For exemple a login class. I've made one as an abstract class...
2
9600
by: Dave Veeneman | last post by:
Is is legal to declare abstract members in non-abstract classes? How about non-abstract members in abstract classes? I am writing a base class with three derived classes. The base class will define the behavior for most, but not all of its members. The derived classes will define the behavior for the remaining members (the undefined members). I'd like to force the derived classes to implement the undefined members in the base class. I...
6
5798
by: Dan Sikorsky | last post by:
If we were to define all abstract methods in an abstract class, thereby making that class non-abstract, and then override the heretofore 'abstract' methods in a derived class, wouldn't that remove the need to have abstract class types in C#? Derived classes from abstract base classes must overrided the abstract method defininition anyway, so why not just provide a complete definition for the abstract method when defining the containing...
7
4463
by: jason | last post by:
In the microsoft starter kit Time Tracker application, the data access layer code consist of three cs files. DataAccessHelper.cs DataAcess.cs SQLDataAccessLayer.cs DataAcccessHelper appears to be checking that the correct data type is used DataAcess sets an abstract class and methods
0
2673
by: mailforpr | last post by:
Hi. Let me introduce an iterator to you, the so-called "Abstract Iterator" I developed the other day. I actually have no idea if there's another "Abstract Iterator" out there, as I have never looked for one on the net (I did browse the boost library though). It doesn't matter right now, anyway. To put it simply, Abstract Iterator is mainly a wrapper class. It helps
4
3197
by: N.RATNAKAR | last post by:
hai, what is abstract class and abstract method
0
2821
by: emin.shopper | last post by:
I had a need recently to check if my subclasses properly implemented the desired interface and wished that I could use something like an abstract base class in python. After reading up on metaclass magic, I wrote the following module. It is mainly useful as a light weight tool to help programmers catch mistakes at definition time (e.g., forgetting to implement a method required by the given interface). This is handy when unit tests or...
4
6565
by: David Zha0 | last post by:
Hi, "when we call a virtual method, the runtime will check the instance who called the method and then choose the suitable override method, this may causes the performance drop down", is this right? And, why not use "new" instead of using "virtual"? And the last question, what is the differences between a abstract method and a interface?
6
4024
by: Miguel Guedes | last post by:
Hello, I recently read an interview with Bjarne Stroustrup in which he says that pure abstract classes should *not* contain any data. However, I have found that at times situations are when it would be useful to have /some/ data defined in such an abstract class for reasons of forming a common block of data existing in or used by all descendant classes (see example below.) In such a case where a common block of data *always* exists,...
0
8739
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8512
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8612
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7347
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5638
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4171
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4329
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2739
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1732
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.