CodeSkulptor time delay: no attribute 'sleep' - python

In CodeSkulptor (online Python coding page) I wrote a simple code, with a time delay. So simple:
import time
time.sleep(5)
print("random string")
When I press run, I got an error message: Line 2: AttributeError: '<invalid type>' object has no attribute 'sleep'
Any ideas what is wrong? Or how can I fix it?

You're doing javascript. You have to go to py3.codeskulptor.org. Your code works fine there.

The module time in CodeSkulptor implements only the time function:
http://www.codeskulptor.org/docs.html#Time
See the content of the module:
http://www.codeskulptor.org/#user44_uEhmhATcPLOytns.py
The documentation of CodeSkulptor3 mentions only the time function in the time module:
http://py3.codeskulptor.org/docs.html#Time
But the sleep function and other functions are present in the implementation:
http://py3.codeskulptor.org/#user301_4e5WktRmz4A193D.py
Note that in CodeSkulptor3 all printing waits the end of the sleep function. So this function is probably useless if you want wait before to print.

Related

Using schedule module to reming me to drink water every ten seconds

I am using schedule module to remind me to drink water every ten seconds
import schedule
def remindDrink():
print("Drink Water")
while True:
schedule.every().day.at("16:35").do(remindDrink())
So the problem here is that the task gets executed, but immedieately, not at the given time, and VSCode throws a weird error at me
Traceback (most recent call last):
File "e:\Code\Python Code\randomModule.py", line 12, in <module>
schedule.every().day.at("16:31").do(sendNotification())
File "C:\Users\PC\AppData\Local\Programs\Python\Python310\lib\site-packages\schedule\__init__.py", line 625, in do
self.job_func = functools.partial(job_func, *args, **kwargs)
TypeError: the first argument must be callable
PS E:\Code\Python Code>
This is the error, what am I doing wrong?
Same module different approach, I personally prefer this approach because it keeps my work clean, easy to read and to understand at your first glance and ofcourse easy to refactor.
from schedule import every, repeat, run_pending
import time
#repeat(every().day.at("16:35"))
def remindDrink():
print("Drink Water")
while True:
run_pending()
time.sleep(1)
Your broken code fixed:
Your broken code is fixed below, now the choice is yours, you can either use the above code or this:
import schedule
import time
def remindDrink():
print("Drink Water")
schedule.every().day.at("16:35").do(remindDrink)
while True:
schedule.run_pending()
time.sleep(1)
Remove the () from remindDrink() in the last line inside the do() function
Your code should look like this:
schedule.every().day.at("16:35").do(remindDrink)
Refer back to this question: TypeError: the first argument must be callable in scheduler library
quick thought, shedule....do(), within do() you don't run the function, just put the name of the function inside do.
'''
schedule.every().day.at("16:35").do(remindDrink)
'''

Forcing Micro:Bit Shutdown

I have this code for a parking system. When the number of spaces goes above 20 it sends and error message due to 20 being the limit of spaces. I want to try shutdown the program after this point.
I have tried doing what you can do in Python. This is:
import sys
display.scroll("Error: Limit exceeded.")
sys.exit()
This gives me an attribute error.
from microbit import *
import sys
elif spaces > 20:
display.scroll("Error: The spaces have exceeded the limit.")
sys.exit()
This should shutdown the program, not letting it to function, after the elif statement. There is more code (if statements, loops, function) but it is irrelevant.
Thanks :)
There's a couple ways I can think of.
In general, you can just enter an infinite loop, which will effectively halt everything, if there's no way to interrupt the loop:
while True:
microbit.sleep(1000000) # wait for 1000 seconds until the end of time
In micro:bit's documentation there's also microbit.panic(), which, quote, "requires a restart" of the micro:bit:
microbit.panic(0)
You could see if that works for you.
And since the micro:bit uses MicroPython as its Python implementation, you can look here in the MicroPython documentation:
import pyb
pyb.stop() # stop CPU, waiting for external interrupt
However, if an external interrupt does occur (and one might), the program would then probably continue.
Your code snippet is a bit misleading as it must be in a while True: loop. Just breakout of that outer loop.

How to cancel a request after 5 minutes without a reply

I have the following function,
import requests
def get_url_type(data):
x = {}
for i in range(0,len(data)):
print i
try:
x[i] = requests.head(data['url'][i]).headers.get('content-type')
except:
x[i] = 'Not Available'
return(x)
This function returns the URL type of each URL that is being passed to it and whenever there is no response, it throws error which is caught using exception. My problem here is, some of the requests take more than 5-10 mins time which is too much on production environment. I want the function to return "Not Available" when it takes more than 5 mins. When I did a research about it, it was mentioned to convert the function to asynchronous one. I have trying to change it without much success.
The following is what I have tried,
import asyncio
import time
from datetime import datetime
async def custom_sleep():
print('SLEEP', datetime.now())
time.sleep(5)
My objective is, whenever the request function takes more than 5 mins, it should return "Not available" and move to the next iteration.
Can anybody help me in doing this?
Thanks in advance !
It seems you just want a request to time out after a given time has passed without reply and move on to the next request. For this functionality there is a timeout parameter you can add to your request. The documentation on this: http://docs.python-requests.org/en/master/user/quickstart/#timeouts.
With a 300 seconds (5 minutes) timeout your code becomes:
requests.head(data['url'][i], timeout=300)
The asynchronous functionality you are mentioning has actually a different objective. It would allow your code to not have to wait the 5 minutes at all before continuing execution but I believe that would be a different question.

Recursion error using tkinter root.after

I'm making a tkinter program in which it will be needed to make the connection with Arduino via serial (but that's not very important).
Before explaining my problem, here is the code:
def arduino_makeConnection():
global arduino
try:
arduino = serial.Serial('/dev/ttyACM0', 9600, timeout = 0)
except:
print "Failed to connect"
if(time.time()-time_start<20):
root.after(0,arduino_makeConnection())
global time_start
time_start=time.time()
arduino_makeConnection()
So, I want to try to make connection via serial with the arduino only during 20s. After that time, I want it to give it up.
The problem is that my tkinter window doesn't open even though it prints in my console "Failed to connect" many many times until it gets the message (way before the 20 seconds have run off): RuntimeError: maximum recursion depth exceeded in cmp
I have tried to change time from 0 to 10 or 100ms on the root.after, but that doesn't solve the problem.
I think this has something to do with event handler, or something like that. However I thought that as I am not using a While or any other kind of loop, Tkinter would work...
Actually, before using the root.after I was making a While that was only breaking after the 20s or insead if the arduino was plugged in during that time. However when I searched in the internet, I realized that a loop in Tkinter is not a good idea. So, I changed to the root.after method, but now it's not working either!
Any help?
Thanks in advance!
Consider this code:
root.after(0,arduino_makeConnection())
This is exactly the same as this code:
result = arduino_makeConnection()
root.after(0, result)
And, assuming your function doesn't return anything, it's exactly the same as this:
root.after(0, None)
See the problem? The after command must be given a reference to a callable. In short, remove the parenthesis:
root.after(0,arduino_makeConnection)
Also, I highly recommend against using 0 (zero) as the first parameter. At the very least you should use 1 (one). A value of zero can have surprising side effects because you essentially create an infinite event queue that never empties.
If you tried to make an MCVE, you might come up with
import tkinter as tk
root = tk.Tk()
def callback():
print('callback')
root.after(0, callback())
callback()
This might make it more obvious that calling callback() calls callback() calls ..., until you get the recursion error. Remove the () in the root.after call. Also use a non-zero delay. Try the above with, for instance, `root.after(100, callback).

How to launch win32 applications in separate threads in Python

So, I am having this following snippet which attempts to start Microsoft Powerpoint through the win32api:
import threading
import win32com.client
import sys
class myDemo(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
try:
myObject = win32com.client.Dispatch("Powerpoint.Application")
print "OK"
except:
print "Failed to start Powerpoint!"
sys.exit(1)
print "Now attempting to shutdown..."
try:
myObject.quit()
except:
print "Error"
if __name__ == "__main__":
test = myDemo()
test.start()
The problem is that it fails and I have no clue why.
However, if I change the last line to test.run() it will launch successfully.
So again why is this failing with test.start()?
Why is this happening and how should I solve it considering I need Powerpoint to run on a seperate thread asynchronously?
Thanks in advance.
EDIT: Apparently my question is somehow related to this: http://python.6.x6.nabble.com/Dispatch-error-CoInitialize-has-not-been-called-td1951088.html
However apart from the proposed proper solution no one seems to answer why exactly COM is behaving this way.
I'm afraid your question likely can't be summed up in one or two sentences due to complexities in COM and threading and why they work the way they do. But for starters, here's some good information why COM behaves the way it does under threading:
http://msdn.microsoft.com/en-us/library/ms809971.aspx
Additionally, you should consider reviewing the book Python Programming on Win32. It contains useful information that sheds more light on COM threading. (Despite its age it is still useful.)
Finally, in case it wasn't clear from the reference you provided, whenever your program uses threads and COM, you must indicate in code that you're going to use COM within a thread:
import pythoncom
import win32com.client
### ... inside the thread function ...
x = win32com.client.Dispatch("someCOMobject")
win32com.CoInitialize()
# com calls here
win32com.CoUninitialize()
This type of call uses what's called single-apartment threading. It occurs when the threaded code itself instantiates COM objects.
If you find yourself instantiating a single COM object outside the threaded code (and using the instantiated object in the threaded code e.g. passing access to the COM object between threads), then this type of COM threading is called multithreaded-apartment threading:
import sys
sys.coinit_flags = 0
import pythoncom
import win32com.client
# ... outside the thread function ...
x = win32com.client.Dispatch("someCOMobject")
# ... inside the thread function ...
pythoncom.CoInitialize(pythoncom.COINIT_MULTITHREADED)
# com calls here for x
pythoncom.CoUninitialize()
Hope this helps.
OK, so I think I found an answer but I am not yet sure why it works..
If I cut and paste this line import win32com.client from the top of the page right inside the try block where I dispatch microsoft powerpoint, the app works successfully.
However, I still can't find out why.
There are at least two more ways to solve the issue:
Use run() method instead of start(), i.e. test.run()
Before myObject = win32com.client.Dispatch("Powerpoint.Application") insert the following lines: import pythoncom; CoInitialize()
Notice that using run() instead of start() has been tested in other scripts and it always worked for me!

Categories