Reverse engineering


#1

In the List Slicing exercise you, removed all the X’s from the string using [::-2] to decode the message.

garbled = "!XeXgXaXsXsXeXmX XtXeXrXcXeXsX XeXhXtX XmXaX XI"
message = garbled[::-2]

I am trying to reverse engineer this. I start with a variable containing the string in the correct oder, then another variable reversing the string:

other = "I am the secret message!"
backwards = other[::-1]

This is where I get confused. While I realize the long and inefficient way to do this is,

print backwards[23] + "X"+ backwards[22] + "X" + backwards[21] + "X"

I’m sure there is a more efficient way. Do I turn the backwards into a list, append “X” N times between every other index, then convert it back to a string? If this is the case, how do you do that?

Thanks!


#2

have you considered using a loop to append to a list, and then join the list into a string?


#3

I have. Am i correct that I need to insert the string into a list first? Also, am i able to loop through and and append using [::2]?


#4

Insert the string into a list? Like this?
'hello' -> ['hello']
or this? (but that’s not what you said)
['h', 'e', 'l', 'l', 'o']
And, what difference would this make to the operation that you’re planning to do? Which operation is that exactly anyway?

Append means to add at the end. You can assign to slices, yes, but you’d be overwriting those elements and would therefore need to first make a list that is of the new size and space out the elements, you could just as well space them out with 'X'
There doesn’t exist space between elements in a list. You can’t drop values in between existing values. You need a new list, or a different data structure (if you can imagine it and describe it well enough, then you can also write that code - to write code is to describe what you want to happen)


str’s join method already does exactly what you’re asking for.


If you think something seems likely to exist, then it’s probably fairly simple to google it. But if you’re guessing rather wildly, or wishing, then the approach you should be taking is probably instead to learn the language features and then using those to describe what you want to do.

In this case I think the reasonable train of thought is that, since each letter has to be processed, a loop is needed. And as each character is iterated over, you would keep that character somewhere, and add an X after it. A list supports this well, and also easily supports removing the last X at the end. Once the iteration is done, create a string from those characters, something that str.join does. (and if one isn’t aware of str.join then googling will make it easy to figure out how to convert a list of characters into a string)


#5

You might generalize a bit and create a function named intersperse which takes a value to put between each element and an iterable.

Which you could then use as:

>>> intersperse('X', 'abc')
['a', 'X', 'b', 'X', 'c']
>>> ''.join(intersperse('X', 'abc'))
'aXbXc'

Again, a bit silly for strings since str.join already does that, and you have to use str.join to convert the list to string anyway.

[::2] to specify where the sequence should be put does make for a very neat solution. One just has to create a list of the right size first:

def intersperse(delimiter, sequence):
    result = [delimiter] * (len(sequence) * 2 - 1)
    result[::2] = sequence
    return result

(I’m initially filling the list with the delimiter, and overwriting every other location with the sequence)


#6

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.