views:

210

answers:

4

I have a ridiculous code segment in one of my programs right now:

str(len(str(len(var_text)**255)))

Is there an easy way to shorten that? 'Cause, frankly, that's ridiculous.

A option to convert a number >500 digits to scientific notation would also be helpful (that's what I'm trying to do)

Full code:

print("Useless code rating:" , str(len(var_text)**255)[1] + "e" + str(len(str(len(var_text)**255))))
A: 

This looks like it's producing a string version of the number of digits in the 255th power of the length of a string. Is that right? I'd be curious what that's used for.

You could compute the number differently, but it's not shorter and I'm not sure it's prettier:

str(int(math.ceil(math.log10(len(var_text))*255)))

or:

"%d" % math.ceil(math.log10(len(v))*255)
Ned Batchelder
I was using it as a (actually fairly useless) way of calculating passkey strength. But since the number got too big, I wanted it in scientific notation, and the numbers were too big to be converted.
Skyler
too big.. for python? are you serious? Python "big numbers" can contain over 200000 digits last I checked
SpliFF
not for python, for the C converter. And the passkeys were being generated from files. (music even) That to the power of 255...
Skyler
len = ceil(log10(x)) is incorrect when x is a power of 10 - I think you want floor(log10(x)) + 1 (or just int(log10(x) + 1) in python)
Peter Gibson
@Peter: you must be right: another reason why the original code is probably as good as it will get.
Ned Batchelder
A: 

Are you trying to determine the number of possible strings having the same length as var_text? If so, you have your base and exponent reversed. You want to use 255**len(var_text) instead of len(var_text)**255.

But, I have to ask ... how long do these passkeys get to be, and what are you using them for?

And, why not just use the length of the passkey as an indicator of its length?

Nathan Davis
A: 

Firstly, if your main problem is manipulating huge floating point expressions, use the bigfloat package:

>>> import bigfloat
>>> bigfloat.BigFloat('1e1000')
BigFloat.exact('1.0000000000000001e+1000', precision=53)

As for the details in your question: len(str(num)) is approximately equal to log(num, 10) + 1. This is not significantly shorter, but it's certainly a better way of expressing it in code (for the benefit of anyone who doesn't know that off the top of their head). You can then simplify it with log laws:

  len(str(x**y))
= log(x**y, 10) + 1
= y * log(x, 10) + 1

So maybe you'll find:

"%i" % (log(len(var_text),10)*255 + 1)

... is better? It's not significantly shorter, but it's a much clearer mathematical relationship between input and output.

detly
+5  A: 

TL;DR: y = 2.408 * len(var_text)

Lets assume that your passkey is a string of characters with 256 characters available (0-255). Then just as a 16bit number holds 65536 numbers (2**16) the permutations of a string of equal length would be

n_perms = 256**len(passkey)

If you want the number of (decimal) digits in n_perms, consider the logarithm:

>>> from math import log10
>>> log10(1000)
3.0
>>> log10(9999)
3.9999565683801923
>>> 

So we have length = floor(log10(n_perms)) + 1. In python, int rounds down anyway, so I'd say you want

n_perms = 256**len(var_text)
length = int(log10(n_perms)) + 1

I'd argue that 'shortening' ugly code isn't always the best way - you want it to be clear what you're doing.

Edit: On further consideration I realised that choosing base-10 to find the length of your permutations is really arbitrary anyway - so why not choose base-256!

length = log256(256**len(var_text)
length = len(var_text) # the log and exp cancel!

You are effectively just finding the length of your passkey in a different base...

Edit 2: Stand back, I'm going to attempt Mathematics!

if x = len(var_text), we want y such that
y = log10(256**x)
10**y = 256**x
10**y = (10**log10(256))**x
10**y = (10**(log10(256)x))
y = log10(256) * x

So, how's this for short:

length = log10(256) * len(var_text)     # or about (2.408 * x)
Peter Gibson
+1 for short != readable.
Jon-Eric
Thanks for the explained answer. I've decided to just drop the whole code that used this, as it wasn't really necessary, and didn't really accomplish anything, but I do appreciate the answer.
Skyler