[ACCEPTED]-increment int object-int

Accepted answer
Score: 14

ints are immutable, so you'll have to build 2 your own class with all the int's methods 1 if you want a "mutable int"

Score: 8

You can use ctypes as mutable integers. Choosing 3 the right ctype will be important though, as 2 they limit the size of integer they can 1 carry.

>>> from ctypes import c_int64
>>> num = c_int64(0)
>>> id(num)
4447709232
>>> def increment(number):
...     number.value += 1
... 
>>> increment(num)
>>> increment(num)
>>> increment(num)
>>> num.value
3
>>> id(num)
4447709232
>>> 

More info: https://docs.python.org/2/library/ctypes.html#fundamental-data-types

Score: 6

If you absolutely have to get that code 9 to work, here's a dirty method, where an 8 instance method moves up a frame and overwrites 7 its own locals entry. Wouldn't recommend. (like, really 6 not. I'm not even sure what that does. What 5 happens to the old instance? I don't know 4 enough about frames...). Really, I'm only 3 posting this because everyone said it's 2 impossible, when in reality it's just ridiculously 1 bad form. ;-)

import sys
class FakeInt(int):
    def __init__(self, *arg, **kwarg):
        self._decr = False
        int.__init__(self, *arg, **kwarg)
    def __neg__(self):
        if self._decr:

            upLocals = sys._getframe(1).f_locals
            keys, values = zip(*upLocals.items())
            i = list(values).index(self)

            result = FakeInt(self-1)
            upLocals[keys[i]]=result

            return result
        self._decr = not self._decr
        return self

A = FakeInt(10)
while --A:
    print A,

outputs:

9 8 7 6 5 4 3 2 1
Score: 5

You can put an immutable object inside a 10 mutable container; lists are easiest.

This 9 code prints 0, demonstrating the problem:

a = 0       # `a` points to a new int (a `0`)
b = a       # `b` points to the same thing as `a` (the `0`)
b = 1       # `b` points to a new int (a `1`)
print(a)    # `a` still points to the same thing (the `0`)

If 8 you put the int in a list, but otherwise 7 use the same code as before, you can get 6 the effect of having a mutable int (though 5 it's the list that is being mutated really):

a = [0]        # `a` points to a new `0` inside a new list
b = a          # `b` points to the same thing as `a` (the list)
b[0] = 1       # the list that `a` and `b` point to is mutated
print(a[0])    # `a[0]` points to the same object as `b[0]` (the `1`)

In 4 practice, you should structure your data 3 so that the above 'trick' is redundant. The 2 examples should not be used directly, but 1 should help you figure out what to do.

Score: 4

It would probably be easier to create a 2 class that implements the int methods and 1 wraps an internal integer.

Score: 0

Yes, the short answer is that, ints are 1 immutable.

Score: 0

I had a similar issue today and came up 15 with a class called IterInt that lets you 14 increment or decrement in place using "+" and 13 "-" decorators.

Usage:

x = IterInt()

print x
# result: 0

print +x
# result: 1

print +x
# result: 2

print +x
# result: 3

print -x
# result: 2

print -x
# result: 1

print -x
# result: 0

In my case I had a 12 situation where I wanted to modify an application's 11 existing menu by inserting several command 10 items after a specific index. The provided 9 API I'm using has an "addCommand" function 8 that can take an index at which to insert.

Consider 7 this pseudo code where menu has commands 6 a through g, something like menu = [a, f, g], and 5 I want to insert b-e at index 1-4

idx = 1
menu.addCommand(b, index=idx)
idx += 1
menu.addCommand(c, index=idx)
idx += 1
menu.addCommand(d, index=idx)
idx += 1
menu.addCommand(e, index=idx)
idx += 1

# result: menu = [a, b, c, d, e, f]

It would 4 be nice if I could write it so idx increments 3 in place like c where I could do idx++, but 2 functions do not allow python's idx+=1 methodology 1 in arguments.

Solution:

class IterInt(int):
"""
This function will return the next integer from the init_value starting point or 0 if None.
Each subsequent call to increment returns the next value
:param init_value:
:return:
"""
def __init__(self, init_value=None):
    if init_value is None:
        init_value = 0

    if init_value is not None:
        self.increment_value = init_value
    self.increment_value = init_value

def __pos__(self):
    self.increment_value += 1
    return self.increment_value

def __neg__(self):
    self.increment_value -= 1
    return self.increment_value


idx = IterInt(1)
menu.addCommand(b, index=+idx)
menu.addCommand(c, index=+idx)
menu.addCommand(d, index=+idx)
menu.addCommand(e, index=+idx)

# result: menu = [a, b, c, d, e, f]

More Related questions