Reputation: 403
Im new in python, many hours googled and search here in stackoverflow. But still have problem with my code. I need run foo function in time interval, and fill dataframe (eg every second add timestamp to df). I'm still coming across a error message: NameError: name 'df' is not defined
Thank you for your answer.
Code:
WAIT_TIME_SECONDS = 1
class ProgramKilled(Exception):
pass
df = pd.DataFrame([])
############################################################
############################################################
def foo():
global df
time1 = str(datetime.now())
time2 = time1.replace(":", "_")
print(time2)
df2 = pd.DataFrame(data= {
'timestamp': [time2],
'cas_zapas_1_text': ['cas']
})
df = df.append(df2)
############################################################
############################################################
def signal_handler(signum, frame):
raise ProgramKilled
class Job(threading.Thread):
def __init__(self, interval, execute, *args, **kwargs):
threading.Thread.__init__(self)
self.daemon = False
self.stopped = threading.Event()
self.interval = interval
self.execute = execute
self.args = args
self.kwargs = kwargs
def stop(self):
self.stopped.set()
self.join()
def run(self):
while not self.stopped.wait(self.interval.total_seconds()):
self.execute(*self.args, **self.kwargs)
if __name__ == "__main__":
signal.signal(signal.SIGTERM, signal_handler)
signal.signal(signal.SIGINT, signal_handler)
job = Job(interval=timedelta(seconds=WAIT_TIME_SECONDS), execute=foo)
job.start()
while True:
try:
time.sleep(1)
except ProgramKilled:
print("Program killed: running cleanup code")
job.stop()
break
This is resultof script:
runfile('C:/Users/Miro/.spyder-py3/untitled8.py', wdir='C:/Users/Miro/.spyder-py3')
Exception in thread Thread-8:
Traceback (most recent call last):
File "C:\Users\Miro\Anaconda3\envs\spyder_4_0_1\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "C:\Users\Miro\.spyder-py3\untitled8.py", line 90, in run
self.execute(*self.args, **self.kwargs)
File "C:\Users\Miro\.spyder-py3\untitled8.py", line 68, in foo
df = df.append(df2)
NameError: name 'df' is not defined
2020-06-16 08_29_31.920157
Program killed: running cleanup code
Upvotes: 0
Views: 19840
Reputation: 403
Thank you all for your helpful and quick answers. This solution works:
WAIT_TIME_SECONDS = 1
global df
df = pd.DataFrame([])
class ProgramKilled(Exception):
pass
############################################################
############################################################
def foo():
global df
time1 = str(datetime.now())
time2 = time1.replace(":", "_")
print(time2)
df2 = pd.DataFrame(data= {
'timestamp': [time2],
'cas_zapas_1_text': ['cas']
})
df = df.append(df2)
############################################################
############################################################
def signal_handler(signum, frame):
raise ProgramKilled
class Job(threading.Thread):
def __init__(self, interval, execute, *args, **kwargs):
threading.Thread.__init__(self)
self.daemon = False
self.stopped = threading.Event()
self.interval = interval
self.execute = execute
self.args = args
self.kwargs = kwargs
def stop(self):
self.stopped.set()
self.join()
def run(self):
while not self.stopped.wait(self.interval.total_seconds()):
self.execute(*self.args, **self.kwargs)
if __name__ == "__main__":
signal.signal(signal.SIGTERM, signal_handler)
signal.signal(signal.SIGINT, signal_handler)
job = Job(interval=timedelta(seconds=WAIT_TIME_SECONDS), execute=foo)
job.start()
while True:
try:
time.sleep(1)
except ProgramKilled:
print("Program killed: running cleanup code")
job.stop()
break
Upvotes: 0
Reputation: 77347
You made df
part of the ProgramKilled
class namespace. Just dedent it and it becomes a module level variable. Functions that want to assign it later use global df
- but you're already doing that part correctly in your code.
Just change to
class ProgramKilled(Exception):
pass
df = pd.DataFrame([])
Upvotes: 0
Reputation: 13061
It means df is a class variable and not work.
class ProgramKilled(Exception):
pass
df = pd.DataFrame([])
If not a class variable, you should change it as following
class ProgramKilled(Exception):
pass
...
if __name__ == "__main__":
...
df = pd.DataFrame([])
...
If you need to define it there, I think it's not a good choice.
class ProgramKilled(Exception):
global df
df = pd.DataFrame([])
pass
Upvotes: 0