Access Violation with wxPythons CallLater - python

I'm attempting to convert some of my code from Tkinter to wxPython. Currently I'm trying to create a function that continually loops, updating the time. However, I have run into some problems. Whenever I close the program, a window pops up, and gives me the following warning.
Access violation at address 1E058497 in module 'python26.dll'. Read of address 00000008.
This then causes my IDE (PyScripter) to freeze and crash. I think it may be trying to call the function after the program has been destroyed. This then causes it to access an unavailable location in memory, causing all sorts of fun. Any help would be appreciated.
Snippet:
def tick (self):
''' Continually updates the time. '''
TimeStr = '%I:%M %S %p'
DateStr = '%A, %B %d, %Y'
Time = time.strftime(TimeStr)
Date = time.strftime(DateStr)
self.TimeDate = Time + '\t\t' + Date
self.ST.SetLabel(self.TimeDate)
wx.CallLater(1000, self.tick)
In the Tkinter version wx.CallLater(1000, self.tick) was substituted with .after(1000, self.tick), If that helps.
Edit:
I tried it in IDLE and it seemed to work. However, no luck in PyScripter.

what you can do is:
(1)
self.scheduled_call = wx.CallLater(1000, self.tick)
during program close, cancel via, xxx.scheduled_call.??????()
I forgot the exact name of the method, please check wx docs.
OR if the above is not possible
(2) set a boolean variable in the instance, that controls the call.
if self.var: wx.CallLater(1000, self.tick)
var is True when program is running
during program close, set xxx.var to False

Related

Datetime object switches values during while loop interations

I'm seeing this weird issue in my Python code, and not quite sure what is going on. So quick backstory on the code, I've got a function that my UI script calls on startup that runs in a separate thread. This thread is intended to call a function in a separate module that checks to see if the stored timestamp in a database is older than x_value, and does stuff if that's true.
So here's the function (I can post more code later if needed, but this function is where the issue is happening):
def tableUpdateCheck(sensor_manager):
last_check = datetime.now()
print(f"last_check: {last_check.strftime('%m/%d/%Y_%H:%M:%S')}")
while RUN_TABLE_UPDATE_THREAD:
print(f"Now: {datetime.now().strftime('%H:%M:%S')}\tLast check time: {last_check.strftime('%H:%M:%S')}")
if datetime.now() - last_check > timedelta(seconds=60):
print('Running update table update check...')
sensor_manager.updateTables()
last_check = datetime.now()
time.sleep(5)
if __name__ == '__main__':
sensor_mgr = SensorManager()
table_thread = Thread(target=tableUpdateCheck, args=[sensor_mgr])
table_thread.start()
# Start webserver stuff
The resulting output looks like this:
Now: 17:49:13 Last check time: 17:49:13
Now: 17:49:18 Last check time: 17:49:10
Now: 17:49:23 Last check time: 17:49:13
Now: 17:49:28 Last check time: 17:49:10
Now: 17:49:33 Last check time: 17:49:13
Now: 17:49:38 Last check time: 17:49:10
And continues to do this until the if statement runs, and "last_check" goes back to fluctuating between two values.
Any thoughts on why this might be? It doesn't stop the overall program from ultimately doing what it's supposed to do, but it's super annoying.
So for anyone who might stumble across this in the future, it turns out that "app.run_server(debug=True)" in Flask apps causes an extra thread to run at start. I'm not 100% why this is the case, but that seems to be what's causing the problem I'm describing.
However, using a production Flask app, or simply setting the "debug" argument to False on a development server will not start the multiple threads, and this issue goes away.

Getting the exact system time during program execution

I'm doing an alarm clock and I want to print alarm raise if the system time is the same as the one being save but it turn out that while running the program the time became static that's why it didn't raise the alarm while the program is still executed.
How can I make the time not to be static during program execution? Just let me know if you need additional information. :)
def alarmClock(self):
timeString2 = time.strftime("%H:%M:%S")
getData = self.queryResultTable.get_children()
for data in getData:
for dataValue in self.queryResultTable.item(data)['values']: #sample data: 19:00:00 or 20:00:00
for timeData in timeString2:
if timeData == dataValue:
print('alarm Raise')
I would just check the time when you get to your conditional. This way it will check the time right before you are checking to see if an alarm should be raised. In my opinion this will be much simpler than having it run in the background the whole time. You don't need to make a new variable it would just look like this:
if time.ctime() == dataValue:
print("alarm Raise")

How to create a Python 'alarm' which will act either today or tomorrow

I have been given a python script which allows me to mute the volume of my mac at a time I set so that any podcasts I'm listening to as I fall asleep won't wake me up once I am asleep.
However, it will only act once the time given happens on that day, therefore if I try to activate it before midnight, it will mute the laptop immediately, which is not ideal because if I want to use it I have to wait for midnight to pass before I go to sleep.
#!/usr/bin/env python3
import datetime as dt
import osascript
import sys
from threading import Timer
def do_the_biz():
osascript.osascript("set volume output volume 0")
print("Night night")
today = dt.datetime.now()
dateString = today.strftime('%d-%m-%Y') + " " + sys.argv[1]
newDate = today.strptime(dateString,'%d-%m-%Y %H:%M')
delay = (newDate - dt.datetime.now()).total_seconds()
Timer(delay,do_the_biz,()).start()
So, a typical execution of this script looks like this:
$./sleep.py 04:00
and the command line will return the following once it has reached 4am, and then close the program:
Night Night
What I would like is to be able to manipulate the date so that the script will operate at the next available time of, for example, 4am - so it would essentially operate almost in the exact same way an alarm would. For this I could run an entirely different script of sleep.tomorrow.
However, in an ideal world, I would like to be able to:
have the option to have another argument where I specify today or tomorrow and the program acts accordingly;
be able to cancel the process without having to close the terminal.
I am new to python and have been having a hard time understanding the differences between the various datetime functions and the documention hasn't helped, so a brief explanation and comparison between what they input and output and how they interact would be gratefully appreciated.

How to make Tkinter python script take variable every X seconds?

First of excused my poor coding skills. Just started learning about a week ago
Anyway, I'm trying to right now create a GUI for this weather/clock thing for a project. Right now I need it so that the GUI, I was thinking of using Tkinter, updates every second and basically pulled strings from this program. Currently, the program calculates the time of sunrise and sunset and lunar cycle.
I tried two ways so far, the first method, running the entire program under one script, but it doesn't work due to the mainloop() prevent the calculation from repeating itself for the next day.
So now I was hoping to separate the program into two parts. One with the calculations and the other as the main GUI program. So what I did was basically.
Simplified Calculation Script (Its very long so I write the important part):
its day.py
import datetime
import math
import schedule
import astral
a = Astral()
def tick():
d = datetime.datetimee.today()
second = d.second
minutes = d.minute
hour = d.hour
month = d.month
print(str(hour) + ":" + str(minute) + ":" + str(second))
def mooninfo():
global percent_illuminate
global moon_phase
moon_phase = a.moon_phase(date=datetime.date(year,month,day)
percent_illuminate = VERY LONG EQUATIONS
print("Moon is at... " + str(moon_phase))
print(percent_illuminate)
schedule.every(1).second.do(tick)
schedule.every().day.do(mooninfo)
while True:
schedule.run_pending()
And for the tkinter script I tried
from day import moon_phase
Instead of just importing the moon_phase it started to run the program printing out the time of day nonstop.
So if anyone could help me
Let the tkinter script update everytime the different variable, second, minutes, hour, day, month, and moon_phase changed.
Or is there a way to get around the mainloop() of tkinter and just make it run while True: loop too?
Or any other better way to do it.
I saw that you can let Tkinter track the time making a digital clock of the sort but I need the calculations and also I am also sending variables over to an Arduino too (But I already figured that out).
Any help is greatly appreciated, thanks
You're importing a variable from a function. I think you should be importing the class (restructure day.py as a class first), then calling the mooninfo() method to return the value of the moon_phase variable.

Improperly creating timestamped filenames

I'm using a raspberry pi and a python script to capture images from a camera connected to the pi. I have a task scheduler that calls the script, and the script make a command line call that interfaces with the camera. I'm trying to have it create a new file titled with the timestamp taken from python's datetime module.
The problem I'm experiencing is that it won't print both. I can create a file with just the date timestamp; I can create one with just the time. When I try to combine both, however, the file isn't created, and I'm not sure why. Is it because the filename ends up being too long?
I've tried numerous variations of the code below:
import os
import time
import datetime
ts = time.time()
st = datetime.datetime.fromtimestamp(ts).strftime("%y-%m-%d_%H:%M:%S")
sys_call = 'fswebcam -r 1280x720 /home/pi/python/projectx_images/%s' %st
os.system(sys_call)
I've also tried using datetime.now() to no avail. Specifically, if I try either st = datetime.datetime.fromtimestamp(ts).strftime("%y-%m-%d') or st = datetime.datetime.fromtimestamp(ts).strftime("%H:%M:%S') then it works fine, but not with both.
Perhaps using Python is overkill here. Since your task scheduler is probably already invoking a shell when it invokes Python, let's just have the shell do the work.
Use this command for your command scheduler:
fswebcam -r 1280x720 /home/pi/python/projectx_images/$(date +%Y-%m-%d_%H:%M:%S)
Assuming...
st = datetime.datetime.fromtimestamp(ts).strftime("%y-%m-%d_%H:%M:%S') <--- close with " instead of '
isn't your problem... I've used the following code and it works for me.
ti = datetime.datetime.utcfromtimestamp(time.time()).strftime("%y-%m-%d_%H:%M:%S")
outputs...
'17-11-18_01:47:48'
Note: This outputs in UTC +0:00 so you'd need to apply another operation on it to get it to your timezone. Since time.time() returns a UNIX epoch time in seconds, you'd need to offset the time by however much faster/slower your timezone is, in relation to UTC +0:00, in seconds.
I.e. if you're in EST time, then you'd apply utcfromtimestamp() on time.time() - 18000 to get the time for your timezone.
ti = datetime.datetime.utcfromtimestamp(time.time() - 18000).strftime("%y-%m-%d_%H:%M:%S")

Categories