Time delay in python mode?

edited August 2017 in Python Mode

Is there a way to create a time delay in python mode?

Answers

  • I am still unsure how to use this. It looks like it returns the current second or value as an int, but how would I use this in a time delay or Sleep mode? I assumed it would need an argument in the brackets:

    second(1)

    This obviously doesn't work.

  • Solved elsewhere.

  • I am still wondering if there is a Time Delay/halt command for python. I know with JAVA and processing, there is delay() command

    https://processing.org/reference/delay_.html

    But I can't seem to find any for python. I was wondering if changing the FRAME RATE could accomplish the same thing?

  • FrameRate might not be sufficient to what you are trying to do. Lowering the framerate value will make things flow slower. What you want is for your draw function to show one state (the fall drawing) under certain conditions and the explosion in another condition and during a length of time. This can be accomplish with a boolean flag to keep track of your state and a time field. For this, I refer to your other post: https://forum.processing.org/two/discussion/23857/problem-with-code-images-random-function-etc#latest

    Kf

  • For this, I refer to your other post

    yes, you might get more coherent, joined-up responses if you stop creating new questions for every new little problem you have.

  • edited August 2017

    I have been working with the time delay, but I am still having some challenges. In the code below, I have a rectangle being produced randomly on the screen. I used the millis() to wait 1 second between creating each rectangle. I wanted to use a WHILE LOOP to have it count out TEN rectangles, but I couldn't get it to work. Instead I used conditionals, but I know there is a better way forward. The code below works fine, but I was wondering if anyone had suggestions on how to use a while loop instead for counting or any other suggestions?

    size1=20
    size2=20
    count=0
    uptoten=1
    
    def setup():
        global size1, size2, rand_posX, rand_posY, timer
        size(400, 400)
        background(255) # white
        rand_posX= random(20, 380)
        rand_posY=random(20, 380)
    
    
    def draw():
        create_rect()
    
    def create_rect():
            global size1, size2, rand_posX, rand_posY, timer, count, uptoten
            if uptoten <= 10:
                if count<10:
                    count=count+1
                    rand_posX=random(20,380)
                    rand_posY=random(20,380)
                    timer=millis()
    
                else:
                    noFill()
                    rect(rand_posX, rand_posY, size1, size2)
                    fill(0,0,0)
                    text(uptoten, rand_posX+6, rand_posY+15)
                    if millis()>timer+1000: # 1 seconds
                        count=0 # reseting count to zero
                        uptoten=uptoten+1
    
  • The draw() function is by itself a while loop. So, do you want a while loop inside a while loop? This is your code modified:

    Kf

    size1=20
    size2=20
    count=0
    uptoten=1
    
    def setup():
        global size1, size2, rand_posX, rand_posY, timer
        size(400, 400)
        background(255) # white
        rand_posX= random(20, 380)
        rand_posY=random(20, 380)
        timer=millis()
    
    
    def draw():
        create_rect()
    
    def create_rect():
            global size1, size2, rand_posX, rand_posY, timer, count, uptoten 
            if uptoten <= 10:
                if millis()>timer+1000:                
                    noFill()
                    rand_posX=random(20,380)
                    rand_posY=random(20,380)
                    timer=millis()
                    rect(rand_posX, rand_posY, size1, size2)
                    fill(0,0,0)
                    text(uptoten, rand_posX+6, rand_posY+15)
                    timer=millis()
                    uptoten=uptoten+1
            else:
                println("DONE");
                noLoop();
    
  • I was even wondering if there was a way to create a "function" with a delay timer in it so it could be called whenever I want.

  • There are a couple of different versions implemented by different users. Here for example: https://github.com/Lord-of-the-Galaxy/Timing-Utilities/blob/master/timing_utils/src/lord_of_galaxy/timing_utils/Stopwatch.java is a version done by Lord_of_the_Galaxy. The code is in Java and it should be easy to use this code to write the python version. Give it a try if you want.

    Kf

  • edited April 2018

    https://Gist.GitHub.com/GoToLoop/ea4db8a8622e27541213da3c9a43ca21

    CountdownClass.pde:

    /** 
     * Countdown Class (v1.2.5)
     * GoToLoop (2017/Aug/26)
     *
     * Forum.Processing.org/two/discussion/27733/
     * countdown-class-library-for-java-js-python
     *
     * Forum.Processing.org/two/discussion/23846/
     * time-delay-in-python-mode#Item_11
     *
     * Gist.GitHub.com/GoToLoop/ea4db8a8622e27541213da3c9a43ca21
     */
    
    import gotoloop.countdown.Countdown;
    
    static final float SECS = 7.5;
    static final int WAIT_TIME = (int) (SECS * 1000);
    
    static final String AWAIT = "Awaiting " + SECS;
    static final String END = "Countdown Finished";
    
    static final color WAITING_BG = PImage.BLUE_MASK | PImage.ALPHA_MASK;
    static final color DONE_BG = PImage.RED_MASK | PImage.ALPHA_MASK;
    
    final Countdown countdown = new Countdown(WAIT_TIME);
    
    void setup() {
      size(300, 180);
      smooth(3);
      frameRate(60);
    
      colorMode(RGB);
      fill(#FFFF00);
    
      textSize(0100);
      textAlign(CENTER, CENTER);
    
      final int m = millis(), t = m + WAIT_TIME;
      countdown.start();
      println(m, t, t - m, TAB, countdown);
    }
    
    void draw() {
      getSurface().setTitle(countdown.done? END : AWAIT);
      background(countdown.done? DONE_BG : WAITING_BG);
    
      final String txt = millis() + "\n" + frameCount;
      text(txt, width>>1, height>>1);
    }
    

    Countdown.java:

    /** 
     * Countdown Class (v1.2.5)
     * GoToLoop (2017/Aug/26)
     *
     * https://Forum.Processing.org/two/discussion/27733/
     * countdown-class-library-for-java-js-python
     *
     * https://Forum.Processing.org/two/discussion/23846/
     * time-delay-in-python-mode#Item_11
     *
     * https://Gist.GitHub.com/GoToLoop/ea4db8a8622e27541213da3c9a43ca21
     */
    
    package gotoloop.countdown;
    
    import java.util.Timer;
    import java.util.TimerTask;
    
    public class Countdown {
      protected static final Timer t = new Timer("Countdown");
    
      public TimerTask task;
      public int delay;
      public volatile boolean done = true;
    
      public Countdown() {
      }
    
      public Countdown(final int waitTime) { // milliseconds
        delay = Math.abs(waitTime);
      }
    
      @Override public String toString() {
        return "Delay: " + delay + "  -  Done: " + done;
      }
    
      public Countdown start() {
        if (task != null)  task.cancel();
        done = false;
        t.schedule(task = new Timeout(), delay);
        return this;
      }
    
      protected class Timeout extends TimerTask {
        @Override public void run() {
          done = true;
        }
      }
    }
    
  • edited August 2017

    kfrajer : you are right, the draw() is a while loop. So should I put the time delay RIGHT IN DRAW? Here is an example of in and out of DRAW ().

    OUTSIDE OF DRAW:

        x=20
        y=20
    
        count=0
    
        def setup():
            global timer, x ,y , m, n
            size(400, 400)
    
            background(255) # white
    
        def draw():
            ellipse(x,y,36,76)
            timer_function()
    
        def timer_function():
            global count, timer, x ,y
    
            if count < 10:
                count=count+1
                timer=millis()
    
    
            elif millis() > timer+2000 :
                    print("2 seconds has passed")    
                    x=x+10
    
                    count=0
    

    INSIDE OF DRAW:

        x=20
        y=20
    
        count=0
    
        def setup():
            global timer, x ,y , m, n
            size(400, 400)
    
            background(255) # white
    
        def draw():
            global x, count, timer
    
            ellipse(x,y,36,76)
    
            if count<10:
                count=count+1
                timer=millis()
            elif millis()> timer+2000:
                print("2 seconds has passed")
                x=x+10
                count=0
    

    I have a feeling that OUTSIDE OF DRAW is the better way to go for sake of keeping the function separate.

    But I was thinking about how to stop something from happening without stopping the entire program. I used your code and then called the draw() after the noLoop (just to see if I could continue the program once noLoop has been used) and I got a recursion error from depth exceeded.

  • You can do either. It really depends on your application. Ideally, you could encapsulate your timing code in a function and it is exactly what you did in the example above: Outside of draw. For short codes and demos, I will probably keep it everything in draw().

    Kf

  • edited April 2018

    https://Gist.GitHub.com/GoToLoop/a476ac6a01d18700240853fed33c0e57

    CountdownClass.pyde:

    """
     Countdown Class (v1.2.5)
     GoToLoop (2017/Aug/28)
    
     Forum.Processing.org/two/discussion/27733/
     countdown-class-library-for-java-js-python#Item_2
    
     Forum.Processing.org/two/discussion/23846/
     time-delay-in-python-mode#Item_14
    
     Gist.GitHub.com/GoToLoop/a476ac6a01d18700240853fed33c0e57
    """
    
    from countdown import Countdown
    
    SECS = 7.5
    WAIT_TIME = int(SECS * 1000)
    
    WAITING_BG = PImage.BLUE_MASK | PImage.ALPHA_MASK
    DONE_BG = PImage.RED_MASK | PImage.ALPHA_MASK
    
    countdown = Countdown(WAIT_TIME)
    
    def setup():
        size(300, 180)
        smooth(3)
        frameRate(60)
    
        colorMode(RGB)
        fill(0xffFFFF00)
    
        textSize(0100)
        textAlign(CENTER, CENTER)
    
        m = millis(); t = m + WAIT_TIME
        countdown.start()
        print m, t, t - m, TAB, countdown
    
    
    def draw(AWAIT='Awaiting ' + `SECS`, END='Finished'):
        this.surface.title = countdown.done and END or AWAIT
        background(DONE_BG if countdown.done else WAITING_BG)
    
        txt = `millis()` + ENTER + `frameCount`
        text(txt, width>>1, height>>1)
    

    countdown.py:

    """
     Countdown Class (v1.2.5)
     GoToLoop (2017/Aug/28)
    
     https://Forum.Processing.org/two/discussion/27733/
     countdown-class-library-for-java-js-python#Item_2
    
     https://Forum.Processing.org/two/discussion/23846/
     time-delay-in-python-mode#Item_14
    
     https://Gist.GitHub.com/GoToLoop/a476ac6a01d18700240853fed33c0e57
    """
    
    from java.util import Timer, TimerTask
    
    class Countdown:
        _t = Timer('Countdown')
    
        def __init__(self, waitTime=0): # milliseconds
            self.delay = abs(int(waitTime))
            self.done = True
    
            class Job(TimerTask):
                def run(_): self.done = True
    
            self._Timeout = Job
            self.task = None
    
    
        def __str__(self, STR='Delay: %d  -  Done: %s'):
            return STR % (self.delay, self.done)
    
    
        def start(self):
            self.task and self.task.cancel()
            self.task = self._Timeout()
            self.done = False
            self._t.schedule(self.task, self.delay)
            return self
    
  • edited April 2018

    http://Bl.ocks.org/GoSubRoutine/1a0d21828319cf18fecf44101764bd60

    index.html:

    <script async src=http://CDN.JSDelivr.net/npm/p5></script>
    <script defer src=countdown.js></script>
    <script defer src=sketch.js></script>
    

    sketch.js:

    /**
     * Countdown Class (v1.2.5)
     * GoToLoop (2017/Aug/29)
     *
     * Forum.Processing.org/two/discussion/27733/
     * countdown-class-library-for-java-js-python#Item_1
     *
     * Forum.Processing.org/two/discussion/23846/
     * time-delay-in-python-mode#Item_16
     *
     * Bl.ocks.org/GoSubRoutine/1a0d21828319cf18fecf44101764bd60
     */
    
    "use strict";
    
    const SECS = 7.5, WAIT_TIME = SECS * 1000 | 0,
          AWAIT = SECS, END = 'Finished', LF = '\n',
          countdown = new Countdown(WAIT_TIME);
    
    let waitingBG, doneBG;
    
    function setup() {
      createCanvas(300, 180);
      frameRate(60);
    
      colorMode(RGB).blendMode(BLEND);
      fill('yellow').stroke(0).strokeWeight(1.5);
      textSize(0o100).textAlign(CENTER, CENTER);
    
      waitingBG = color('blue');
      doneBG = color('red');
    
      const m = ~~millis(), t = m + WAIT_TIME;
      countdown.start();
      console.log(m, t, t - m, countdown.toString());
      status = m + ', ' + t + ', ' + (t - m);
    }
    
    function draw() {
      top.document.title = countdown.done && END || AWAIT;
      background(countdown.done && doneBG || waitingBG);
    
      const txt = ~~millis() + LF + frameCount;
      text(txt, width>>1, height>>1);
    }
    

    countdown.js:

    /**
     * Countdown Class (v1.2.5)
     * GoToLoop (2017/Aug/29)
     *
     * https://Forum.Processing.org/two/discussion/27733/
     * countdown-class-library-for-java-js-python#Item_1
     *
     * https://Forum.Processing.org/two/discussion/23846/
     * time-delay-in-python-mode#Item_16
     *
     * http://Bl.ocks.org/GoSubRoutine/1a0d21828319cf18fecf44101764bd60
     */
    
    "use strict";
    
    class Countdown {
      get delay() {
        return this._delay;
      }
    
      set delay(waitTime) {
        this._delay = ~~Math.abs(waitTime);
      }
    
      constructor(waitTime=0) { // milliseconds
        this.delay = waitTime;
        this.done = true;
        this._timeout = () => this.done = true;
        this.task = 0;
      }
    
      toString() {
        return 'Delay: ' + this.delay + '  -  Done: ' + this.done;
      }
    
      start() {
        clearTimeout(this.task);
        this.done = false;
        this.task = setTimeout(this._timeout, this.delay);
        return this;
      }
    }
    
  • edited April 2018

    https://Gist.GitHub.com/GoToLoop/893dc18856a7842b76a92d8aea837da1

    CountdownClass2.pyde:

    """
     Countdown Class II (v1.2.5)
     GoToLoop (2017/Aug/30)
    
     Forum.Processing.org/two/discussion/27733/
     countdown-class-library-for-java-js-python#Item_3
    
     Forum.Processing.org/two/discussion/23846/
     time-delay-in-python-mode#Item_17
    
     Gist.GitHub.com/GoToLoop/893dc18856a7842b76a92d8aea837da1
    """
    
    from countdown import Countdown
    
    SECS = 7.5
    WAIT_TIME = int(SECS * 1000)
    
    WAITING_BG = PImage.BLUE_MASK | PImage.ALPHA_MASK
    DONE_BG = PImage.RED_MASK | PImage.ALPHA_MASK
    
    countdown = Countdown(SECS)
    
    def setup():
        size(300, 180)
        smooth(3)
        frameRate(60)
    
        colorMode(RGB)
        fill(0xffFFFF00)
    
        textSize(0100)
        textAlign(CENTER, CENTER)
    
        m = millis(); t = m + WAIT_TIME
        countdown.start()
        print m, t, t - m, TAB, countdown
    
    
    def draw(AWAIT='Awaiting ' + `SECS`, END='Finished'):
        this.surface.title = countdown.done and END or AWAIT
        background(DONE_BG if countdown.done else WAITING_BG)
    
        txt = `millis()` + ENTER + `frameCount`
        text(txt, width>>1, height>>1)
    

    countdown.py:

    """
     Countdown Class II (v1.2.5)
     GoToLoop (2017/Aug/30)
    
     https://Forum.Processing.org/two/discussion/27733/
     countdown-class-library-for-java-js-python#Item_3
    
     https://Forum.Processing.org/two/discussion/23846/
     time-delay-in-python-mode#Item_17
    
     https://Gist.GitHub.com/GoToLoop/893dc18856a7842b76a92d8aea837da1
    """
    
    from threading import Timer
    
    class Countdown:
        def __init__(self, waitTime=0.0): # seconds
            self.delay = abs(waitTime)
            self.done = True
    
            def job(): self.done = True
    
            self._timeout = job
            self.task = None
    
    
        def __str__(self, STR='Delay: %.3f  -  Done: %s'):
            return STR % (self.delay, self.done)
    
    
        def start(self):
            self.task and self.task.cancel()
            self.task = Timer(self.delay, self._timeout)
            self.done = False
            self.task.start()
            return self
    
  • I couldn't get the Countdown library to work. I installed it, restarted processing and it still gives me the error No Module Named Countdown. I looked back in the libraries and it says it is installed.

  • edited April 2018
    • In order for class Countdown to be found by statement from countdown import Countdown, its file gotta be exactly named "countdown.py". L-)
    • And in order to have its name's extension ".py", it can't be the 1st tab.
    • The extension for the 1st tab is always ".pyde". The other tabs are ".py".
    • For Python, there are 2 versions: "Countdown Class" & "Countdown Class II".
    • "Countdown Class" relies on from java.util import Timer, TimerTask and its delay property is in int milliseconds.
    • "Countdown Class II" relies on from threading import Timer and its delay property is in float seconds.
    • In order to use class Countdown, regardless its version, invoke its name w/ () passing the desired delay value as its argument, and store it in some global variable : countdown = Countdown(time_to_wait).
    • Start the countdown delaying by invoking its start() method: countdown.start(). :!!
    • Now keeping checking its property done until it becomes True: if countdown.done:
    • Once it becomes True, it means the desired delay countdown time has finished. #:-S
    • You can always restart the countdown again by re-invoking its start() method as many times as you need it.
    • The previous task is automatically cancel() when re-invoking start(). :P
    • You can even change its delay for some other value before calling start(): countdown.delay = another_time_to_wait_value; countdown.start().
    • And if you happen to need to track different delay times at the same time, instantiate class CountDown that many times and store each of those in its own variable or store them all in 1 list container.
    • Besides those 2 Python versions, there are also 1 for Java and 1 for JavaScript! :-bd
  • edited August 2017

    I couldn't get the Countdown library to work. I installed it, ...

    • Oh, I wasn't aware there was such 3rd-party library available to download within Contribution Manager already. b-(
    • However, it's called CountdownTimer, not just Countdown as mine:
      https://GitHub.com/dhchoi/processing-countdowntimer
    • You see, my own versions aren't distributed via the Contribution Manager yet.
    • I've just made & pasted them here in your discussion thread!
    • And they're much simpler to use than CountdownTimer.
    • They just have method start() and properties delay & done and nothing else. :-\"
    • However, b/c it doesn't rely on any 3rd-party libraries (not even Processing itself!), the Java version for my Countdown ("Countdown.java") can be easily compiled via javac.exe and then packaged as "Countdown.jar" via jar.exe. ~O)
    • BtW, we can place ".jar" files in subfolder "code/". Then import them in our own sketches.
    • Not only for Java Mode, but Python Mode too. Probably R Mode as well. \m/
  • I am just getting back to this thread. I did see you Countdown timer in the distribution manager now, but I am unsure on how to import or call it!

  • I did see you Countdown timer in the distribution manager now, ...

    That CountdownTimer library isn't mine. I've never published my own Countdown class anywhere else! :-\"

    Once installed, if you wanna import that particular 3rd-party library, you may try out this statement: L-)
    add_library('CountdownTimer')

  • Interesting. It says Dong Hyun Choi. When I click on the instructions at the bottom, it takes me to your website : https://github.com/dhchoi/processing-countdowntimer https://ibb.co/c9JesH

    Ok, I will try the ADD LIBRARY

  • ... it takes me to YOUR website : https://github.com/dhchoi/processing-countdowntimer

    MY website? 8-}

  • edited April 2018

    Oh I see what I've done, I mixed up here: you wrote : "However, it's called CountdownTimer, not just Countdown as mine:" I thought the first one was yours...now I see. Are you going to share yours at some point or is it just a personal project?

  • edited April 2018

    Are you going to share yours at some point...

    I've written them for you here in this very forum thread! Can't you spot them? :-\"
    There are 4 versions btW: :\">

    • 1 Java version: "Countdown.java".
    • 1 JS version: "countdown.js".
    • 2 Python versions: both named "countdown.py".

    I advise you to read your forum thread from the beginning. #:-S
    You seem pretty lost after your almost a year "vacation". B-)

  • Yes I have finally spotted them. Trying to understand them now.
    Ok, I have the countdown.py (as the second tab) and your pyde copied and pasted in the first tab. I do not get any errors running it so I have named them correctly. The program seems to run a timer, the bottom number runs slower than the one on top.
    The one at the top I assume is regular time (in seconds). The one on the bottom, I am not sure how it works. No matter what I changed the SECS or the (SECS * number), it seems to run at the same speed. My benchmark was 10 second ( at the top) and the bottom always seems to be at about 600. Looking at the console, I see the FALSE shows up immediately, but even when I set the SECS to something low, it never gets to TRUE (which is what I thought it was supposed to do). I am probably wrong here...what else is new...

  • edited April 2018

    Looking at the console, I see the FALSE shows up immediately, ...

    That console printed info is run from within setup(). Therefore it happens once only!

    When I run it, my console displays something like this: 2764 10264 7500 Delay: 7500 - Done: False

    1. 2764 is current millis().
    2. 10264 is the expected millis() when Countdown::done becomes True.
    3. 7500 is the Countdown::delay time. That is: 10264 - 2764.
    4. Delay: 7500 - Done: False is the String returned by Countdown::_ _ str _ _()

    ... , it never gets to TRUE (which is what I thought it was supposed to do).

    Have you paid attention to what is displayed at the top of the sketch's window? L-)

    In the beginning its title is: Awaiting 7.5.
    Once the expected millis() is reached its title becomes: Finished

    Constant SECS is 7.5, which is the desired Countdown::delay time in seconds.
    While constant WAIT_TIME is SECS multiplied by 1000. Which is its corresponding time in milliseconds.

  • edited April 2018

    Be aware that "CountdownClass1.pyde" & "CountdownClass2.pyde" are a silly test drive I've come up w/ in order to confirm that "countdown.py" is indeed working correctly. :(|)

    The class Countdown inside file "countdown.py" is the actual library. $-)
    The ".pyde" sketch is merely a very limited example for the library in "countdown.py". 8-X

  • edited April 2018

    And in order to make easier to spot each version and have them organized in 1 place, I've re-published them all in a new own forum thread of mine: :-bd

    https://Forum.Processing.org/two/discussion/27733/countdown-class-library-for-java-js-python

    And as GitHub's Gists as well: :bz

    1. Java Mode Version: https://Gist.GitHub.com/GoToLoop/ea4db8a8622e27541213da3c9a43ca21
    2. p5.js JS Version: http://Bl.ocks.org/GoSubRoutine/1a0d21828319cf18fecf44101764bd60
    3. Python Mode Version based on java.util.Timer: https://Gist.GitHub.com/GoToLoop/a476ac6a01d18700240853fed33c0e57
    4. Python Mode Version based on threading.Timer: https://Gist.GitHub.com/GoToLoop/893dc18856a7842b76a92d8aea837da1
  • This is great and you are generous, but I cannot make heads or tails on how to use this script properly. I can see that is works, but how it works is beyond me.

Sign In or Register to comment.