I have a haystack:
source = ''' "El Niño" "Hi there! How was class?"
"Me" "Good..."
"I can't bring myself to admit that it all went in one ear and out the other."
"But the part of the lesson about writing your own résumé was really interesting!"
"Me" "Are you going home now? Wanna walk back with me?"
"El Niño" "Sure!"'''
I have a mask:
out_table = '→☺☻♥♦♣♠•◘○§¶▬↨↑↓←∟↔'
And I have a token --
(single space).
All their elements are strings (class of <str>
).
I need a function that will:
source
)
) with a single character randomly picked from the maskFinally, I need a similar method that will revert the above process, so it will replace each occurrence (every character) of the →☺☻♥♦♣♠•◘○§¶▬↨↑↓←∟↔
list into
(space).
An example (can vary -- randomness) example result is (just a printout):
↔◘↔▬"El→Niño"↓"Hi∟there!↓How↨was↨class?"
↔◘↔▬"Me"↓"Good..."
♥♦♣♠"I↓can't↨bring§myself↓to∟admit↓that↓it↓all↓went↓in↓one§ear↓and↓out§the↓other."
↔◘↔▬"But☻the☻part☻of↓the→lesson∟about↓writing↓own↓résumé§was§really→interesting!"
↔◘↔▬"Me"↓"Are↓you☻going↓home§now?→Wanna↓walk∟back↓with↓me?"
♥♦♣♠"El↓Niño"→"Sure!"
Assumptions:
So, I the most "randomly border" scenario all spaces will be replaced with the same character. Which isn't a problem at all as long as the whole process is reversible back to the original haystack (source
).
Since this is my first Python code, I have browsed a number of Python and non-Python related questions here and in the net and I have come with the following idea:
import random
def swap_charcter(message, character, mask):
the_list = list(message)
for i in random.sample(range(len(the_list)), len(list(mask))):
the_list[i] = random.choice(mask)
return message.join(the_list)
# print(swap_charcter('tested', 'e', '!#'))
print(swap_charcter('tested', 'e','→☺☻♥♦♣♠•◘○§¶▬↨↑↓←∟↔'))
But... I must be doing something wrong, because each time I run this (or many, many other) piece of code with just a space as an argument, I am getting the Sample larger than population or is negative error.
Can someone help here a little bit? Thank you.
EDIT: I have replaced list(character)
→ list(message)
, as suggested in the comments.
A quick example:
import random
mask = '→☺☻♥♦♣♠•◘○§¶▬↨↑↓←∟↔'
original = 'The quick fox jumps over the lazy dog'
pieces = original.split(' ')
filled = [piece+random.choice(mask) for piece in pieces]
result = ''.join(filled)
result = result[0:-1]
print(result)
Result:
The♥quick○fox∟jumps•over↨the∟lazy♠dog
This method takes your string and:
split
),join
),result[0:-1]
)This solution uses the fact that strings are themselves iterables:
from collections.abc import Iterable
isinstance('hello', Iterable)
Result:
True
You don't need to convert strings to lists to pick out individual characters or to get their length; you can do this directly.
Putting that together in a function and letting you specify the character to replace as a bonus, you get:
import random
def swap_characters(string, character, mask):
'''Replace all instances of a character from a string with a random sample from mask
Parameters
----------
string : str
The string to be modified
character : str
The character to be replaced
mask : str
The string of characters from which to sample
Returns
-------
str
The modified string
'''
pieces = string.split(character)
filled = [piece+random.choice(mask) for piece in pieces]
result = ''.join(filled)
return result[0:-1]
mask = '→☺☻♥♦♣♠•◘○§¶▬↨↑↓←∟↔'
example = "Let's take extra spaces. Here's 10: "
x = swap_characters(example, ' ', mask)
print(x)
Result:
Let's←take¶extra☻spaces.♣Here's↨10:↑↓∟◘§☻↓☻↓◘
The reverse is a more common scenario with a variety of options. For example:
x = swap_characters(example, ' ', mask)
print(x)
for char in mask:
x = x.replace(char, ' ')
print(x)
Result:
Let's↓take←extra¶spaces.☺Here's☺10:♠§◘☻☺▬☺→¶←
Let's take extra spaces. Here's 10:
Alternatively using regular expressions:
import re
x = swap_characters(example, ' ', mask)
print(x)
set = '|'.join(mask)
x = re.sub(set, ' ', x)
print(x)
Result:
Let's•take¶extra↔spaces.○Here's↓10:♦↔∟♦◘♥••♣→
Let's take extra spaces. Here's 10: