Reputation: 15804
Using Python 2.7, imagine I have two variables:
encoded_username = 'bender_in_soup_1234'
code = '000204071012'
The string in code
actually specifies the position of upper case characters in encoded_username
. I.e. 00
implies the first character is upper case. 02
implies the third character is upper case. 04
implies the fifth character is upper case. And so on. It can possibly go to 99
(usernames
are not longer than 100 characters).
The fully decoded username is:
decoded_username = 'BeNdEr_In_SoUp_1234'
What's the most efficient way (in Python 2.7) to decode the encoded_username
using the code
provided?
I'm trying:
upper_case_positions = [code[i:i+2] for i in range(0,len(code),2)]
for position in upper_case_positions:
encoded_username[position] = encoded_username[int(position)].upper()
return encoded_uname
But this simply gives me 'str' object does not support item assignment
.
Moreover, I'm to parse through multiple usernames while decoding them, i.e. the code above is going to be nested inside a for
loop. Having for
loops within for
loops makes me feel there could have been a more efficient solution. What do you folks suggest? I'm highly intrigued.
Upvotes: 0
Views: 120
Reputation: 333
String are immutable Why are Python strings immutable? Best practices for using them
You can use regexp to split in chunk https://stackoverflow.com/a/25430739/123808
You can transform in list ( which is mutable) and rebuild your string once you mutation is done
import re
encoded_username = 'bender_in_soup_1234'
code = '000204071012'
encoded_username_list = list ( encoded_username )
upper_case_positions = [int(pos) for pos in re.findall('.{2}', code)]
for position in upper_case_positions:
encoded_username_list[position] = encoded_username[position].upper()
print "".join(encoded_username_list)
BeNdEr_In_SoUp_1234
Upvotes: 1
Reputation: 42678
Here you have an aproach using ord
and chr
:
encoded_username = 'bender_in_soup_1234'
code = '000204071012'
def upperText(s, pos):
gap = ord("a") - ord("A")
upper_case_positions = [int(pos[i:i + 2]) for i in xrange(0, len(pos), 2)]
txt = map(ord, s)
for i in upper_case_positions:
txt[i] -= gap
return "".join(map(chr, txt))
print upperText(encoded_username, code)
BeNdEr_In_SoUp_1234
Upvotes: 1
Reputation: 10359
How about the following:
encoded_username = 'bender_in_soup_1234'
code = '000204071012'
upper_case_positions = [int(code[i:i+2]) for i in range(0, len(code), 2)]
decoded_username = ''.join(let.upper() if pos in upper_case_positions else let
for pos, let in enumerate(encoded_username))
print decoded_username
Firstly, you need to wrap your upper_case_positions
as integers to ensure they are usable as positions. We enumerate the word to return each character and its relevant position, and change the case where required. Joining using an empty string gives us our output username. This prints, as expected, 'BeNdEr_In_SoUp_1234'
Upvotes: 2