Emulate uint32_t in Python? - python

I was trying to port a function from C to Python and to make it easy to debug, I'd prefer it performed the same CPU word-size limited operations so I could compare the intermediate results. In other words, I'd like something like:
a = UnsignedBoundedInt(32, 399999)
b = UnsignedBoundedInt(32, 399999)
print(a*b) # prints 1085410049 (159999200001 % 2**32)
What's the best way to achieve this so that all operations (including bitwise shifts) would work as in C?

You can try using ctypes.uint_32 to bound the results for you:
>>> import ctypes
>>> print ctypes.c_uint32(399999 * 399999).value
1085410049
Alternatively you can use numpy's data types:
>>> import numpy as np
>>> a = np.uint32(399999)
>>> b = np.uint32(399999)
>>> a * b
__main__:1: RuntimeWarning: overflow encountered in uint_scalars
1085410049

Here's an interesting solution, though it only works under Python 2:
class U32:
"""Emulates 32-bit unsigned int known from C programming language."""
def __init__(self, num=0, base=None):
"""Creates the U32 object.
Args:
num: the integer/string to use as the initial state
base: the base of the integer use if the num given was a string
"""
if base is None:
self.int_ = int(num) % 2**32
else:
self.int_ = int(num, base) % 2**32
def __coerce__(self, ignored):
return None
def __str__(self):
return "<U32 instance at 0x%x, int=%d>" % (id(self), self.int_)
def __getattr__(self, attribute_name):
print("getattr called, attribute_name=%s" % attribute_name)
# you might want to take a look here:
# https://stackoverflow.com/q/19611001/1091116
r = getattr(self.int_, attribute_name)
if callable(r): # return a wrapper if integer's function was requested
def f(*args, **kwargs):
if args and isinstance(args[0], U32):
args = (args[0].int_, ) + args[1:]
ret = r(*args, **kwargs)
if ret is NotImplemented:
return ret
if attribute_name in ['__str__', '__repr__', '__index__']:
return ret
ret %= 2**32
return U32(ret)
return f
return r
print(U32(4) / 2)
print(4 / U32(2))
print(U32(4) / U32(2))
For Python 3 compatibility, have a look here.

Related

Python 3.5.1 - variable returns none

My question is regarding some code that is part of an Udacity assignment. The following code is not returning any value. I assume that I'm not calling the "scalar" function properly from my "normalized" function. The line norm = self.scalar(scale) returns type none. Can someone give me a pointer?
Code:
import math
from decimal import Decimal, getcontext
getcontext().prec = 10
class Vector(object):
def __init__(self, coordinates):
try:
if not coordinates:
raise ValueError
self.coordinates = tuple([Decimal(x) for x in coordinates])
self.dimension = len(self.coordinates)
except ValueError:
raise ValueError('The coordinates must be nonempty')
except TypeError:
raise TypeError('The coordinates must be an iterable')
def __eq__(self, v):
return self.coordinates == v.coordinates
def scalar(self, c):
new_coordinates = [Decimal(c)*x for x in self.coordinates]
#new_coordinates = []
#n = len(self.coordinates)
#for i in range(n):
# new_coordinates.append(self.coordinates[i] * c)
#print(Vector(new_coordinates))
def magnitude(self):
new_sq = [x**2 for x in self.coordinates]
new_mag = math.sqrt(sum(new_sq))
return (new_mag)
def normalized(self):
magnitude = self.magnitude()
scale = 1/magnitude
print(scale)
norm = self.scalar(scale)
#print(type(norm))
print(norm)
return (norm)
my_vector = Vector([1,2])
Vector.normalized(my_vector)
Python has this cool little trick where it will always return None if not specified. So if you write a function hello world that doesn't return anything you will get None.
for example:
def hello_world():
print('hello world')
result = hello_world()
print(result) # prints nothing cause result==None
You dont have a return statement in your scalar method, so it will always return None.
My guess is that you want to return the object you create in scalar
def scalar(self, c):
new_coordinates = [Decimal(c)*x for x in self.coordinates]
return new_coordinates
Or for brevity
def scalar(self, c):
return [Decimal(c)*x for x in self.coordinates]
The problem is that you're trying to get a value from scalar even though it doesn't return anything. I'm not entirely sure what you're trying to return so you'll have to deal with that yourself.
One notable issue is with your method calling the attribute of the my_vector instance. It's not technically the issue, but it should probably be changed. Your code should be the following.
my_vector = Vector([1,2])
my_vector.normalized()

Define a new numerical base in python (new charset)

I would like to know how to define a new numerical base in Python.
For example:
base dimension = 4
Charset = 'u', '$', '6', '}' (from the least important to the most)
I would like to know how to create and handle it, to be able to do simple arithmetic like:
$} + 6u * 6 = $$}
7 + 8 * 2 = 23
I know I could use replace to replace u -> 0, $ -> 1 and so on, and use the int() function. However int() is not defined for base > 36, and I will have to handle these cases.
I know I could make my own function to convert them to base 10, do the math, and convert them back, but I would like to avoid that if possible.
Rather than replace, you can use dictionaries to translate back and forth between the charset and regular ints, something like:
charset = 'u$6}'
b = len(charset) #base
vals = {c:i for i,c in enumerate(charset)}
digits = {vals[c]: c for c in vals} #inverse dictionary
def toInt(s):
return sum(vals[c]*b**i for i,c in enumerate(reversed(s)))
def toNewBase(n):
nums = [] if n > 0 else [0]
while n > 0:
n,r = divmod(n,b)
nums.append(r)
return ''.join(digits[i] for i in reversed(nums))
def add(s,t):
return toNewBase(toInt(s) + toInt(t))
def subtract(s,t):
return toNewBase(toInt(s) - toInt(t))
def multiply(s,t):
return toNewBase(toInt(s) * toInt(t))
def divide(s,t):
return toNewBase(toInt(s) // toInt(t))
typical output:
>>> add('$}',multiply('6u','6'))
'$$}'
def str_base(number, base):
# http://stackoverflow.com/a/24763277/3821804
(d,m) = divmod(number,len(base))
if d > 0:
return str_base(d,base)+base[m]
return base[m]
def charset(chars):
class cls(int):
__slots__ = ()
def __new__(cls, src):
if isinstance(src, str):
return int.__new__(
cls,
''.join(str(chars.index(i)) for i in src),
len(chars)
)
return int.__new__(cls, src)
def __str__(self):
return str_base(self, chars)
def __repr__(self):
return '%s(%r)' % (type(self).__name__, str(self))
cls.__name__ = 'charset(%r)' % chars
return cls
Usage:
test = charset('u$6}')
print(test( test('$}') + test('6u') * test('6') ) ) # => '$$}'
See it working online: http://rextester.com/WYSE48066
At the moment, I'm too tired to explain it.

Enforcing type restriction in list abstraction using python

Below is the list abstraction in functional paradigm, that encapsulates any type of data in its representation.
empty_rlist = None
#Representation - start
#Constructor
def rlist(first, rest):
return(first, rest)
#Selector
def first(s):
return s[0]
def rest(s):
return s[1]
#Representation - end
#Constructor and Selector constitutes ADT(above) that supports below invariant:
#If a recursive list s is constructed from a first element f and a recursive list r, then
# • first(s) returns f, and
# • rest(s) returns r, which is a recursive list.
#Usage(interface) - start
def create_list(first, rest):
return rlist(first, rest)
def len_rlist(s):
"""Compute the length of the recursive list s"""
def compute_length(s, length):
if s is empty_rlist:
return length
else:
return compute_length(rest(s), length + 1)
return compute_length(s, 0)
def getitem_rlist(s, i):
"""Return the element at index i of recursive list s"""
if i == 1:
return first(s)
else:
return getitem_rlist(rest(s), i-1)
def count(s, value):
"""Count the occurence of value in the list s """
def count_occurence(s, value, count):
if s == empty_rlist:
return count
else:
if first(s) == value:
return count_occurence(rest(s), value, count + 1)
else:
return count_occurence(rest(s), value, count)
return count_occurence(s, value, 0)
#Usage - end
Lst = empty_rlist
Lst = create_list(4, Lst)
Lst = create_list(3, Lst)
Lst = create_list(1, Lst)
Lst = create_list(1, Lst)
print(count(Lst, 1))
In the above code, interfaces that are provided to users of this abstraction are create_list / len_rlist / getitem_rlist / count.
Questions:
How to enforce that the object passed to parameter(s) of interfaces len_rlist / getitem_rlist / count is nothing but the object provided by create_list interface?
How to enforce above list abstraction store same type data?
Note: Practically it is required to enforce these rules from syntax perspective.
Because python is dynamicaly typed language you can't check type before executing. But in reality sometimes need check input parameters, return values. I use next solutions for this tasks:
def accepts(*types):
"""Check input types"""
#print types
def check_accepts(f):
assert len(types) == f.func_code.co_argcount
def new_f(*args, **kwds):
for (a, t) in zip(args, types):
assert isinstance(a, t), \
"arg %r does not match %s" % (a,t)
return f(*args, **kwds)
new_f.func_name = f.func_name
return new_f
return check_accepts
def returns(rtype):
"""Check returns type"""
def check_returns(f):
def new_f(*args, **kwds):
result = f(*args, **kwds)
assert isinstance(result, rtype), \
"return value %r does not match %s" % (result,rtype)
return result
new_f.func_name = f.func_name
return new_f
return check_returns
if __name__ == '__main__':
import types
#returns(types.NoneType) #Check None as result
#accepts(int, (int,float)) #First param int; second int or float
def func(arg1, arg2):
#return str(arg1 * arg2)
pass
func(1, 2)
In order to enforce the type, you will have to provide the type as a parameter somewhere in your constructor. Consider building a parameterized type constructor. Here is an example.
>>> def list_spec_for(type_):
... empty_rlist = type_()
... def rlist(first, rest):
... return (type_(first), rest)
... return empty_rlist, rlist
>>> empty_rlist, rlist = list_spec_for(int)
>>> empty_rlist
0
>>> rlist(1, empty_rlist)
(1, 0)
>>> rlist("1", empty_rlist)
(1, 0)
>>> rlist("one", empty_rlist)
ValueError: invalid literal for int() with base 10: 'one'
If accepting "1" is not OK for your purpose, you can of course add an isinstance check to the definition of rlist.
Python is not a strongly typed language. More exactly, it is a dynamic typed. That means that variables contains values that do have a type, but the language itself will never forbids to put a value of a different type in a variable.
a = 1 # a contains an integer value
a = "abc" # a now contains a string value
But, you have the isinstance and type functions that could help to achieve this requirement : you could affect a type to your recursive list and only allow to bind together an element and a recursive list of compatible types.
The full spec could be :
a rlist stores the type of the element it accepts
a rlist can be constructed by adding a first element for which isinstance(elt, typ) is true, and typ is the accepted typ of the rest part
an initial list can be constructed by giving it explicetly a type, or by using the type of its first element
Implementation:
class rlist:
def __init__(self, first, rest=None, typ=None):
self.first = first
self.rest = rest
if rest is None: # initial creation
self.typ = type(first) if typ is None else typ
else:
if not isinstance(rest, rlist):
raise TypeError(str(rest) + " not a rlist"
self.typ = rest.typ
if not isinstance(first, self.typ):
raise TypeError(str(first) + "not a " + str(typ))
# other methods ...
But when you need strong typing, you should wonder if Python is really the appropriate language - Java is strongly typed and natively supports all that. The Python way is more I accept this and just hope it'll fit, programmer should know what he does

Why does Python call __str__ instead of returning long value

I have a simple class that extends long to accept a string with value modifiers (ie '10m' would be 1024*1024*10)
I have the __str__ function that prints the original value passed in (ie if '10m' is passed in, return '10m')
Problem is that when I call something such as:
>>> printf("%d" % Size('10m'))
I get the following
SystemError: ../Objects/stringobject.c:4044: bad argument to internal function
Obviously if I print "%s" I get '10m'
So the question is, since I'm subclassing long, why does the class call __str__ when it should be getting the long value.
BTW, a bit more testing shows that the %x and %f will print the integer value which confuses me more. I also tried adding the __format__ but that appears to only be called on when "...".format() is called.
EDIT #1, Here's the code:
class Size(long):
'''Represents a size reflected bytes. Subclass of long.
Size passed in must be in the formats <int> or "0x<int>" or "0x<int><unit>" or "<int><unit>" or "<int><unit><int><unit>....".
"0x<int><unit>0x<int><unit>" or similar numbers are not supported as is "<int><unit><int>"
b = bytes
s = sectors (512-byte)
k = kilobytes
m = megabytes
g = gigabytes
t = terabytes
'''
units = { 'b':1, 's':512, 'k':1024, 'm':1024 ** 2, 'g':1024 ** 3, 't':1024 ** 4 }
def __new__(cls, value):
'''Creates a Size object with the specified value.
Value can be a number or a string (optionally prefixed with '0x' or
postfixed with a type character). If using hex, the final character
will be treated as part of the value if it is a hex digit, regardless
of whether it is a valid unit character.
Examples:
Size(50)
Size("0x100s") # 256 sectors
Size("64")
Size("512k")
Size("0x1b") # this is 1b bytes, not 1 byte
'''
self = _new_unit_number(value, cls.units, long, cls)
return self
def __init__(self, value):
self._orig_value = value
def __str__(self):
print "calling str"
return str(self._orig_value) # Convert to str in case the object was created w/an int
def __format__(self, format_spec):
print "calling format"
print format_spec
try:
value = format(str(self), format_spec)
except ValueError:
value = format(int(self), format_spec)
return value
def _new_unit_number(value, unit_list, num_type, cls):
'''Converts a string of numbers followed by a unit character to the
requested numeric type (int or long for example).
'''
base = 10
start = 0
digits = string.digits
try:
if value[0:2] == '0x':
start = 2
base = 16
digits = string.hexdigits
if value[-1] in digits:
return num_type.__new__(cls, value[start:], base)
else:
try:
# Use a regex to split the parts of the unit
regex_string = '(\d+[%s])' % (''.join(unit_list.keys()))
parts = [x for x in re.split(regex_string, value[start:]) if x]
if len(parts) == 1:
return num_type.__new__(cls, num_type(value[start:-1], base) * unit_list[value[-1]])
else:
# Total up each part
# There's probably a better way to do this.
# This converts each unit to its base type, stores it in total,
# only to be converted back to the base type.
total = 0
for part in parts:
total += num_type(part[start:-1], base) * unit_list[part[-1]]
# Finally return the requested unit
return num_type.__new__(cls, total)
except KeyError:
raise ValueError("Invalid %s unit identifier: %s"
% (cls.__name__, unit_list[value[-1]]))
# not a string or empty, see if we can still use the class's constructor
except (TypeError, IndexError):
return num_type.__new__(cls, value)
Not really an answer, but too long for a comment.
I find this question highly interesting. I tried to replicate the behaviour using this:
#! /usr/bin/python2.7
class Size (long):
def __new__ (cls, arg):
if arg and type (arg) == str:
if arg [-1] == 'm':
return super (Size, cls).__new__ (cls, long (arg [:-1] ) * 2 ** 20)
return super (Size, cls).__new__ (cls, arg)
def __init__ (self, arg):
self.s = arg
def __str__ (self):
return self.s
a = Size ('12m')
print (a)
print ('%s' % a)
#The following fails horribly
print ('%d' % a)
Behaviour as described by OP. But now comes the funny part: When I inherit from int and not from long, it works smoothly:
class Size (int):
def __new__ (cls, arg):
if arg and type (arg) == str:
if arg [-1] == 'm':
return super (Size, cls).__new__ (cls, int (arg [:-1] ) * 2 ** 20)
return super (Size, cls).__new__ (cls, arg)
def __init__ (self, arg):
self.s = arg
def __str__ (self):
return self.s
That is, it works fine in python2, but fails in python3. Strange, strange.
Please see Python issue tracker, Issue 18780: SystemError when formatting int subclass:
>>> class I(int):
... def __str__(self):
... return 'spam'
...
>>> '%d' % I(42)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
SystemError: Objects/unicodeobject.c:13305: bad argument to internal function
This works in 3.4.0alpha4, but not in 3.[0123].

nice decimal.Decimal autonormalization

This gonna be my first question here. I am trying to make a decimal.Decimal child class which mainly differs the parent by making autonormalization on itself and on the results of its callable arguments whose returns Decimal objects. The code below have the concept to
decorate all methods of Decimal to return MyDecimal instances (whose trim zeros of the end of their strings by creation) instead of decimal.Decimals. For this, metaclass was used.
However, I feel this code a bit hacky though. Moreover, according to the speed test results, it is also damn slow: 2.5 secs for the decimal.Decimal vs. 16 secs for MyDecimal on my system.
My question is: Is there a cleaner (and faster) way of doing this?
import decimal
class AutoNormalizedDecimal(type):
def __new__(cls, name, bases, local):
local_items = list(local.items())
parent_items = [i for i in bases[0].__dict__.items()
if i[0] not in local.keys()]
for a in local_items + parent_items:
attr_name, attr_value = a[0], a[1]
if callable(attr_value):
local[attr_name] = cls.decorator(attr_value)
return super(AutoNormalizedDecimal, cls).__new__(
cls, name, bases, local)
#classmethod
def decorator(cls, func):
def wrapper_for_new(*args, **kwargs):
new_string = args[1].rstrip('0').rstrip('.')
if not new_string:
new_string = '0'
newargs = (args[0], new_string)
return func(*newargs, **kwargs)
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
if (isinstance(result, decimal.Decimal)
and not isinstance(result, MyDecimal)):
return MyDecimal(str(result))
return result
if func.__name__ == '__new__':
return wrapper_for_new
return wrapper
class MyDecimal(decimal.Decimal, metaclass=AutoNormalizedDecimal):
def __str__(self):
return decimal.Decimal.__str__(self).replace('.', ',')
n = MyDecimal('-5423.5420000')
def speedtest():
import time
start = time.time()
d = decimal.Decimal('6')
for i in range(1000000):
d += decimal.Decimal(str(i))
print(time.time()-start)
start = time.time()
d = MyDecimal('6')
for i in range(1000000):
d += MyDecimal(str(i))
print(time.time()-start)
Here is how this works:
>>> n
Decimal('-5423.542')
>>> type(n)
<class '__main__.MyDecimal'>
>>> str(n)
'-5423,542'
>>> x = MyDecimal('542.63') / MyDecimal('5.2331')
>>> x
Decimal('103.6918843515315969501824922')
>>> type(x)
<class '__main__.MyDecimal'>
>>> y = MyDecimal('5.5252') - MyDecimal('0.0052')
>>> y
Decimal('5.52')
>>> z = decimal.Decimal('5.5252') - decimal.Decimal('0.0052')
>>> z
Decimal('5.5200')
Thanks in advance!
PS: Credit goes to Anurag Uniyal for his code which gave me a way to start: https://stackoverflow.com/a/3468410/2334951
EDIT1: I came out to redefine as_tuple() method which I could call all the time I need the trimmed Decimal version:
class MyDecimal(decimal.Decimal):
def as_tuple(self):
sign, digits_, exponent = super().as_tuple()
digits = list(digits_)
while exponent < 0 and digits[-1] == 0:
digits.pop()
exponent += 1
while len(digits) <= abs(exponent):
digits.insert(0, 0)
return decimal.DecimalTuple(sign, tuple(digits), exponent)
def __str__(self):
as_tuple = self.as_tuple()
left = ''.join([str(d) for d in as_tuple[1][:as_tuple[2]]])
right = ''.join([str(d) for d in as_tuple[1][as_tuple[2]:]])
return ','.join((left, right))

Categories

Resources