simple integer subclass

Discussion in 'Python' started by Andreas Pfrengle, Aug 3, 2010.

  1. I'm trying to define a subclass of int called int1. An int1-object
    shall behave exactly like an int-object, with the only difference that
    the displayed value shall be value + 1 (it will be used to display
    array indices starting at 1 instead of 0). Right now I have:

    class int1(int):
    def __str__(self):
    return int.__str__(self + 1)

    However, if I calculate with int1 and int- (or other number) objects,
    the result is always coerced to an int (or other number object), e.g:
    a = int1(5)
    b = 5
    print a # "6"
    print a+b #"10"

    How can I tell int1 to be the "default integer object"? Do I need to
    overload *every* mathematical operation method of int, or is there an
    easier way?
     
    Andreas Pfrengle, Aug 3, 2010
    #1
    1. Advertising

  2. Andreas Pfrengle

    samwyse Guest

    On Aug 2, 6:52 pm, Andreas Pfrengle <> wrote:
    > I'm trying to define a subclass of int called int1. An int1-object
    > shall behave exactly like an int-object, with the only difference that
    > the displayed value shall be value + 1 (it will be used to display
    > array indices starting at 1 instead of 0). Right now I have:
    >
    > class int1(int):
    >     def __str__(self):
    >         return int.__str__(self + 1)
    >
    > However, if I calculate with int1 and int- (or other number) objects,
    > the result is always coerced to an int (or other number object), e.g:
    > a = int1(5)
    > b = 5
    > print a      # "6"
    > print a+b  #"10"
    >
    > How can I tell int1 to be the "default integer object"? Do I need to
    > overload *every* mathematical operation method of int, or is there an
    > easier way?


    I had a similar problem a few years ago, and couldn't find a solution
    then. The thread from back then may shed some light on your problem.
    http://groups.google.com/group/comp...hread/thread/10cfe2affc265ac/2ad03b121c1c6489
     
    samwyse, Aug 3, 2010
    #2
    1. Advertising

  3. Andreas Pfrengle

    Carl Banks Guest

    On Aug 2, 4:52 pm, Andreas Pfrengle <> wrote:
    > I'm trying to define a subclass of int called int1. An int1-object
    > shall behave exactly like an int-object, with the only difference that
    > the displayed value shall be value + 1 (it will be used to display
    > array indices starting at 1 instead of 0). Right now I have:
    >
    > class int1(int):
    >     def __str__(self):
    >         return int.__str__(self + 1)
    >
    > However, if I calculate with int1 and int- (or other number) objects,
    > the result is always coerced to an int (or other number object), e.g:
    > a = int1(5)
    > b = 5
    > print a      # "6"
    > print a+b  #"10"
    >
    > How can I tell int1 to be the "default integer object"? Do I need to
    > overload *every* mathematical operation method of int, or is there an
    > easier way?


    (Preface: I normally don't offer recommendations without answering the
    question as asked, but once in a while it has to be done.)

    I **highly** recommend against this approach.

    You are creating an object that differs from a built-in, int, in a
    highly misleading way that only makes sense in a very limited context,
    and this object's modified behavior gives no clue that it's been
    modified in such as way. (That is, it's not possible to tell if the
    object's not a regular int just by looking at __str__()'s return
    value.) To make matters worse, you want to program this object to
    coerce other integers, so there's a risk of these objects escaping
    from the context where they make sense.

    This is just a bad idea. The type is not the place to implement
    behavior that makes sense only in a limited context. Instead, do
    something like this:

    print "Item %d is %s." % (i+1, s)


    Carl Banks
     
    Carl Banks, Aug 3, 2010
    #3
  4. Andreas Pfrengle

    rantingrick Guest

    On Aug 2, 6:52 pm, Andreas Pfrengle <> wrote:
    > I'm trying to define a subclass of int called int1. An int1-object
    > shall behave exactly like an int-object, with the only difference that
    > the displayed value shall be value + 1 (it will be used to display
    > array indices starting at 1 instead of 0)


    Is zero based indexing that bad for you? I also think this is a very
    bad idea unless you can offer a sensible use case -- for which i
    cannot imagine.
     
    rantingrick, Aug 3, 2010
    #4
  5. On 3 Aug., 03:22, Carl Banks <> wrote:>
    > You are creating an object that differs from a built-in, int, in a
    > highly misleading way that only makes sense in a very limited context,
    > and this object's modified behavior gives no clue that it's been
    > modified in such as way.  (That is, it's not possible to tell if the
    > object's not a regular int just by looking at __str__()'s return
    > value.)  To make matters worse, you want to program this object to
    > coerce other integers, so there's a risk of these objects escaping
    > from the context where they make sense.
    >
    > This is just a bad idea.  The type is not the place to implement
    > behavior that makes sense only in a limited context.  Instead, do
    > something like this:
    >
    > print "Item %d is %s." % (i+1, s)


    I see your concerns. I started with the approach to add +1 directly
    before displaying the int. However, since there are some variables
    that shall be displayed normally and others that are indices I want to
    show starting at 1, I thought the easiest way would be to define a
    type that does the job, then I would only need to define it once and
    not take care everywhere whether I have a normal variable or a
    displayed index.
    Thinking about it, it might really be dangerous to coerce always to
    int1, since sometimes I might want a normal int as result (I can't
    tell yet for sure).
    I'm just thinking about only overloading the operations if the int1 is
    on the left-hand side (so __op__ coerces to int1, while __rop__
    doesn't). This would make operations non-commutative - but I also
    would need to put more brains in every calculation, which could
    finally take more effort than only "upgrading" the display :-???
    Seems I end up with your suggestion - if noone else has an idea ;-)

    The application will be a browsergame, and most gamers start counting
    at 1, so they would probably wonder about a "level 0 item" ;-)
    If there didn't already exist lots of code, I would redesign the whole
    data-structure - I think that's "lessons learned" for the next project
    -.-
     
    Andreas Pfrengle, Aug 3, 2010
    #5
  6. Andreas Pfrengle

    rantingrick Guest

    > On Aug 3, 5:15 am, Andreas Pfrengle <> wrote:
    >
    > Seems I end up with your suggestion - if noone else has an idea ;-)



    START_COUNTING_FROM_HERE = 1
     
    rantingrick, Aug 3, 2010
    #6
  7. Andreas Pfrengle wrote:
    > On 3 Aug., 03:22, Carl Banks <> wrote:>
    >
    >> You are creating an object that differs from a built-in, int, in a
    >> highly misleading way that only makes sense in a very limited context,
    >> and this object's modified behavior gives no clue that it's been
    >> modified in such as way. (That is, it's not possible to tell if the
    >> object's not a regular int just by looking at __str__()'s return
    >> value.) To make matters worse, you want to program this object to
    >> coerce other integers, so there's a risk of these objects escaping
    >> from the context where they make sense.
    >>
    >> This is just a bad idea. The type is not the place to implement
    >> behavior that makes sense only in a limited context. Instead, do
    >> something like this:
    >>
    >> print "Item %d is %s." % (i+1, s)
    >>

    >
    > I see your concerns. I started with the approach to add +1 directly
    > before displaying the int. However, since there are some variables
    > that shall be displayed normally and others that are indices I want to
    > show starting at 1, I thought the easiest way would be to define a
    > type that does the job, then I would only need to define it once and
    > not take care everywhere whether I have a normal variable or a
    > displayed index.
    > Thinking about it, it might really be dangerous to coerce always to
    > int1, since sometimes I might want a normal int as result (I can't
    > tell yet for sure).
    > I'm just thinking about only overloading the operations if the int1 is
    > on the left-hand side (so __op__ coerces to int1, while __rop__
    > doesn't). This would make operations non-commutative - but I also
    > would need to put more brains in every calculation, which could
    > finally take more effort than only "upgrading" the display :-???
    > Seems I end up with your suggestion - if noone else has an idea ;-)
    >
    > The application will be a browsergame, and most gamers start counting
    > at 1, so they would probably wonder about a "level 0 item" ;-)
    > If there didn't already exist lots of code, I would redesign the whole
    > data-structure - I think that's "lessons learned" for the next project
    > -.-
    >

    The level of an item is attribute of this item, not an index in a list.
    You may have an issue with your design, using an improper structure.

    In a more general manner, given your example I don't see why you should
    expose the index of an element in an internal list to the user.

    JM
     
    Jean-Michel Pichavant, Aug 3, 2010
    #7
  8. Jean-Michel Pichavant wrote:
    > Andreas Pfrengle wrote:
    >> On 3 Aug., 03:22, Carl Banks <> wrote:>
    >>
    >>> You are creating an object that differs from a built-in, int, in a
    >>> highly misleading way that only makes sense in a very limited context,
    >>> and this object's modified behavior gives no clue that it's been
    >>> modified in such as way. (That is, it's not possible to tell if the
    >>> object's not a regular int just by looking at __str__()'s return
    >>> value.) To make matters worse, you want to program this object to
    >>> coerce other integers, so there's a risk of these objects escaping
    >>> from the context where they make sense.
    >>>
    >>> This is just a bad idea. The type is not the place to implement
    >>> behavior that makes sense only in a limited context. Instead, do
    >>> something like this:
    >>>
    >>> print "Item %d is %s." % (i+1, s)
    >>>

    >>
    >> I see your concerns. I started with the approach to add +1 directly
    >> before displaying the int. However, since there are some variables
    >> that shall be displayed normally and others that are indices I want to
    >> show starting at 1, I thought the easiest way would be to define a
    >> type that does the job, then I would only need to define it once and
    >> not take care everywhere whether I have a normal variable or a
    >> displayed index.
    >> Thinking about it, it might really be dangerous to coerce always to
    >> int1, since sometimes I might want a normal int as result (I can't
    >> tell yet for sure).
    >> I'm just thinking about only overloading the operations if the int1 is
    >> on the left-hand side (so __op__ coerces to int1, while __rop__
    >> doesn't). This would make operations non-commutative - but I also
    >> would need to put more brains in every calculation, which could
    >> finally take more effort than only "upgrading" the display :-???
    >> Seems I end up with your suggestion - if noone else has an idea ;-)
    >>
    >> The application will be a browsergame, and most gamers start counting
    >> at 1, so they would probably wonder about a "level 0 item" ;-)
    >> If there didn't already exist lots of code, I would redesign the whole
    >> data-structure - I think that's "lessons learned" for the next project
    >> -.-
    >>

    > The level of an item is attribute of this item, not an index in a list.
    > You may have an issue with your design, using an improper structure.
    >
    > In a more general manner, given your example I don't see why you
    > should expose the index of an element in an internal list to the user.
    >
    > JM
    >

    "If there didn't already exist lots of code, I would redesign the whole
    data-structure"

    sorry I didn't get this one at first read, my comment is pretty much
    useless.

    JM
     
    Jean-Michel Pichavant, Aug 3, 2010
    #8
  9. Hi Andreas,

    On Aug 3, 2010, at 1:52 AM, Andreas Pfrengle wrote:
    > I'm trying to define a subclass of int called int1. An int1-object
    > shall behave exactly like an int-object, with the only difference that
    > the displayed value shall be value + 1 (it will be used to display
    > array indices starting at 1 instead of 0). Right now I have:
    >
    > class int1(int):
    > def __str__(self):
    > return int.__str__(self + 1)
    >
    > However, if I calculate with int1 and int- (or other number) objects,
    > the result is always coerced to an int (or other number object), e.g:
    > a = int1(5)
    > b = 5
    > print a # "6"
    > print a+b #"10"
    >
    > How can I tell int1 to be the "default integer object"? Do I need to
    > overload *every* mathematical operation method of int, or is there an
    > easier way?


    Maybe you could use:
    1) a dict with keys 1..n
    2) a simple list (or iterable) subclass with 1-based indices.

    class list1(list):
    def __new__(cls, *args, **kwargs):
    return list.__new__(cls, *args, **kwargs)

    def __getitem__(self, key):
    return list.__getitem__(self, key-1)

    ... etcetera


    Cheers, Roald
     
    Roald de Vries, Aug 3, 2010
    #9
  10. Hi Andreas,

    On 2010-08-03 12:15, Andreas Pfrengle wrote:
    > On 3 Aug., 03:22, Carl Banks <> wrote:>
    > Thinking about it, it might really be dangerous to coerce always to
    > int1, since sometimes I might want a normal int as result (I can't
    > tell yet for sure).


    Yes, that way your problem may shift from inconvenient to
    outright hairy. ;-)

    > The application will be a browsergame, and most gamers start counting
    > at 1, so they would probably wonder about a "level 0 item" ;-)
    > If there didn't already exist lots of code, I would redesign the whole
    > data-structure - I think that's "lessons learned" for the next project


    What about

    def _index_to_level(index):
    return index + 1

    with this or a different name? This admittedly is longer
    than writing `something + 1` but in the latter case you
    might wonder what the addition is for, i. e. if it's really
    a level offset calculation or something else.

    Stefan
     
    Stefan Schwarzer, Aug 5, 2010
    #10
  11. Hello everyone,

    thanks for all the suggestions. I did effort to redesign parts of the
    data structure the last days, but not all (only those I could easily
    keep track of in my code).
    For the rest I add +1 before the presentation and comment it. Seems
    the easiest way now.

    Andreas
     
    Andreas Pfrengle, Aug 5, 2010
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jstorta
    Replies:
    3
    Views:
    457
    jstorta
    Feb 20, 2006
  2. Replies:
    3
    Views:
    237
    Gabriel Genellina
    Dec 20, 2007
  3. S.Volkov
    Replies:
    2
    Views:
    230
    S.Volkov
    Mar 12, 2006
  4. Trans
    Replies:
    8
    Views:
    332
    Robert Klemme
    Oct 23, 2008
  5. Fab

    Subclass of subclass

    Fab, Aug 9, 2012, in forum: C++
    Replies:
    0
    Views:
    403
Loading...

Share This Page