1

My programs supposed to play a game. It's the loading screen I'm having problems with. When I run it, time.sleep acts as if it's sleeping 0.1 seconds, instead of the much smaller numbers I input into it. Why is this? Is there a way I can make the delays shorter? Here's the code:

import os
import random
import time
import sys

def mywrite(line2,line1,t,s,x='small'):
    if x=='small':
        x=0.0000000000000000000000000000000000000000000000000000000000000000000000001
    else:
        x=random.random()*t+s
    word=''
    for c in line1:
        if line1.index(c)<len(line1)-1:
            print(line2)
            word=word+c
            print(word)
            time.sleep(x)
            os.system('cls')
        else:
            print(line2)
            word=word+c
            print(word,' \n')
            time.sleep(x)
mywrite('__________________________________________________________\n',' %33s'%'Scrambled',0.005,0.1,'random')
print('    Press "a" to play %30s'%'Press "s" to exit')
print('__________________________________________________________')
start=input()
if start=='a':
    permission=1
if start=='s':
    permission=0
if permission==0:
    sys.exit()
if permission==1:
    print("Choose Difficulty")
    print('Easy        -Press a')
    print('Hard        -Press b')
    print('Insane      -Press c')
    diff=input()
y=0
while permission==1:
    os.system('cls')
    mywrite('''





  _                       _   _                 
 (_)   ___     __ _    __| | | |  _ __     __ _ 
 | |  / _ \\   / _` |  / _` | | | | '_ \\   / _` |
 | | | (_) | | (_| | | (_| | | | | | | | | (_| |
 |_|  \\___/   \\__, |  \\__,_| |_| |_| |_|  \\__,_|
              |___/                                                       
    ''', 0.005, 0.001)
    time.sleep(2)
    os.system('cls')
    mywrite('''
  _                           _                 
 (_)           __ _          | |           __ _ 
 | |          / _` |         | |          / _` |
 | |         | (_| |         | |         | (_| |
 |_|          \__, |         |_|          \__,_|
              |___/                             
                          _                 
       ___             __| |      _ __  
      / _ \           / _` |     | '_ \ 
     | (_) |         | (_| |     | | | |
      \___/           \__,_|     |_| |_|

    ''', 0.005, 0.001)
    time.sleep(2)
    os.system('cls')
    mywrite('''
  _                           _                 
 | |           __ _          (_)           __ _ 
 | |          / _` |         | |          / _` |
 | |         | (_| |         | |         | (_| |
 |_|          \__,_|         |_|          \__, |
                                          |___/ 
                          _                 
       ___             __| |      _ __  
      / _ \           / _` |     | '_ \ 
     | (_) |         | (_| |     | | | |
      \___/           \__,_|     |_| |_|

    ''', 0.005, 0.001)
    time.sleep(2)
    os.system('cls')
    mywrite('''





  _                       _   _                 
 | |   ___     __ _    __| | (_)  _ __     __ _ 
 | |  / _ \   / _` |  / _` | | | | '_ \   / _` |
 | | | (_) | | (_| | | (_| | | | | | | | | (_| |
 |_|  \___/   \__,_|  \__,_| |_| |_| |_|  \__, |
                                          |___/ 

    ''', 0.005, 0.001)
    time.sleep(4)
    os.system('cls') 
    if y==2:
        break

If that's too long, here's the part that contains the problem:

import os
import random
import time
import sys

def mywrite(line2,line1,t,s,x='small'):
    if x=='small':
        x=0.0000000000000000000000000000000000000000000000000000000000000000000000001
    else:
        x=random.random()*t+s
    word=''
    for c in line1:
        if line1.index(c)<len(line1)-1:
            print(line2)
            word=word+c
            print(word)
            time.sleep(x)
            os.system('cls')
        else:
            print(line2)
            word=word+c
            print(word,' \n')
            time.sleep(x)
while permission==1:
    os.system('cls')
    mywrite('''





  _                       _   _                 
 (_)   ___     __ _    __| | | |  _ __     __ _ 
 | |  / _ \\   / _` |  / _` | | | | '_ \\   / _` |
 | | | (_) | | (_| | | (_| | | | | | | | | (_| |
 |_|  \\___/   \\__, |  \\__,_| |_| |_| |_|  \\__,_|
              |___/                                                       
    ''', 0.005, 0.001)
    time.sleep(2)
    os.system('cls')
    mywrite('''
  _                           _                 
 (_)           __ _          | |           __ _ 
 | |          / _` |         | |          / _` |
 | |         | (_| |         | |         | (_| |
 |_|          \__, |         |_|          \__,_|
              |___/                             
                          _                 
       ___             __| |      _ __  
      / _ \           / _` |     | '_ \ 
     | (_) |         | (_| |     | | | |
      \___/           \__,_|     |_| |_|

    ''', 0.005, 0.001)
    time.sleep(2)
    os.system('cls')
    mywrite('''
  _                           _                 
 | |           __ _          (_)           __ _ 
 | |          / _` |         | |          / _` |
 | |         | (_| |         | |         | (_| |
 |_|          \__,_|         |_|          \__, |
                                          |___/ 
                          _                 
       ___             __| |      _ __  
      / _ \           / _` |     | '_ \ 
     | (_) |         | (_| |     | | | |
      \___/           \__,_|     |_| |_|

    ''', 0.005, 0.001)
    time.sleep(2)
    os.system('cls')
    mywrite('''





  _                       _   _                 
 | |   ___     __ _    __| | (_)  _ __     __ _ 
 | |  / _ \   / _` |  / _` | | | | '_ \   / _` |
 | | | (_) | | (_| | | (_| | | | | | | | | (_| |
 |_|  \___/   \__,_|  \__,_| |_| |_| |_|  \__, |
                                          |___/ 

    ''', 0.005, 0.001)
    time.sleep(4)
    os.system('cls') 
    if y==2:
        break

BTW I'm only a few days into python, so please keep the explanations simple. Thank you.

MarianD
  • 13,096
  • 12
  • 42
  • 54
Qartx
  • 27
  • 9
  • you should avoid writing 0.0000000000000000000000000000000000000000000000000000000000000000000000001 and learn about [E-notation](https://en.wikipedia.org/wiki/Scientific_notation#E-notation) – Azat Ibrakov Apr 11 '17 at 23:11
  • I know about that. I just got frustrated and spammed that 0. XD – Qartx Apr 11 '17 at 23:16
  • off-topic, but why is the first "loading" art backspace-escaped but the rest aren't? If you don't need escapes, don't put escapes. If you do, put them everywhere (or preferably, use raw string notation `r"something\with\backslashes"`) – Adam Smith Apr 11 '17 at 23:27
  • It didn't show properly when i ran the first one without them. After i put them in, they all worked fine. My teacher mentioned something about it being like that because backspaces only sometimes cause problems. – Qartx Apr 11 '17 at 23:43

4 Answers4

1

You can test minimum resolution of time.sleep by doing something like:

from datetime import datetime
import time

def test_time(delay):
    start = datetime.now()
    time.sleep(delay)
    finish = datetime.now()
    diff = finish - start
    return diff.total_seconds()

Define that in your REPL (IDLE or terminal or whatever you use) and test it out. On my system, using Python 3.6.1, I get:

>>> test_time(1)
1.014032
>>> test_time(1)
1.014032
>>> test_time(0.1)
0.109204
>>> test_time(0.0001)
0.015601
>>> test_time(0.0002)
0.015601
>>> test_time(0.000000000001)
0.0156
>>> test_time(0.000000000001)
0.0156
>>> test_time(0.0000000000000000000000001)
0.015601
>>>

So the minimum resolution of time.sleep is somewhere around 0.0156 seconds on my machine. Your individual implementation may vary.

Adam Smith
  • 52,157
  • 12
  • 73
  • 112
  • Thanks. But do you know of an alternative for time.sleep? One that has a minimum resolution of around 0.0001 or so? – Qartx Apr 11 '17 at 22:53
  • The fact that you need resolution that small indicates that you shouldn't be using Python for this. Why do you need to sleep for tenths of milliseconds at a time? – Adam Smith Apr 11 '17 at 23:00
  • Also: what OS are you using? You're more likely limited by your architecture than your choice of programming language! See [this similar question](https://stackoverflow.com/questions/1133857/how-accurate-is-pythons-time-sleep) – Adam Smith Apr 11 '17 at 23:02
  • e. g. you can make for-loop in range of 100000 or so but it doesn't seem to be a good solution because after all you are going to have desired behavior only on your machine and a disaster on another – Azat Ibrakov Apr 11 '17 at 23:06
  • I'm using windows. This is a grade 10 tech project, so I'd rather my teacher didn't get bored of watching the ridiculously long loading screen. And yes, I asked her for help, but she said she doesn't know :/ – Qartx Apr 11 '17 at 23:13
  • @Qartx What you're trying to do cannot be reasonably done. Abandon course, young padawan, and implement a different method! (What are you `time.sleep`ing for? Can you fix it with concurrency? `async`/`await` is new and awesome!) – Adam Smith Apr 11 '17 at 23:24
  • The thing is, idk what concurrency, async, or await are. Thanks for the info tho, I can now search them up. – Qartx Apr 11 '17 at 23:45
  • @Qartx No wait stop! Down that path lies only madness! There's an old saying in programming: "I had a problem, so I used threading. Now have two I problems." Trying to introduce concurrency when it's not absolutely necessary is a headache at best, and will ruin everything at worst. It's almost CERTAINLY not necessary here (and given your code: absolutely not. You're not waiting on something to return data, you're just trying to make a graphic look animated. Don't do that here) – Adam Smith Apr 11 '17 at 23:48
  • Oh ok. Thanks. I'll still look into it so i can use in in the future tho. – Qartx Apr 11 '17 at 23:51
1

Actually, time.sleep tries to achieve the desired sleep time but does not guarantee it. From the documentation:

The argument may be a floating point number to indicate a more precise sleep time. The actual suspension time may be less than that requested because any caught signal will terminate the sleep() following execution of that signal’s catching routine. Also, the suspension time may be longer than requested by an arbitrary amount because of the scheduling of other activity in the system.

Here are some measurements of accuracy.

There's no cross-platform way to achieve sub-millisecond timing. E.g. on windows you cannot get better than 1ms. See https://mail.python.org/pipermail/python-win32/2006-August/004906.html. On Linux, there may be ways using nanosleep(). See also Python: high precision time.sleep

Community
  • 1
  • 1
Tim Hoffmann
  • 1,325
  • 9
  • 28
0

i found that if you use:

timer = time.time()
    while timer + wait > time.time(): #wait is your sleep time
      pass

the result is better then when you use:

time.sleep(wait)

but i don't know why

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Dec 13 '21 at 15:57
0

As suggested by Vincent Havinga above, i tried to test the resolution of

timer = time.time()
while timer + wait > time.time(): #wait is your sleep time
  pass

it rounds to 3rd decimal, so setting 0.003333 round to 0.0039

btw... time.sleep() resolution is blocked at 0.015 while the code above grant a resolution down to 3rd decimal so 0.001

nice, and thx Vincent

Jorel
  • 11
  • 3