Reputation: 15
I'm currently trying to write a script that will create a unique ID for a user relying on a number of variables, like birthdate, name, hometown, etc. This creates a very long number that is completely unique to that user, however, to try to make the number even more unique, I want to change a random number in the string. This is what I have so far:
rand = randint(1,15)
tempid = id / 10**rand
if randint(1,2) == 1:
tempid = tempid + randint(2,10000)
else:
tempid = tempid - randint(5,7500)
print(id)
id = tempid * (10**rand)
print(str(id))
The code is fairly simple. It makes the number much smaller by dividing it by a large multiple of 10, adds or subtracts a random number, and multiplies it back to it's original length, with some changed numbers in the middle. The only problem is, because it must be an integer to be able to do any math with it, Python shortens it to 1.[something]e+[something]. This isn't helpful at all, becasue now it's not an ID. Is there anyway I can change it back to its original form, where it's just a long string, or perhaps change the code so it never becomes e? Thank you!
Upvotes: 0
Views: 155
Reputation: 6891
I also agree with the other answers; as far as best practice goes, you should not do it this way at all. You will almost certainly make a worse than optimal solution. However, to solve the actual problem you pose, I would want to approach it in a different manner.
The problem is, as stated, that your division will not leave you with an integer result, which makes Python automatically convert to a float. This is not what you want if you want to keep your value unique. You want to do all your calculations on integers only. To achieve that, the simplest way is to multiply your modifiers, instead of dividing your original number. That way you will never leave the integer domain, and there is no need to convert you value back to an integer:
print(id)
rand = randint(1,15)
multiplier = 10**rand
if randint(1,2) == 1:
id += multiplier * randint(2,10000)
else:
id -= multiplier * randint(5,7500)
print(id)
In addition I have used a bit of syntactic sugar, that I find rather nice, namely +=
and -=
. They add and subtract a value from your variables respectively: a = a + 3
<=> a += 3
.
Upvotes: 0
Reputation: 22564
Your problem is that id
when you print it refers to a large float
value, which is then printed in exponential notation. If it were an integer value, no e
would be in the printout. The float value comes from your line
tempid = id / 10**rand
which, in Python 3.x, stores a float value in tempid
. You later execute
id = tempid * (10**rand)
which multiplies a float by an integer, resulting in a float, and that float is what is printed in the next line
You can avoid this in several ways. You can keep all the calculations in integers by replacing your division line with
tempid = id // 10**rand
That extra slash mark means integer division, so tempid
here and id
later are integers. However, this may change the resulting values. So a better way is allow tempid
to be a float but ensure that id
is always an integer, using
id = int(tempid * (10**rand))
This should keep all your values the same and give you the print you want.
That answers your actual question. However, I agree with @user2722968 that if your purpose is to create a unique ID you should use module meant for that purpose, such as uuid. The history of computing shows that randomizing a part of a string to get a random value does poorly, and getting actual random or unique values is difficult to get right. You should do it the way others have shown to work well.
Upvotes: 0
Reputation: 16535
Unless this is a specific exercise, you do not want to generate unique IDs the way you do. It will fail. Use the uuid module instead.
Upvotes: 2