Search code examples
pythonpython-3.xsleepsys

Python 3.6 sleep() different sleep times within same string depending on character


In python 3.6, I'm trying to get a string to print with a delay between characters and a longer delay for punctuation at the end of sentences to pseudo-simulate spoken English. Here is my code. My problem is that I get the delay between characters, but I don't get the longer delay between sentences.

import time
import sys


def delay_print(s):
    for c in s:
        if c != "!" or "." or "?":
            sys.stdout.write(c)
            # If I comment out this flush, I get each line to print
            # with the longer delay, but I don't get a char-by char 
            # delay
            # for the rest of the sentence.
            sys.stdout.flush()
            time.sleep(0.05)
        elif c == "!" or "." or "?":
            sys.stdout.write(c)
            sys.stdout.flush()
            time.sleep(3)


delay_print( """
    Hello.
    I want this to have an added delay after sentence-ending 
    punctuation?
    But I also want it to have a shorter delay after each character 
    that isn't one of those chars.
    This is supposed to mimic speech patterns. Like if you've ever 
    played SNES Zelda: A Link to the Past.
    Why isn't this code doing what I want it to?.
    What I've written is broken and I don't know why!
""")

Solution

  • Your or clause isn't doing what you think it's doing. The first one checks if any of these three things is True:

    1. character != "!"
    2. bool(".")
    3. bool("?")

    Note that 2 and 3 are always true.

    If statements short circuit evaluate. If the character input were ., it would check condition 1 and find it false. Then it would include condition 2 in the evaluation False or ".". Since "." is always true, it short circuits and returns "." which evaluates to true. Try it yourself, type False or "." into the interpreter, you'll find it returns ".".

    Personally, I would do this with a set implementation like this:

    if c not in {"!", ".", "?"}: