-1

I faced a curious problem while taking the writing of an integer in bits in Python (I am working in Sage)

I first tried to run the code

m=7
m.bits()

Everything worked fine there. Then, I wanted to do this with a random integer. Thus, I tried to run the code

import random
m=randint(2,10)
m.bits()

That is where I got the error "AttributeError: 'int' object has no attribute 'bits'" as if the function randint was not returning an integer. I managed to force it to be an integer by doing

m=m+0

However, I am still wondering why the first writing was not working. I have to say that I am coding on online sage, even if I do not think this should be an issue.

Thanks in advance!

Jongware
  • 22,200
  • 8
  • 54
  • 100
H. Potter
  • 119
  • 7
  • Plain Python integers don't have a `.bits` method, but Sage Integers do: http://doc.sagemath.org/html/en/reference/rings_standard/sage/rings/integer.html#sage.rings.integer.Integer.bits – PM 2Ring Jan 03 '17 at 14:15
  • @vaultah I tried it in Sage and it did work. Maybe they have implemented such a method in Sage – H. Potter Jan 03 '17 at 14:16
  • The result of randint() is an int: `from random import randint; type(randint(2,10))` -> `` – Rudi Jan 03 '17 at 14:19
  • I don't now what Sage is , but can you explain what .bits() do, maybe there is a phytonic function for that – ᴀʀᴍᴀɴ Jan 03 '17 at 14:19
  • OTOH, you can use the builtin `bin` function in standard Python to get the binary representation of an in int as a string, eg `bin(13), which prepends `'0b'` to the bit string. Another option to do that is to use the format function or the `.format` method of `str`. Eg, `format(13, 'b')` or `'{0:b}'.format(13)`, neither of which prepends `'0b'`. – PM 2Ring Jan 03 '17 at 14:20
  • @PM2Ring `'{0:b}'.format(13)` – Łukasz Rogalski Jan 03 '17 at 14:21
  • @Arman 8.bits() returns an array of length 4 where all entries are equal to 0 except the last one which is a 1. It's the writing of that integers in binary. (Sage is a program that let you code with complex mathematical objects (e.g. finite fields, elliptic curves)) – H. Potter Jan 03 '17 at 14:24
  • So try `bin` function , it represent binary of an integer instead `bits` – ᴀʀᴍᴀɴ Jan 03 '17 at 14:26
  • And in Python 3.6+ you can use an f-string, eg `n=13; f'{n:b}'` – PM 2Ring Jan 03 '17 at 14:26
  • @PM2Ring Well, I did found a solution by doing m=m+0, I was just wondering why I had to do that to avoid that error. Thanks for your help anyway :) – H. Potter Jan 03 '17 at 14:27
  • 1
    Presumably `m = m + 0` converts an ordinary Python `int` object into a Sage `int` object. If you are running this in Sage, `0` must be interpreted as a Sage int and `+` as the operator which (when fed an int and a Sage int) returns a Sage int object. – John Coleman Jan 03 '17 at 14:31
  • @JohnColeman it certainly does, since most likely `__add__` between Sage integer and standard Python integer is implemented to return instance of former one. They just forgot to decorate `random.randint` so it returns their integer. – Łukasz Rogalski Jan 03 '17 at 14:35
  • Sage didn't necessarily "forget" to decorate, in this case the "Sage" version of `random` was to allow the seed to be consistently set but otherwise mimic the module completely. – kcrisman Jan 03 '17 at 15:00

1 Answers1

1

For a random Sage integer (using various distributions), use ZZ.random_element (doc here). Try this example:

a = ZZ.random_element(2,10)
a.bits()

I've opened Trac 22131 to clarify this issue; one shouldn't have to do something quite this elaborate, there could be a random_integer function at the top level. (There is a random_prime, for instance.)

kcrisman
  • 4,374
  • 20
  • 41