How while loops affect other codes running

I need help understanding while loops. I know this should be basic knowledge, but I can’t get a clear picture of the while loop with code outside of the loop. In my case I have to have something done once every 24 hours. That is the whole while loop with sleep(1). I have that.

I need to understand how the while loop effects the rest of the code running. Do I need to split the while code. Put other code inside the while loop so the other code still runs while waiting on the while code to activate?

Thanks for the help, great forum for help, so helpful.

The while loop does not effect code outside the loop except that changes to variables and data inside the loop will be seen outside the loop.

In simple terms, Python runs one line of code at a time. If you start at the top of the script, and imagine the interpreter doing whatever you tell it to do in line 1, line 2, line 3 etc until you reach a while loop. Then it runs the lines of code inside the while loop and jumps back to the beginning of the loop. It does that until the while condition is false, when it jumps to just past the loop.

Try this:


import time

print("starting launch")

x = 10

while x > 0:

    print(x)

    x = x - 1

    time.sleep(1)  # Pause for 1 second (not 1 day!)



print("lift off")

The code before the while loop runs, then the while loop repeats the inner block until the conditionx > 0 is false, then the code after the loop runs.

Code after the loop will never run if the while loop never completes.

A while loop is not the best solution for this. The problem is that your script will need to run for weeks or months at a time, and for 99.99% of that time it’s just doing nothing.

If you reboot your computer, your script will stop running and your scheduled task will not run.

When you have a task that needs to be repeated according to some schedule (once a day, once a month, once an hour, etc) the best solution is not to program the schedule yourself, but to leave it to the OS. How you do that depends on which OS you have. On Linux the scheduler is called “cron”. Windows and Mac OS will have one too, but I don’t know what they are called.

You write a script that just does whatever the task is, then you tell the scheduler to run that script every day, and the OS will take care of running it every 24 hours.

Here is an example: suppose you want to delete a file called “rubbish.junk” ever 24 hours. You might be tempted to write this:


import os

import time

while True:

    # Run at exactly 5am

    if time.strftime('%H:%M:%S') == '05:00:00':

        os.remove('/home/steve/rubbish.junk')

    sleep(1)



But don’t do this! There is no guarantee that the call to strftime will hit at exactly 5:00:00. If it misses by a second, the file won’t be deleted until at least one day later.

Better is to just write a script to delete the file:


import os

os.remove('/home/steve/rubbish.junk')

and use the OS scheduler to run it every day at 5:00am.

Thanks for explaining both about the while loop and the os.schedule. Yes, much better solution with the os.schedule.
I have one other question.

i = 1
while i < 6:
  print(i)
  # this is where I would part of the code that had to keep running (initialize function, main function)
i += 1

This would make the loop a wrapper around the program. Is this OK?

Thanks.

No. You don’t need to keep anything running. That is the point of using the OS, which is already always running (unless the computer is off).

Just write your script to run once (no while loop!) and the OS scheduler (cron on Linux, something else on Windows) will handle everything else.

Forget the while loop, and write your script like this:

declare your functions
setup any variables you need
run the functions

There is no loop needed.

For linux i use systemd timer unit these days as i find it easier to get right the cron. I use this for lots of time related scripts at home and work.

For windows there is a task scheduler with its command line schtasks tool, there is also a gui. I have not used this.

For macOS use launchctl to add a scheduled task.
I use this to run a email clean up python script once a day.

Got it. This is a really useful tool when you think about it. Thanks for the great explainations. This is why this forum is so wonderful. Where else could you aquire this knowledge?

I do have one question. When done with writing the script and make it an ‘.exe’. Will that program run on any operating system or only on windows?

I’m not on Windows, but I believe that just having the .py extension and
the #!/usr/bin/env python3 shebang line will made a script executable,
at least from the command line. AIUI the .py file association invokes
the Python launcher, which understants the shebang line.

I don’t think you need to make an “exe” even on Windows.

On UNIX/POSIX (eg MacOS or Linux) scripts can be made genuinely
executable by (a) setting the read and execute permissions and (b)
setting the correct shebang line, which is usually #!/usr/bin/env python3.

When you try to execute a command on a UNIX/POSIX system either at the
command line or via the OS exec*p() call, the following happen:

  • if the command is just a word instead of the full path to an
    executable, the full path is inferred by looking for executable files
    in the $PATH environment variable
  • having found the executable, the loader looks at the file header
  • a binary file is loaded into memory and executed, but a script with a
    shebang line is run via an interpreter

That last bit makes scripts directly executable, again without making
an “exe”.

The usual shebang line for a Python script is:

 #!/usr/bin/env python3

The format is:

  • #! which is the “shebang”, indicating that this is a script to be
    run by an interpreter such as Python
  • the next bit is the path to the interpreter
  • optionally followed by an argument for the interpreter

I’m going to show the direct version first:

 #!/usr/bin/python3

If that’s in your script and you ran the command:

 your-script-name some arguments

this would cause the OS to invoke the executable /usr/bin/python3 with
the argument list:

 /usr/bin/python3 the-path-to-your-script some arguments

/usr/bin/python3 is a real binary executable, and the above invocation
causes python3 to open your script and run it with some arguments.

This is why scripts need both the execute and read permissions: the
execute permission is used by the OS to find the script as an
“executable” and the read permission is needed by the interpreter
because it literally has to open the script and read its contents.

So the shebang line is a little indirection understood by the OS
itself
which invokes some interpreter on your script file. By invoking
/usr/bin/python3 it causes the script to be interpreted as Python.

By contrast, shell scripts start:

 #!/bin/sh

which will invoke the executable /bin/sh (available on all
UNIX/POSIX systems, providing a Bourne shell) on a script. That makes a
shell script a shell script.

Returning to the original shebang:

 #!/usr/bin/env python3

this is a bit of a gimmick. Python3 is not always installed in the same
place, or you may want to run your “preferred” python3. The env
command will find python3 in your $PATH, thus choosing the python3
which would be found if you invoked python3 yourself.

The short summary: you do not normally need to “make an exe”.

On UNIX/POSIX the OS directly understands the shebang line.

On Windows the python launcher is associated with the .py extenstion,
and the luancher understands the shebang line.

Cheers,
Cameron Simpson cs@cskk.id.au

Windows “.exe” files will only run on Windows, or on Linux or Mac systems which have a Windows emulator installed.