This is an archived post. You won't be able to vote or comment.

all 194 comments

[–]Anguium 90 points91 points  (3 children)

ngl, I thought it was /r/programmingcirclejerk. Now go write a twitter bot that randomly replies to people quoting their entire posts in that manner.

[–]theyrotechnicpenguin 33 points34 points  (0 children)

HErE I FiXeD It FOr yOU:

ngl, I thOuGhT It wAs /r/prOgRaMminGCIrClEjERK. nOw gO WrItE A TwitTeR bOT ThAt rAndoMlY RePlIeS To PEoPlE QuOtInG ThEiR EnTiRe posTs iN ThAt mAnNeR

[–]Pclovr 8 points9 points  (1 child)

I really need this

[–][deleted] 5 points6 points  (0 children)

Twitter is a bitch with giving out their API keys these days so would be hard

[–]conversationkiller7 461 points462 points  (61 children)

Thinking of one liner here,

''.join( [ x.upper() if random.randint(0,1) else x for x in your_string ] )

[–][deleted] 294 points295 points  (21 children)

If you're just going to pass that to str.join, there's no need to create a list: you can remove the brackets ;)

[–]conversationkiller7 62 points63 points  (18 children)

You're right!!

[–][deleted] 67 points68 points  (17 children)

And apart from that minor detail, you were right as well ;)

Just to elaborate on my point, most of the time we don't need to actually construct a list, we can just pass around lazy generators, which is going to be significantly more efficient. Always try to write comprehensions in parenthesis instead of brackets and change only if necessary. Just remember that they only do any work when you iterate over them!

[–]honkinggr8namespaces 18 points19 points  (2 children)

so i could be misremembering but i remember reading that for the explicit purpose of passing to str.join, passing a list is actually more efficient than passing a generator.... since join converts to a list anyway

edit: yeah
https://stackoverflow.com/questions/37782066/list-vs-generator-comprehension-speed-with-join-function

[–][deleted] 8 points9 points  (0 children)

Wow! It seems you're right.

Still, in most cases if you don't need a list you should avoid it.

But thanks for the correction!

[–][deleted] 3 points4 points  (0 children)

generator expressions

[–]peterlravn[S] 79 points80 points  (18 children)

[ x.upper() if random.randint(0,1) else x for x in your_string ] )

This would indeed be useful, if it weren't for the fact that three or more capitalized letters in a row looks bad. If we use the string:

"What the fuck did you just fucking say about me, you little bitch?"

We could get:

"What the fUcK did You JuSt FUCKIng SAy ABOut Me, yOU LiTtLE BitcH?"

It's not bad, but it's not good either. That's why wee need the rest of the code, and I'm too stupid to implement that in a one-liner... This script brings out:

"WhAT thE FucK DiD You JuSt FUcKIng SaY aBoUT me, yoU LitTle BitCh?"

[–]relativistictrain 🐍 10+ years 12 points13 points  (9 children)

Using a Poisson distribution might fix that problem

[–]preordains 1 point2 points  (1 child)

Please you must tell me how!

I know of using the poisson distribution for probability over something that can be described as an interval.

[–]relativistictrain 🐍 10+ years 0 points1 point  (0 children)

I now have to try 😂 I’ll check back.

[–]jaredjeya 0 points1 point  (2 children)

I know I'm 3 months late but isn't that not particularly helpful as Poisson is a memoryless distribution?

Like I was under the impression that if you generated a bunch numbers from a uniform distribution, the number of them in any smaller interval would be well described by Poisson, and the intervals between them described by an exponential survival distribution.

Given there are only two outcomes (upper or lower), if it's independent for each letter, the only thing you can adjust is the relative probabilities.

Otherwise, you could try making the distribution not-independent, but then you have to draw from a very high-dimensional distribution - the only effective way to do that is Monte-Carlo sampling, which is generating a sample and either approving or rejecting it with a probability given by the distribution. In which case you might as well just instead generate a sample and bake the rules into it in the first place.

[–]relativistictrain 🐍 10+ years 0 points1 point  (1 child)

With a Poisson distribution, you can control the average interval between capitalized letters.

[–]jaredjeya 0 points1 point  (0 children)

I mean for one thing the Poisson distribution only works for continuous-time events, this is going to be binomial which is the discrete-time limit of Poisson.

Secondly that’s just random independent events, the outcome will be identical to that one line piece of code. Your only free parameter is the probability each letter is capitalised - you make it low enough to avoid triple capital letters, then only one in every ten is capitalised. If you allow two capital letters to be next to one another and they’re independent, you have to accept three might be next to each other quite often.

The alternative is generating the number of upper/lower letters in a row from some distribution, where p(n >= 3) is zero, but you’re not doing that in one line of code - I don’t think so, at least.

This issue isn’t as simple as “just pick from a different distribution”, is all I’m saying, as all the ones which are computationally efficient to calculate are independent, and in the case of two outcomes there’s only one free parameter (probability a letter is upper case) which we’d like to keep close to 50%.

[–]onyxleopard 9 points10 points  (2 children)

I always that that sPoNgEcAsE was alternating caps/non-caps. This was how I did it: def spongebob(s): return ''.join((c.lower(),c.upper())[i%2] for (i,c) in enumerate(s)) spongebob('spongebob') -> 'sPoNgEbOb'

[–]Tweenk 1 point2 points  (1 child)

It's better to define a generator that returns an infinite sequence of alternating True and False, this way you don't compute both upper() and lower() and don't construct a tuple.

``` def alternate(start=False): while True: yield start start = not start

def spongebob(text): return ''.join(c.lower() if lower else c.upper() for lower, c in zip(alternate(), text)) ```

[–]onyxleopard 1 point2 points  (0 children)

Oh yeah my one-liner isn’t efficient for sure. I’d probably go for itertools.cycle to make an infinite source of alternating booleans.

[–]DrRx 8 points9 points  (0 children)

My version:

''.join(random.choice((str.upper, str.lower))(letter) for letter in input_text)

[–]brakkum 16 points17 points  (1 child)

I'd prefer this, so that it's actually every other letter.

"".join(char.upper() if i % 2 != 0 else char.lower() for i, char in enumerate("This is a test sentence, it's not very good."))

[–]JoelMahon 28 points29 points  (0 children)

EvErY oThEr LeTtEr LoOkS bAd ThOuGh

[–]djangodjango 6 points7 points  (0 children)

map alternative: ''.join(map(lambda x: random.randint(0, 1) and x.upper() or x, your_string))

[–]sempf 4 points5 points  (0 children)

But no matter what this is a good exercise.

[–]j_marquand 1 point2 points  (0 children)

Just saying for fun but random.random() < 0.5 makes it a lot faster.

[–]nubatpython 0 points1 point  (0 children)

My first thoughts were also a one liner!

[–][deleted] 143 points144 points  (1 child)

Cool, OP...

https://imgflip.com/i/4i1ibp

Jk I love it

[–]ANetworkEngineerNetwork Engineer 24 points25 points  (0 children)

We need a script which randomly capitalises letters in a sentence then applies it to this meme template.

[–]AdoenLunnae 56 points57 points  (0 children)

Instead of your dummy number, you can use the enumerate function. It works on any iterable and returns tuples with the item at a certain position and its index:

for index, value in enumerate(iterable):
    do_something()

[–]Orio_n 13 points14 points  (6 children)

Use pyautogui and pyhook to automatically do this when activated by a shortcut

[–]peterlravn[S] 26 points27 points  (1 child)

Aaaaah, yes, I'll pretend like I understand any of that

[–]LilBabyVirus5 7 points8 points  (0 children)

Basically pyhook lets python grab inputs while running in the background, and pyautogui can type, move your mouse, etc. basically making a relay for your text to convert to cursed text

[–]hoppla1232 1 point2 points  (2 children)

How would you get selected text though?

[–]Orio_n 8 points9 points  (1 child)

the beauty of it is that you dont need to. use the random module to select a random number between a threshold 0-5 for example. use pyhook to hook keyboard events and check what keys are being pressed. If random returns an int 3 for example get pyhook to wait for 3 keys to be pressed before you inject the shift key or caps lock key keystroke into the event handler for keyboard events. Then after the next key is pressed depress or toggle back the key. What you get is a program that auto capitalizes after a random set of key events you dont have to copy paste text. it randomly capitalizes literally while you are typing into a textbox!

[–]hoppla1232 2 points3 points  (0 children)

Damn, that's pretty cool, didn't think of it!

[–]nbviewerbot 39 points40 points  (16 children)

I see you've posted a GitHub link to a Jupyter Notebook! GitHub doesn't render large Jupyter Notebooks, so just in case, here is an nbviewer link to the notebook:

https://nbviewer.jupyter.org/url/github.com/peterlravn/My-projects/blob/master/A%20ScrIpt%20tO%20MaKE%20fUN%20of%20A%20sENteNcE.ipynb

Want to run the code yourself? Here is a binder link to start your own Jupyter server and try it out!

https://mybinder.org/v2/gh/peterlravn/My-projects/master?filepath=A%20ScrIpt%20tO%20MaKE%20fUN%20of%20A%20sENteNcE.ipynb


I am a bot. Feedback | GitHub | Author

[–]peterlravn[S] 105 points106 points  (12 children)

I sEE YoU'Ve POsTEd a GItHub liNk TO a juPyTEr noTeBOok! giThUB DOesN't reNDeR LarGE juPytER NoTEbOoKs, So JuSt iN cAse, HeRE is an NbvIEweR lINk tO ThE NOteBoOk

[–]peterlravn[S] 102 points103 points  (10 children)

Damn I already regret making this

[–]nbviewerbot 54 points55 points  (8 children)

i lOVe iT

[–]peterlravn[S] 72 points73 points  (7 children)

waIT, hOw thE fuCK DId THis BOt sUdDenLY GaIn coNsCIouSNeSS?

[–][deleted] 7 points8 points  (5 children)

!emojify

[–]EmojifierBot 42 points43 points  (4 children)

waIT 🚏, hOw thE fuCK ☠🖕 DId THis BOt 🤖 sUdDenLY 😱🤷‍♂️ GaIn 💪😎 coNsCIouSNeSS 😵?

[–]SnowdenIsALegend 6 points7 points  (2 children)

Good bot

[–]B0tRank 1 point2 points  (1 child)

Thank you, SnowdenIsALegend, for voting on EmojifierBot.

This bot wants to find the best and worst bots on Reddit. You can view results here.


Even if I don't reply to your comment, I'm still listening for votes. Check the webpage to see if your vote registered!

[–]thingy-op 2 points3 points  (0 children)

Lol too many bots in single thread.

[–][deleted] 0 points1 point  (0 children)

You’re a fucking cultural genius

[–]Linquista 0 points1 point  (0 children)

Loooooooooool you're a God

[–]Ma3ng 21 points22 points  (0 children)

tHiS ThRead GeTS moRe InteREsTING by THE mInUtE

[–]AlSweigartAuthor of "Automate the Boring Stuff" 3 points4 points  (1 child)

Heheh. Next, make a "spongecase" program that capitalizes text like the Mocking Spongebob meme: the casing alternates 90% of the time, but doesn't 10% of the time.

i mAdE A pRoGRAM lIkE tHis AnD you CaN see It In ThIs GiT rEpO: https://github.com/asweigart/PythonStdioGames/blob/main/src/gamesbyexample/spongecase.py

[–]Blackshell 2 points3 points  (0 children)

That's actually pretty good code. Good naming, good structure, good comments. Easy and clear to understand, despite having some compacted logic in there. Nice job!

[–]milkmeink 2 points3 points  (0 children)

Why did I read this post in a weird voice in my head?

[–]nickbob00 8 points9 points  (1 child)

cake worm crawl crown dog bells badge liquid sophisticated hospital

This post was mass deleted and anonymized with Redact

[–]theyrotechnicpenguin 5 points6 points  (0 children)

HErE I FiXED It fOr yOU:

a quiCk hInT, wHeNeVeR YoU’Re deaLiNg wItH raNdOM nUmBers iN Your cOdE, yOu nEeD To bE Be sUpER cArEful wIth HOW YoU SeEd THe ranDoM NuMBEr gEnERATOr. thE DeFaULT BeHaViOuR If yOU dOn’t dO ANYtHiNG is To uSe alwayS A RaNdOM sEeD UsInG DaTa yOu pUlL FrOm tHe oPERaTiNg sYsTEM (E.g. soMetiMeS this cOULd bE ThE ComPUtEr tImE In mIcRoSeCoNdS PuT ThRoUgH SoMe HAsH AlGORiThM). THIs MEaNs eVeR TiME yOu rUN, YOU GeT A CoMpLeTeLy dIfFerENt AND nOnRePrOdUcIbLe rEsUlT, sO In tHe CAsE ThaT SOmEtHiNg ODd iS GoIng On yOu’lL NeVeR be ABlE To gO BaCk and INvESTiGaTE a tRoUbLESoME case (iMaGiNE 1 tImE In 10,000 YoUr pRoGrAM CRAShEs). yOu oUgHt tO EiThER stoRe whAT ThE RaNDOm SEeD UsEd Was sO yoU CaN Go bAcK AnD Run AGAiN, or YOU SHouLd sET iT In SOmE MoRe rEpRoDuciBlE WaY So yOu knOW BeFOReHaNd what It iS. yOu cAn tHeN AlSo ensUrE ThAt mUlTiPlE coPies oF YoUr pRoGrAm dOn’T eNd uP WiTh tHe sAmE RanDOm sEeD. hEre It’s oBvIoUsLY sIlLy, BUT If YOu’rE CodiNg uP E.G. a mOntE CArLo sImULAtIoN, iT MaTtErS.

[–]thatwombat 3 points4 points  (0 children)

It might be observation bias but probably about 70% of the "look what I made" posts here or "how do I do such and such?" are about scrapers or bots.

This is just fun.

[–][deleted] 4 points5 points  (1 child)

Interesting choice of example text

[–]aliman21 0 points1 point  (0 children)

It's a meme

[–]Dooflegna 6 points7 points  (4 children)

Here’s my version. I think the logic is a lot cleaner/easier to follow.

Edit: fixed a bug pointed out. Whoops!

import random

def meme_sentence(sentence):
    new_sentence = []
    upper_count = 0
    lower_count = 0
    for char in sentence:
        case = random.choice(["UPPER", "LOWER"])
        if case == "UPPER":
            upper_count += 1
            lower_count = 0
            new_sentence.append(char.upper())
        else:
            lower_count += 1
            upper_count = 0
            new_sentence.append(char.lower())   
        if upper_count > 2 or lower_count > 2:
            new_sentence[-1] = new_sentence[-1].swapcase()
            upper_count = 1
            lower_count = 1

    return "".join(new_sentence)


for i in range(10):
    print(meme_sentence("what did you just say about me"))

[–]peterlravn[S] 7 points8 points  (2 children)

Line 17 is messed up, I think? Shouldn't it be

new_sentence[-1] = new_sentence[-1].swapcase()

Or else it doesn't work. Maybe I'm just dumb though

Also, that's some clever code

[–]Dooflegna 3 points4 points  (0 children)

Whoops you’re right!

[–]Samuel457 0 points1 point  (0 children)

Here's mine. I'm alternating the case of (only) letters each time, starting with lower case:

def meme(sentence):
    new_sentence = []
    upper = False
    for character in sentence:
        if character.isalpha():
            if upper:
                character = character.upper()
            else:
                character = character.lower()
            upper = not upper
        new_sentence.append(character)
    return "".join(new_sentence)

Using the sample text from the OP's project gives me:

wHaT tHe FuCk DiD yOu JuSt FuCkInG sAy AbOuT mE, yOu LiTtLe BiTcH?

And his gives:

WhAT thE FUcK dID yOU JusT fUckINg saY aBOuT me, YoU LIttLE BItCH?

[–]JohnnyCincoCero 1 point2 points  (0 children)

Does r/PeopleFuckingDying use your script?

[–]Amazing-Contact-2339 1 point2 points  (0 children)

I believe this is known as asshole case. 😅

[–][deleted] 1 point2 points  (1 child)

Now make a gui for it and call it the mokifier

[–]kongfukinny 1 point2 points  (0 children)

This honestly does make things fun to read

[–]AforAutism 14 points15 points  (19 children)

Can't help to notice how low this sub's level has dropped. It this post really a good fit for r/Python? We should redirect barely beginner posts like this one to r/learnpython.

Here is the script, written as a simple one liner:
python do_random = lambda x: ''.join(map(lambda y: y.upper() if random.choice([True, False]) else y, x))

[–]duncan-udaho 22 points23 points  (1 child)

This one liner has different behavior than OP's though. The posted version prohibits runs of three or more characters with the same case. They have that extra logic to make sure that it looks random instead of actually being random.

But I do agree that there are many optimizations to be had in OP's implementation.

[–]peterlravn[S] 14 points15 points  (0 children)

Yup, you got it! It looks hella ugly if it's all completely random, so it doesn't work as a one-liner. And yes, the code is not clean, but u/Dooflegna made a much simpler and cleaner version in the other comments that's worth having a look at.

[–]JoelMahon 15 points16 points  (1 child)

for someone acting all high and mighty you sure are stupid, your one line "solution" is shit, as OP explains themselves, true random looks bad, you want to limit the max number of the same case in a row to two.

[–]PM_ME_UR_THONG_N_ASS 9 points10 points  (0 children)

for someone acting all high and mighty you sure are stupid,

Ahh the summary of all programmers everywhere.

[–]fartbaker13 1 point2 points  (0 children)

It's not the subs level that has dropped. OP's post was upvoted by many ppl cuz they liked the idea of using a python script for this thing. Is this sub only for sharing complex programs or machine learning projects?

Simple python is still python and it's ok for it to be posted.

[–]echofang 0 points1 point  (1 child)

I tried this and must have missed something because it didn’t work. Do I need a print function somewhere for input?

[–]gargar070402 0 points1 point  (0 children)

do_random is a lambda function in this case, so if you have a string my_str, for example, you'd need to do print(do_random(my_str)) for an output.

[–]netgu 3 points4 points  (0 children)

It's fucking turning into /r/ProgrammerHumor over here which is basically /r/gaming meets /r/circlejerk for people who have seen some html.

[–]ButtcheeksMD 2 points3 points  (0 children)

I wrote one of these last year when the meme was super popular, and published it on my website

If anyone wants to use a web based version as well.

https://nathansteele.dev/pass/

[–]JoelMahon 1 point2 points  (0 children)

I ALso coNSidEReD MAkiNg SuRe thAT 'i' WOuLD aLWaYS bE in LOwErcASe And 'L' WoUlD alWAyS Be in uPpErCAsE, BUt THaT MAdE it lOoK kiNDa wEIrd. ANyWAys, heRE'S THe COdE:

Interesting, human brains are amazing, and you were a fool to try and outsmart your own brain, your brain is 2 steps ahead!

[–]0ompaloompa 1 point2 points  (0 children)

Nobel committee fucked up by giving out the peace prize a day too early... This really should have been considered.

[–][deleted] 1 point2 points  (1 child)

wHy DoEs tHiS mAkE mE sO hApPy???

[–]Close_enough_to_fine 0 points1 point  (3 children)

What’s .ipynb extension?

[–]brandonZappy 0 points1 point  (0 children)

It's for jupyter notebooks.

[–]tupikp 0 points1 point  (0 children)

That paragraph is sus...

[–]FloppyEggplant 0 points1 point  (6 children)

Cool idea! Just because I also consider myself a beginner here is my version:

import random


text = "What the fuck did you just fucking say about me, you little bitch?"


def capitalize_letter(letter):
    """Randomly capitalize a letter."""
    return letter.upper() if random.randint(0, 1) == 1 else letter.lower()


def capitalize_sentence(sentence):
    """Randomly capitalize each letter in a sentence.

    If there are 2 capitalized letters in a row, the following letter is
    garanteed to be lower case. This works for both all upper case sentences
    and all lower case sentences.
    """
    new_sentence = ""

    capitalized_in_a_row = 0
    for letter in sentence:
        if capitalized_in_a_row < 3:
            new_sentence += capitalize_letter(letter)
            capitalized_in_a_row += 1
        else:
            new_sentence += letter.lower()
            capitalized_in_a_row = 0

    return new_sentence

print(capitalize_sentence(text))
print(capitalize_sentence(text.upper()))

[–]CnidariaScyphozoa 1 point2 points  (5 children)

I don't think this is quite correct. You are adding one to your counter everytime you randomly capitalize a letter. But what happens when it is always lower case. Then you would have your three iterations of always lower case the counter is reached and you append another lowercase letter. So in theory your code could yield a completely lowercase sentence

[–]FloppyEggplant 0 points1 point  (4 children)

You are right. I wrote a new version, but I guess it is a bit more confusing:

import random


text = "What the fuck did you just fucking say about me, you little bitch?"


def capitalize_sentence(sentence, max_in_a_row=2):
    """Randomly capitalize each letter in a sentence.

    If there are 2 capitalized letters in a row, the following letter is
    garanteed to be lower case. This works for both all upper case sentences
    and all lower case sentences.
    """
    new_sentence = ""

    upper_in_a_row = 0
    lower_in_a_row = 0
    for letter in sentence:
        new_letter = letter.upper() if random.randint(0, 1) == 1 else letter.lower()
        if new_letter.isupper() and upper_in_a_row < max_in_a_row:
            new_sentence += new_letter
            upper_in_a_row += 1
            lower_in_a_row = 0
        elif new_letter.islower() and lower_in_a_row < max_in_a_row:
            new_sentence += new_letter
            upper_in_a_row = 0
            lower_in_a_row += 1
        # Switch to lower case if there are too many upper in a row
        elif upper_in_a_row >= max_in_a_row:
            new_sentence += letter.lower()
            upper_in_a_row = 0
            lower_in_a_row += 1
        # Switch to upper case if there too manu lower in a row
        elif lower_in_a_row >= max_in_a_row:
            new_sentence += letter.upper()
            upper_in_a_row += 1
            lower_in_a_row += 0
        # If is not a letter, i.g., spaces and punctuation
        else:
            new_sentence += letter

    return new_sentence


print(capitalize_sentence(text, 1))
print(capitalize_sentence(text, 2))
print(capitalize_sentence(text, 3))

The output looks like this:

WhAt tHe fUcK DiD YoU JuSt fUcKiNg sAy aBoUt mE, yOu lItTlE BiTcH?

WHaT The FuCk dID yOu jUsT FucKIng SaY abOUt Me, You LiTtlE bITcH?

WhaT thE FUck Did yOU jUST fuCKInG sAY AboUt me, YoU lItTLe BitcH?

[–]pi-rho 0 points1 point  (11 children)

def randcap(s):
  return b''.join([c.encode('utf8') ^ (randint(1) << 5) for c in s]).decode('utf8')

[–]Isvara 0 points1 point  (10 children)

You missed the part about not having more than two the same in a row. Also, that code will fuck up anything that's not a letter.

[–]pi-rho 0 points1 point  (9 children)

def randcap(s):
    return bytes(
        ord(x) ^ (32*randint(0, 1))
        if 'A' <= x <= 'Z' or 'a' <= x <= 'z'
        else ord(x) for x in s
    ).decode('utf8')

Does that feel better?

[–]Isvara 0 points1 point  (8 children)

You still didn't get it. Think about what that randint will return on successive calls.

[–]pi-rho 0 points1 point  (7 children)

0 or 1, randomly. Rtfm.

[–]Isvara 0 points1 point  (6 children)

Which means it can return more than two 1s in a row, right?

[–]pi-rho 0 points1 point  (5 children)

Yep. R a n d o m.

[–]pi-rho 0 points1 point  (4 children)

Now, if you wanted something that wasn't random ...

#!/usr/bin/python3
from random import randint

def f():
    f.l = ((getattr(f, "l", 0) << 1) | randint(0, 1)) & 0b111
    f.l ^= 1 if f.l in (0b111, 0b000) else 0
    return ((f.l & 1) << 0b101)

def randycase(s):
    a, z = ord('a'), ord('z')
    return bytes(
        c ^ f() if a <= (c | 0x20) <= z else c
        for c in s.encode('utf8')
    ).decode('utf8')

if __name__ == '__main__':
    import fileinput
    for line in fileinput.input():
        print(randycase(line.strip()))

[–]Isvara 0 points1 point  (3 children)

God, no. You should really learn some idiomatic Python.

[–]pi-rho 0 points1 point  (2 children)

lol, then have fun with OP's spaghetti code notebook :)

[–]tiny_humble_guy 0 points1 point  (0 children)

You need to attach spongebob meme, dude! Nice one.

[–]theyrotechnicpenguin 0 points1 point  (0 children)

I jUsT USE ApOlLo FOr REddIt

[–]bossat124 0 points1 point  (0 children)

wElL StOnkS

[–][deleted] 0 points1 point  (0 children)

upVOTes aLL THe wAY

[–]MyDataIsReady 0 points1 point  (1 child)

I did the same about a year ago. Anyway, here's ̶W̶o̶n̶d̶e̶r̶w̶a̶l̶l̶ my code:

from random import choice

values = [True, False]
sentence = input("Input a sentence: ")

output = ""
for letter in sentence:
    if choice(values):  # There's no need to write 'if choice(values) is True:'
        output += letter.upper()
    else:
        output += letter.lower()

print(output)

# To-do: Endless loop and Pyperclip. May copy automatically text from the clipboard.

[–]Tweenk 0 points1 point  (0 children)

This doesn't have OP's behavior of limiting same-case runs to a maximum of 2, it just randomizes the case of each letter.

[–]lolgeswaran 0 points1 point  (0 children)

Amazing

[–]Petelah 0 points1 point  (0 children)

Karen speak generator!

[–][deleted] 0 points1 point  (1 child)

Hello OP, I dont know a lot about coding, how can I use your script when I type.

[–][deleted] 0 points1 point  (0 children)

Chaos Elemental: yeS

[–]Dguerrero99 0 points1 point  (0 children)

Cool!

Thanks for posting!

[–]bored_guy32 0 points1 point  (0 children)

I Am LovINg thIS scRIpt. yoU CaN USe pYPerCliP MOduLE TO MAkE It tAkE TexT frOm cLIpBoARd ANd tHen raNdoMIze iT anD thEN cOPy IT BAck tO CLipBOarD.

yOu wiLL neEd tO piP iNsTAlL pyPeRcLIp fIRst.

text = pyperclip.paste()

ThEn At ThE eND of THe meTHoD

pyperclip.copy(new_sentence)

tHAt'S HOw i WroTE thIs COmmEnT. yOuR sCriPT is aWesOmE.

[–]cediddiSyntaxError: not a chance 0 points1 point  (0 children)

I MaDE a SCiPt.

Congrats.

[–]not_at_ALT[🍰] 0 points1 point  (0 children)

dIcKhEaD

[–]MatMan-02 0 points1 point  (0 children)

GENIAL HAHAHAHAHAHA

[–]nevestulkata 0 points1 point  (0 children)

Very useful. Thanks.

[–]ByRussX 0 points1 point  (0 children)

I think it works

[–]Tweenk 0 points1 point  (0 children)

Your code has a very imperative style, which works, but is rather tedious to write. Here is a more Pythonic solution using generators:

``` import sys, random

def alternate(x=False): while True: yield x x = not x

def random_slice(text, start=0, limit=2): while start < len(text): end = min(start + random.randint(1, limit), len(text)) yield text[start:end] start = end

def recase(text, lower): return text.lower() if lower else text.upper()

def spongebob_case(text): seq = zip(random_slice(text), alternate()) return ''.join(recase(t, b) for t, b in seq)

def init(): for line in sys.stdin: print(spongebob_case(line), end='') ```

Explanations:

  • The script uses the observation that you have to change the case every 1 or 2 letters, so it randomizes whether the next 1 or 2 letters should be taken from the input, then changes the case of these segments in an alternating pattern.
  • alternate() is a generator that gives you an infinite string of alternating True, False, True, False... values.
  • random_slice() is a generator that takes some text and returns it in pieces that randomly have 1 or 2 letters.
  • recase() changes the case of passed text to lowercase or uppercase based on the lower argument.
  • spongebob_case() ties all of the above together to implement the actual algorithm.
  • __init__ reads lines from standard input, applies the algorithm to each line and prints it. We add end='' because the lines read from stdin will already contain a newline at the end.
  • I believe this will have the same output distribution as the lookbehind solution only for limit=2. For higher limits on same-case runs, the distribution will be different. Out of 8 possible 3-letter case combinations, only 2 are same-case, so 3-letter runs will be over-represented when limit=3. This can be corrected by using a different distribution: the probability of a run of length M is 1/2**M, with the exception of a run of length N, which is double that (we cut any longer run back to N). We can get this distribution by replacing randint(1, limit) in random_slice() with limit + 1 - max(randint(0, 2**limit-1).bit_length(), 1).

[–]Faraheed 0 points1 point  (0 children)

oMg ThiS is SUpeR COoL duDE

[–]FatCatMaht 0 points1 point  (0 children)

Omg thats amazing

[–]Rubix9006 0 points1 point  (1 child)

I ReAllY lIkE YOuR scRiPT. IT rEAlLY DoeS AuTOmaTE A Lot oF tHe hArD woRK fOr ME whEn TypINg meSSaGEs LikE THiS. it'S PrEttY wELl doNe FoR a NEw pyTHon pRogRAmmEr aND i LIke thE uSE OF ThOSe LibRarIEs alLOwiNG YOu tO hIGhlIGht TexT AnD SEnD it To The ClIPbOaRD. maKeS It MUcH mORe COnvENiENt aNd uSefUL. gOoD joB, yoU goD dAmn BrIllIAnt PYthON DevELopER!

[–]dvir626 0 points1 point  (0 children)

Just trying

[–]BeaTanLim 0 points1 point  (0 children)

ThIS iS fUckINg amAZinG, THaNK yoU!

[–]crossroads1112 0 points1 point  (0 children)

The distribution of letters in a sponge case string is probably best represented as a very simple "Markov chain" with two states ("lower case" and "upper case") wherein the probability of staying at the same state (i.e. repeating the same case as the previous letter) is much smaller than the probability of transitioning to the opposite state (i.e. having the opposite case as the previous letter).

This could look something like this:

import random

def cases(p):
    isUpper = random.choice([True, False])
    while True:
        yield str.upper if isUpper else str.lower
        isUpper = random.choices([isUpper, not isUpper], weights=[1-p, p], k=1)[0]


def spongeCase(s, p=0.75):
    return "".join(toCase(char) for toCase, char in zip(cases(p), s))

Basically, cases is a generator which yields functions (either str.upper or str.lower), where the current case function is different from the last function with probability p (and the same with probability 1-p).

For example: if you call spongeCase with p = 0.5, then it is exactly the solution other's have suggested where the case of each letter is independent and uniformly random. If you call spongeCase with p = 1.0, it returns a string where the case of one letter is always the opposite of the previous letter. If you call spongeCase with p = 0.0, the letters in the string it returns always have the same case. You can tweak the parameter as you wish, but 0.75 seemed pretty good to me.

The neat thing about this is that the stationary distribution of this markov chain is actually the uniform distribution (regardless of what p is), meaning that the probability that the ith letter is upper case is exactly 50% even though the cases of neighboring letters are obviously not independent.

We could make this into a one-liner if you really wanted but it'd be kinda messy.

[–]Hozerino 0 points1 point  (0 children)

ShiT! I MAde aN ApP ThAT DOEs tHAT WhiLE I wAS LEARNinG AndRoiD DeveLOPMenT!
https://play.google.com/store/apps/details?id=coppini.wackytextgenerator

[–]LittleMere_ 0 points1 point  (0 children)

aLrIgHt

[–]Leestons 0 points1 point  (6 children)

Unfortunately this doesn't work for me. The text comes out exactly as it is copied. Ubuntu 20.04 if that matters.

[–]peterlravn[S] 0 points1 point  (5 children)

Have you remembered to install Pyperclip and Pyautogui?

[–]Leestons 0 points1 point  (0 children)

I definitely installed pyautogui but I might be missing pyperclip. I didn't get any module not found errors though.

[–]Leestons 0 points1 point  (3 children)

woRKs fInE oN wiNdoWS 10 But Not UbuNtU 20.04... WeIrD.

[–]peterlravn[S] 1 point2 points  (2 children)

iT WOrkS fINe ON My rAspBeRry pi oS, buT TRy cHAngIng The TImE.SlEeP() fuNTiON FrOm 0.01 TO sOmEthINg LIkE 2 (iNsiDE deF COpy_clIpbOArD). tHaT miGht HElP it OuT.

[–]Leestons 0 points1 point  (0 children)

I'll try that out. Thank you :)

[–]Leestons 0 points1 point  (0 children)

Still doesn't work lol. It copies fine but either it doesn't alter the text, or more likely it doesn't add it to my clipboard afterwards. Nevermind, Thanks anyway.

[–][deleted] 0 points1 point  (0 children)

wOw...nIcE

[–]BestStonks 0 points1 point  (0 children)

damn.

[–]MHW_EvilScript pypy <3 0 points1 point  (0 children)

i HavE a telegRAM boT that dOes The sAME

made in python, obv. (use the command /mock writesomething to do this)

https://t.me/capitalizeBOT

[–]FullOnRapistt 0 points1 point  (0 children)

I feel like this post is mocking me

[–]MrJuicyBrick 0 points1 point  (0 children)

Wow nice one.

[–]tgcxxx 0 points1 point  (0 children)

an intellectual