Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #12138

Re: Adding modified methods from another class without subclassing

Path csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!aioe.org!feeder.news-service.com!newsfeed.xs4all.nl!newsfeed6.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail
Return-Path <johnmohagan@gmail.com>
X-Original-To python-list@python.org
Delivered-To python-list@mail.python.org
X-Spam-Status OK 0.005
X-Spam-Evidence '*H*': 0.99; '*S*': 0.00; 'attributes': 0.05; 'instance': 0.05; 'attribute': 0.07; 'python': 0.08; '(self,': 0.09; '[0]': 0.09; 'attribute.': 0.09; 'pitch': 0.09; 'solution,': 0.09; 'structure.': 0.09; 'suggestions,': 0.09; 'meaningful': 0.13; 'def': 0.15; 'board.': 0.15; 'class,': 0.15; '(python)': 0.16; '@property': 0.16; '__init__': 0.16; 'accordingly,': 0.16; 'form"': 0.16; 'mon,': 0.16; 'this:': 0.16; 'wrote:': 0.16; 'thanks,': 0.18; '>>>': 0.18; 'maybe': 0.21; "doesn't": 0.22; 'header:In-Reply-To:1': 0.22; 'applicable,': 0.23; 'emphasis': 0.23; 'received:209.85.213.46': 0.23; 'received:mail- yw0-f46.google.com': 0.23; 'aug': 0.24; 'sender:addr:gmail.com': 0.25; 'skip:[ 10': 0.27; 'classes': 0.28; 'skip:p 30': 0.28; '+0200': 0.28; 'mine': 0.28; 'looks': 0.29; 'skip:( 20': 0.29; 'calculated': 0.30; 'collections': 0.30; 'class': 0.30; 'list:': 0.31; 'actual': 0.32; 'does': 0.32; 'there': 0.33; 'to:addr :python-list': 0.33; '...': 0.34; "i'll": 0.34; 'crazy': 0.34; 'elegant': 0.34; 'notes': 0.35; 'starting': 0.36; 'charset:us- ascii': 0.36; 'put': 0.37; 'but': 0.37; 'something': 0.37; 'open': 0.37; 'could': 0.38; 'somewhat': 0.38; 'received:google.com': 0.38; 'received:209.85': 0.38; 'skip:o 20': 0.38; 'subject:: ': 0.39; 'unlike': 0.39; 'header:Mime-Version:1': 0.39; "there's": 0.39; 'why': 0.39; 'to:addr:python.org': 0.39; 'called': 0.40; 'subject:from': 0.40; "it's": 0.40; 'more': 0.60; 'your': 0.61; 'header:Message-Id:1': 0.61; 'unique': 0.62; 'john': 0.62; 'back': 0.62; 'course.': 0.63; 'series': 0.65; 'subject:without': 0.67; 'collection': 0.73; 'introduce': 0.79; 'otten': 0.84; 'subject:class': 0.84; 'together,': 0.84; 'zen': 0.84; 'received:home': 0.91; 'musical': 0.93; 'reducing': 0.95
DKIM-Signature v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=sender:date:from:to:subject:message-id:in-reply-to:references :x-mailer:mime-version:content-type:content-transfer-encoding; bh=Ujekeg/XtMP+jYivwapab/X+Nn3ag4x13PBhI2XJPao=; b=uzOLYqcfAZRCHTMQgDvFyMc7ik6WGM6ygPKcfzpiTOx+oPtC8pP9zfnGqOKKG79JDF yWtSCN1RXUnNggYIFqelidYJMghTx7Njti13OUhDw29kFdZHaBtsO75wL/+55k8i9/QX E9FGPAFaMGqidB8SZpw1Eumkfn51F79jkybB0=
Sender "John O'Hagan" <johnmohagan@gmail.com>
Date Wed, 24 Aug 2011 21:01:55 +1000
From John O'Hagan <research@johnohagan.com>
To python-list@python.org
Subject Re: Adding modified methods from another class without subclassing
In-Reply-To <j2u7n0$k3h$1@dough.gmane.org>
References <20110822150445.d351f4761ac00559079f7edc@johnohagan.com> <j2t7mu$osn$1@dough.gmane.org> <20110823002009.5be9524e66d87949af45ede3@johnohagan.com> <j2u7n0$k3h$1@dough.gmane.org>
X-Mailer Sylpheed 3.2.0beta1 (GTK+ 2.24.4; x86_64-pc-linux-gnu)
Mime-Version 1.0
Content-Type text/plain; charset=US-ASCII
Content-Transfer-Encoding 7bit
X-BeenThere python-list@python.org
X-Mailman-Version 2.1.12
Precedence list
List-Id General discussion list for the Python programming language <python-list.python.org>
List-Unsubscribe <http://mail.python.org/mailman/options/python-list>, <mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive <http://mail.python.org/pipermail/python-list>
List-Post <mailto:python-list@python.org>
List-Help <mailto:python-list-request@python.org?subject=help>
List-Subscribe <http://mail.python.org/mailman/listinfo/python-list>, <mailto:python-list-request@python.org?subject=subscribe>
Newsgroups comp.lang.python
Message-ID <mailman.384.1314183730.27778.python-list@python.org> (permalink)
Lines 88
NNTP-Posting-Host 2001:888:2000:d::a6
X-Trace 1314183730 news.xs4all.nl 23916 [2001:888:2000:d::a6]:56402
X-Complaints-To abuse@xs4all.nl
Xref x330-a1.tempe.blueboxinc.net comp.lang.python:12138

Show key headers only | View raw


On Mon, 22 Aug 2011 20:38:30 +0200
Peter Otten <__peter__@web.de> wrote:

> John O'Hagan wrote:
> 
> > On Mon, 22 Aug 2011 11:32:18 +0200
> > Peter Otten <__peter__@web.de> wrote:
> > 
> >> John O'Hagan wrote:
> >> 
> >> > I have a class like this:
> >> > 
> >> > class MySeq():
> >> >     def __init__(self, *seq, c=12):
> >> >         self.__c = c
> >> >         self.__pc = sorted(set([i % __c for i in seq]))
> >> >         self.order = ([[self.__pc.index(i % __c), i // __c] for i in
> >> >         seq])
> >> >         #other calculated attributes
> >> > 
> >> >     @property
> >> >     def pitches(self):
> >> >         return [self.__pc[i[0]] + i[1] * self.__c for i in self.order]
> >> > 
> >> >     #other methods
> >> 
> >> That makes me dizzy. Are there any maxims in the Zen of Python that this
> >> piece doesn't violate?
> > 
> > "Now is better than never"?
> > 
> > I know it looks crazy to take something apart and put it back together, as
> > in this *simplified* *example*
> 
> emphasis mine ;)
> 
> > , but it does have a meaningful use: reducing a
> > series of musical notes to a unique irreducible form "__pc", ("prime form"
> > in pitch-class set theory), but keeping track of the actual current
> > manifestation of that form via the writeable "order" attribute. That's why
> > "pitches" must be called with each reference, because it may change,
> > unlike "__pc", which can only change if the instance is reinitialised.
> > 
> > I am open to more elegant suggestions, of course. :)
> > [...]
> 
> Dunno. Maybe you could inherit from collections.(Mutable)Sequence and 
> somewhat reduce the number of methods you'd have to implement. 
> Or you introduce a Pitch (Python) class that knows about its pitch class, 
> and put that into a normal list:
> 
> >>> class Pitch(int):
> ...     @property
> ...     def pitch_class(self):
> ...             return self % 12
> ...     def __repr__(self):
> ...             return "Pitch(%s, pitch_class=%s)" % (self, 
> self.pitch_class)
> ...
> >>> map(Pitch, [1,0,42])
> [Pitch(1, pitch_class=1), Pitch(0, pitch_class=0), Pitch(42, pitch_class=6)]
>

That's a good starting point for a neater solution, but there's more I have to solve. For completeness, here's the un-simplified __init__ of the class (yes, it gets worse!):

  
class MySeq():

    def __init__(self, *sequence, octave=12):

        pcset = sorted(set([i % octave for i in sequence]))
        steps = ([pcset[i] - pcset[i - 1] for i in range(1, len(pcset))]
                    + [octave - pcset[-1]]) 
        rotations = [steps[n:] + steps[:n] for n in range(len(steps))]
        prime_steps = min([i for i in rotations if i[-1] == max(steps)])
        self.__prime = [0]
        for step in prime_steps:
            self.__prime.append(step + prime[-1])
        self.__offset = pcset[rotations.index(prime_steps)]
        self.__order = Order([[prime.index((i - offset) % octave),
            (i - self.__offset) // octave] for i in sequence])
        self.__octave = octave   

The __prime attribute is the one all the internal methods refer to, and it's not so much a collection of pitch classes as an interval structure. Accordingly, I'll follow your tip and look into the collections ABCs, many of which look applicable, and go back to the drawing board.

Thanks,

John

Back to comp.lang.python | Previous | Next | Find similar | Unroll thread


Thread

Re: Adding modified methods from another class without subclassing John O'Hagan <research@johnohagan.com> - 2011-08-24 21:01 +1000

csiph-web