Python Forum
how to modify a variable that is passed as parameter
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
how to modify a variable that is passed as parameter
#1
Hi everyone,

I have quite some experience with Delphi, Parallax SPIN and Arduino C++

NOw I started to use CircuitPython with a Teensy 4.0-microcontrollerBoard.
The following question is about programming in python in general

On micorcontrollers non-blocking timing is essential. Do multiple things
at the (almost) same time.

From C++ you can pass variables by pointer to be able to modify the variables value
that is used to pass the parameter

So in c++ it would look like this

boolean TimePeriodIsOver (unsigned long &expireTime, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - expireTime >= TimePeriod )
  {
    expireTime = currentMillis; // set new expireTime
    return true;                // more time than TimePeriod) has elapsed since last time if-condition was true
  } 
  else return false;            // not expired
}
the parameter expiretime is passed by pointer so the modifying of the value is stored
inside of the variable that is used by the functioncall

example

unsigned long MyTimer 

if ( TimePeriodIsOver (MyTimer, 500) )
With this call the variable MyTimer gets updated automatically
what makes the call very compact

I tried to realise this in python I have this working solution

import board
import digitalio
import time

def TimePeriodIsOver(p_TimerVar, Period):
    now = time.monotonic()
    Diff = now - p_TimerVar
    if Diff >= (Period / 1000):
       p_TimerVar = now + Period / 1000
       return True , p_TimerVar
       
    else:        
       return False, p_TimerVar


led = digitalio.DigitalInOut(board.D13)

led.direction = digitalio.Direction.OUTPUT
duration = 0.1

print('Hello 4 World!')
now = time.monotonic()
now_ns = time.monotonic_ns()
print ('Now:',now, '  nanosec:', now_ns)

TimerVar = time.monotonic()
print('before while true TimerVar',TimerVar)

while True:
    #print('TimerVar',TimerVar)
    #time.sleep(0.25)
    TPOver, TimerVar, = TimePeriodIsOver(TimerVar, 500)
    if TPOver == True:
      if led.value == True:
        led.value = False

      else:
          led.value = True
But this is not as compact as the c++-Version
So can it be done more compact without the need of another variable like TPOver?

best regards Stefan
Reply
#2
Numbers are immutable, so you cannot change it. That is why you cannot pass a number to a function and have the function change the number, You can only make a new number and return. If you want to change a value passed as a function argument the value must be mutable. If you put your expireTime in a list and passed the list, the function could change the value and the change would be seen outside the function.
def TimePeriodIsOver (expireTime, TimePeriod):
    currentMillis  = millis()
    if currentMillis - expireTime[0] >= TimePeriod:
        expireTime[0] = currentMillis
        return True
    return False

expireTime = [millis()]
while not TimePeriodIsOver(expireTime, 5.0):
    """do something"""
But there are other mutable types that are better suited. How about a class? If this timer thing is something you use a lot, why not make it a class?
import time

class Timer():
    def __init__(self, period=0):
        self.period = period
        self.start_time = None

    def start(self):
        self.start_time = time.time()

    def period_over(self):
        new_time = time.time()
        if self.start_time is None:
            self.start_time = new_time
        if new_time - self.start_time > self.period:
            self.start_time = new_time
            return True
        return False

timer = Timer(5)
while not timer.period_over():
    print('waiting')
    time.sleep(1)
There are packages in Python designed to periodically execute code. I don't know what is available for your target.
Reply
#3
Hi deanhystad,

thank you very much for answering and showing how to code it as a class.
Still I have a question:

Do I understand right
in your demo-code
timer = Timer(5) creates an "instance" of class Timer and the period after which
the "method" .period_over returns true is 5 seconds
and if result is true the timer-"object" gets updated to return false until another 5 seconds are over?

So this could be used in an infinite loop for repeated "delayed" execution of code?

best regards Stefan
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  How to receive two passed cmdline parameters and access them inside a Python script? pstein 2 278 Feb-17-2024, 12:29 PM
Last Post: deanhystad
  Function parameter not writing to variable Karp 5 892 Aug-07-2023, 05:58 PM
Last Post: Karp
  [ERROR] ParamValidationError: Parameter validation failed: Invalid type for parameter gdbengo 3 10,656 Dec-26-2022, 08:48 AM
Last Post: ibreeden
  detecting a generstor passed to a funtion Skaperen 9 3,467 Sep-23-2021, 01:29 AM
Last Post: Skaperen
  are numeric types passed by value or reference? rudihammad 4 2,560 Nov-19-2019, 06:25 AM
Last Post: rudihammad
  Can a function modify a variable outside it? Exsul 3 5,881 Jul-30-2019, 12:47 AM
Last Post: cvsae
  Is there a way to append to a list WITHOUT modifying the parameter passed? arnavb 11 5,584 Sep-23-2018, 07:16 AM
Last Post: Skaperen
  Help in understanding scope of dictionaries and lists passed to recursive functions barles 2 3,148 Aug-11-2018, 06:45 PM
Last Post: barles
  can't understand why 'str' is passed as parameter uddhavpgautam 2 2,723 Apr-16-2018, 05:15 PM
Last Post: nilamo
  Why args type is always tuple, when passed it as argument to the function. praveena 5 5,257 Jan-16-2018, 09:07 AM
Last Post: praveena

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020