Samuel Sehnert
Samuel Sehnert

Reputation: 5

How to replace multiple occurrences of a character with a string with a random ASCII character?

I am trying to create a program that replaces the spaces in between inputted words with random ASCII punctuation.

I have tried using the string and random module to the best of my ability, but have had no luck so far.

    def basewords():
        print("Enter base words here:")
        q = str(input("TIP: Enter your desired words seperated by spaces only.\n> "))
        lst = [string.punctuation, string.digits]
        x = ''.join(random.choice(lst)(c) for c in q)
        q = q.replace(" ", x)
        print(q)

I want the spaces in between words (e.g. Hello World Dog House) with randomized ASCII punctuation characters so that it could theoretically end up like "Hello!World^Dog,House". However, currently, I am getting a TypeError. Any help is much appreciated.

Upvotes: 0

Views: 83

Answers (3)

Doncho Gunchev
Doncho Gunchev

Reputation: 2239

Just join the two lists of special characters, don't put them in a list for random.choice. One liner example:

''.join(i if i != ' ' else random.choice(string.punctuation + string.digits)
    for i in q)

You can of course...

result = ''
for i in q:
    if i != ' ':
        result += i
    else:
        result += random.choice(string.punctuation + string.digits)
q = result

The second example is the verbose version of the one-liner example above. To understand it you can split it in peaces.

q = ''.join( LIST_COMPREHANSION )

This joins with empty strings the LIST_COMPREHANSION inside. You can check https://www.pythonforbeginners.com/basics/list-comprehensions-in-python for details. It consists of:

EXPRESSION for i in q

The expression itself isa ternary operator - https://book.pythontips.com/en/latest/ternary_operators.html:

i if i != ' ' else random.choice(string.punctuation + string.digits)

However using str.replace will not work, the second argument is constant and you can not use random character generator there.

Upvotes: 2

muditrustagii
muditrustagii

Reputation: 793

Dont you think generating random numbers between the ascii value of the first punctuation (33) and the last punctuation (47), will be more easier to implement. And then u can just use it in you code as usual, by using its ascii value to find the corresponding character.

You can more about the ascii table here:

<-Hope it simplifies your solution.

<-UpVote If HelpFul

Upvotes: 0

salparadise
salparadise

Reputation: 5805

The reason for your TypeError is because of this line:

x = ''.join(random.choice(lst)(c) for c in q)

random.choice(iterable) returns one random item in iterable, since your iterable is composed of strings, it returns a string. When doing this (c) you are trying to call a string like a function, this raises a TypeError because a string is not callable.

How about something like this instead:

def basewords():
    print("Enter base words here:")
    q = str(input("TIP: Enter your desired words seperated by spaces only.\n> "))
    specialchars = string.punctuation + string.digits
    def rand():
        return random.choice(specialchars)
    print(''.join(x.replace(' ', rand()) for x in q))

Demo:

In [41]: basewords()
Enter base words here:
TIP: Enter your desired words seperated by spaces only.
> Hello World Dog House
Hello;World>Dog3House

Upvotes: 1

Related Questions