I'm trying to efficiently add one to the end of a string like this:
tt0000001 --> tt0000002 but I'm not sure how to accomplish this.
A complicated way of doing this is to remove the 2 t's at the beginning, count the number of non-zero digits (let's call that number z), make the string an int, add 1, and then create a string with 2 t's, 6 - z 0's, and then the int, but since I need to use many strings (ex: tt0000001, then tt0000002 then tt0000003, etc) many times, it would be great to have a more efficient way of doing this.
Would anyone know how to do this? A one-liner would be ideal if possible.
Thank you!
What you describe is essentially correct. It's not as difficult as you suggest, though, as creating a 0-padded string from an integer is supported.
As long as you know that the number is 7 digits, you can do something like
>>> x = 'tt0000001'
>>> x = f'tt{int(x.lstrip("t"))+1:07}'
>>> x
'tt0000002'
Even simpler, though, is to keep just an integer variable, and only (re)construct the label as necessary each time you increment the integer.
>>> x = 1
>>> x += 1
>>> f'tt{x:07}'
'tt0000002'
>>> x += 1
>>> f'tt{x:07}'
'tt0000003'
Related
Given a real number between 0 and 1 (for example 0.2836) I want to return only the number without the dot (for example in this case from 0.2836 -> 2836 or 02836). I was trying to use python to do this but I just started and I need some help.
As long as you have a number, the following should do:
>>> number = 0.2836
>>> int(str(number).replace('.', ''))
2836
If a . is not found in the string, str.replace just returns the original string.
With more numbers:
>>> int(str(1).replace('.', ''))
1
>>> int(str(1.2).replace('.', ''))
12
The simplest way to remove an unwanted character from a strip is to call its .replace method with an empty string as the second argument:
x = str(123.45)
x = x.replace('.','')
print(x) # Prints 12345
Note, this would leave any leading zeros (i.e. 0.123 using this method would result in 0123)
If you know there are always, say, 4 numbers after the decimal (and in the case that there are less, you want trailing zeros), you could multiply the number by an appropriate factor first:
x = 123.4567
x *= 10000
x = str(int(x)) # Convert float to integer first, then to string
print(x) # Prints 1234567
There are other options, but this may point you in the right direction.
I have a number and I want to format to a string with zero padding and a specific length . Suppose if the fixed length is 22 , I know I can do in this way
format(variable,"%022d")
but does there exist any way can do by this
length = 22
format(variable,"%0lengthd")
It means I need to use variable in % variable d expression
thanks
You should use str(variable).zfill(length) for this:
>>> str(12345).zfill(8)
'00012345'
>>> str(12345).zfill(10)
'0000012345'
It might seem somewhat unintuitive to have to convert the number to a string before zero-padding it, but (at least in my opinion) this is much cleaner than using multiple formats. After all, why hack together a solution when it's already builtin?
Yes, by using string formatting inside:
length = 22
format(variable,"%0{}d".format(length))
Infact, you could probably do this whole thing with one call of str.format():
length = 22
"{0:{1}}".format(variable, length)
Even classic string interpolation supports this:
>>> variable = 100
>>> length = 22
>>> print "%0*d" % (length,variable)
0000000000000000000100
See more details at this answer: variable length of %s with the % operator in python
I am attempting to take two-digit integers representing day-of-month, split the digits into single digits by taking each character in the single digit and adding them together to form a new number.
e.g. If the value for day was an integer 29, then the program would turn that into strings and split them into '2' and '9'. The program would then turn 2 and 9 into integers and add them together to equal 11. Since this is still a double digit number, the program would loop and 1 and 1 would be added together and the final value that would print would be 2. According to the code below(mostly the last ~5 lines), if I enter day=29, then the final answer I keep getting is 4 which is incorrect. Can someone help me fix this:
Note someone mentioned that I didn't re-enter dayStringSum and I accidentally deleted their post am not sure what that means at all.
dayString = str(int(day))
# Turns value day into int
dayStringA = int(str(dayString[0]))
# If day=29 then this variable represents the 2...
dayStringB = int(str(dayString[1]))
# ...and this represents the 9
dayStringSum = (dayStringA + dayStringA)
while(dayStringSum >=10):
dayStringA = int(str(dayStringSum[0]))
# Since daystringsum is now 11, this code changes the value of daystringA into a new value of 1, likewise for below.
dayStringB = int(str(dayStringSum[1]))
print(dayStringSum)
dayStringSum is an integer, so dayStringSum[n] makes no sense. You'll want to turn it into a string first, and then look at its individual characters.
Also, you do not assign a new value to dayStringSum inside the while loop, so if it is >= 10 upon entering the loop, it will remain so, resulting in an infinite loop. You say that you got a final result of 4, but I fail to see how you would get a final result at all.
Try something like this:
daySum = int(day) # Ensure that day is an int before we start.
while(daySum >= 10):
newString = str(daySum)
dayIntA = int(newString[0])
dayIntB = int(newString[1])
daySum = dayIntA + dayIntB # Will be checked on next iteration.
print(daySum)
I'm guessing the reason you're getting the wrong answer is that you add dayStringA + dayStringA when you meant to add dayStringA + dayStringB, i.e. it's just a typo.
The other thing you need to fix is that in the loop, you don't change dayStringSum. This hasn't been a problem so far because dayStringSum is less than 10 in your example, so the loop never executes in the first place, but once you fix that typo, you're going to get an infinite loop and the program will never stop.
Here's what I mean: suppose your day is 29. When you get to this line:
while(dayStringSum >=10):
then dayStringSum will be 11. So then you set dayStringA to 1,
dayStringA= int(str(dayStringSum[0]))
and also dayStringB to 1.
dayStringB= int(str(dayStringSum[1]))
Then that's the end of the loop. So Python goes back to this line:
while(dayStringSum >=10):
What's dayStringSum? Why, it's still 11! You never changed it. So Python will keep looping, going through the same logic over and over again.
Now beyond that, there are a bunch of things that make this code way more complicated than it needs to be. I'm not going to go through them (Code Review would be the place for that), but in general, you don't need to convert things to ints if they are already ints, and likewise you don't need to use str on something that is already a string.
try sum(map(int,"265"))
that maps them to ints and sums them ...
>>> sum(map(int,"254"))
11
or
>>> sum(map(int,str(29)))
11
oh well since its homework I cant really just give away the answer ....
but
its similar to
sum1=0
for integer in [1,2,3]: sum1 += integer
print sum1
Easier way is to take modulus 9 of the number
>>> print(29%9)
2
day = 29
while day >= 10:
day = sum(int(digit) for digit in str(day))
(Also, whenever you're doing major manipulations of the individual digits of an integer, decimal.Decimal is useful, in particular its method
Decimal(29).as_tuple().digits which gives you (2, 9)).
There's probably someone else who asked a similar question, but I didn't take much time to search for this, so just point me to it if someone's already answered this.
I'm trying to take an integer (or long) and turn it into a string, in a very specific way.
The goal is essentially to split the integer into 8-bit segments, then take each of those segments and get the corresponding ASCII character for that chunk, then glue the chunks together.
This is easy to implement, but I'm not sure I'm going about it in the most efficient way.
>>> def stringify(integer):
output = ""
part = integer & 255
while integer != 0:
output += chr(part)
integer = integer >> 8
return output
>>> stringify(10)
'\n'
>>> stringify(10 << 8 | 10)
'\n\n'
>>> stringify(32)
' '
Is there a more efficient way to do this?
Is this built into Python?
EDIT:
Also, as this will be run sequentially in a tight loop, is there some way to streamline it for such use?
>>> for n in xrange(1000): ## EXAMPLE!
print stringify(n)
...
struct can easily do this for integers up to 64 bits in size. Any larger will require you to carve the number up first.
>>> struct.pack('>Q', 12345678901234567890)
'\xabT\xa9\x8c\xeb\x1f\n\xd2'
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))))
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)
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)
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?
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.