Google Colab session timeout - google-colaboratory

In the FAQs it is mentioned that
Virtual machines are recycled when idle for a while, and have a maximum lifetime enforced by the system.
Are the maximum lifetime and idle times fixed or variable? Is there any way to predict them?

PROBLEM:
I have to training my model for hours but the google colab keeps disconnecting after 30 mins automatically if I do not click frequently, leading to loss of all data.
SOLUTION:
Steps:
Open the inspector view by typing Ctrl+ Shift + i and then clicking on console tab at top.
Paste the below code snippet at bottom of console and hit enter
function ClickConnect(){
console.log("Working");
document.querySelector("#top-toolbar > colab-connect-button").shadowRoot.querySelector("#connect").click();
}
setInterval(ClickConnect,60000)
Believe me, that's all folks.
Above code would keep on clicking the page and prevent it from disconnecting.
Below is the image showing console view of above steps:-
Alternatively you can also try below snippet:
interval = setInterval(function() {
console.log("working")
var selector = "#top-toolbar > colab-connect-button"
document.querySelector(selector).shadowRoot.querySelector("#connect").click()
setTimeout(function() {
document.querySelector(selector).shadowRoot.querySelector("#connect").click()
}, 1000)
}, 60*1000)

It's 90 minutes if you close the browser. 12 hours if you keep the browser open. Additionally, if you close your browser with a code cell is running, if that same cell has not finished, when you reopen the browser it will still be running (the current executing cell keeps running even after browser is closed)

Improving to #Ashish Anand's answer
Use this code when you want to start:
function ClickConnect(){
console.log("Working");
document.querySelector("#top-toolbar > colab-connect-button").shadowRoot.querySelector("#connect").click();
}
var clicker = setInterval(ClickConnect,60000);
And the following code when you need to stop:
clearInterval(clicker);

Another way to overcome the session timeout is to run an autoclick script in python (especially if you intend not to use your computer while running your code in colab)
Here is the code : (Be sure to pip install pynput before)
import threading
from pynput.mouse import Button, Controller
from pynput.keyboard import Listener, KeyCode
delay = 20 #this is the delay of the autoclick (20 seconds here)
button = Button.left
start_stop_key = KeyCode(char='s')
exit_key = KeyCode(char='e')
class ClickMouse(threading.Thread):
def __init__(self, delay, button):
super(ClickMouse, self).__init__()
self.delay = delay
self.button = button
self.running = False
self.program_running = True
def start_clicking(self):
self.running = True
def stop_clicking(self):
self.running = False
def exit(self):
self.stop_clicking()
self.program_running = False
def run(self):
while self.program_running:
while self.running:
mouse.click(self.button)
time.sleep(self.delay)
time.sleep(0.1)
mouse = Controller()
click_thread = ClickMouse(delay, button)
click_thread.start()
def on_press(key):
if key == start_stop_key:
if click_thread.running:
click_thread.stop_clicking()
else:
click_thread.start_clicking()
elif key == exit_key:
click_thread.exit()
listener.stop()
with Listener(on_press=on_press) as listener:
listener.join()
Run this script on a commandline window, and then press the key "s" to start autoclicking and "e" for exit, than leave the mouse pointer on a code cell (normally it will click after a certain delay).

Related

PyQt5: Why does QPushButton.setDefault() ignore spacebar but work for enter/return?

I have a modal with two buttons, one Accept and one Cancel.
I set the cancel button to be the default with .setDefault() and .setAutoDefault()
Pressing return activates the cancel-button, but when I press spacebar the accept-button is activated.
Why is the application/accept-button ignoring the defaultness-configuration and activates on spacebar presses rather than the cancel button? It seems like the accept-button has focus or something despite there being a different default.
Why would the default not have focus?
If I call cancel_button.setFocus() just before showing the modal (but not earlier than that), even the spacebar will activate the Cancel-button instead of the Acccept-button, so that solves the underlying problem.
The question is why spacebar and enter do not both activate the default button.
Minimal example:
The modal shows up when the program is run, as well as when the user presses X.
Press ctrl+Q to close the application.
import sys
from PyQt5.QtCore import QSize, Qt
from PyQt5.QtGui import QKeySequence
from PyQt5.QtWidgets import QApplication, QMainWindow, QGroupBox, QHBoxLayout, QVBoxLayout, \
QWidget, QShortcut, QDialog, QPushButton
class Modal(QDialog):
def __init__(self, parent):
super().__init__(parent)
self.resize(QSize(600, 300))
self.setParent(parent)
self.setWindowModality(True)
layout = QVBoxLayout()
self.setLayout(layout)
buttons = self.create_buttons()
layout.addWidget(buttons)
# This sets focus (when pressing spacebar), and makes the modal work as expected.
# The question is why is this needed to make spacebar default to activating Cancel?
# Why is spacebar activating Accept by default without this line?:
#self.cancel_button.setFocus()
def create_buttons(self):
button_groupbox = QGroupBox()
button_box_layout = QHBoxLayout()
button_groupbox.setLayout(button_box_layout)
# Despite setting the defaultness, pressing spacebar still activates the accept-button.
# Pressing return activates the cancel-button, however, and is expected behaviour.
# Why is the Accept-button being activated when space is pressed?
accept_button = QPushButton("Accept")
accept_button.clicked.connect(self.accept)
accept_button.setDefault(False)
accept_button.setAutoDefault(False)
self.accept_button = accept_button
cancel_button = QPushButton("Cancel")
cancel_button.clicked.connect(self.reject)
cancel_button.setDefault(True)
cancel_button.setAutoDefault(True)
self.cancel_button = cancel_button
# This does not set focus (when pressing spacebar), maybe because it has not been added yet?
#cancel_button.setFocus()
button_box_layout.addWidget(accept_button)
button_box_layout.addWidget(cancel_button)
return button_groupbox
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
shortcut = QShortcut(QKeySequence("Ctrl+Q"), self)
shortcut.activated.connect(app.quit)
shortcut = QShortcut(QKeySequence("X"), self)
shortcut.activated.connect(self.run_modal)
self.resize(QSize(800, 600))
self.show()
def showEvent(self, event):
self.run_modal()
def run_modal(self):
self.modal = Modal(self)
self.modal.finished.connect(self.modal_finished)
self.modal.show()
def modal_finished(self, result):
if result == 0:
print("CANCEL")
elif result == 1:
print("ACCEPT")
else:
raise Exception("BAD RESULT")
if __name__ == '__main__':
app = QApplication(sys.argv)
mainwindow = MainWindow()
sys.exit(app.exec_())
By default, widgets receive focus based on the order in which they are added to a parent. When the top level window is shown, the first widget that accepts focus, following the order above, will receive input focus, meaning that any keyboard event will be sent to that widget first.
Note that when widgets are added to a layout, but were not created with the parent used for that layout, then the order follows that of the layout insertion.
The default property of QPushButtons, instead will "press" the button whenever the top level widget receives the Return or Enter keys are pressed, no matter of the current focused widget, and as long as the focused widget does not handle those keys.
In your case, the currently focused widget is the "Accept" button (since it's the first that has been added to the window), which results in the counter-intuitive behavior you're seeing.
If you want the cancel button to react to both Return/Enter keys (no matter what is the focused widget) and the space bar upon showing, then you have to explicitly call setFocus(). But there's a catch: since setFocus() sets the focus on a widget in the active window, it can only work as long as that widget already belongs to that window.
In your case, the cancel_button.setFocus() call done within create_buttons won't work because, at that point, the button doesn't belong to the top level window yet.
It does work when you do that after layout.addWidget(buttons), because then the button is part of the window.
So, considering the above:
if you want to set the focus on a widget, that widget must already belong to the top level widget before calling setFocus();
the default button will always be triggered upon Return/Enter keypress even if another button has focus;
With your current code, you either do what you already found out (using setFocus() on the instance attribute after adding the widget), or use a basic QTimer in the create_buttons function:
QTimer.singleShot(0, cancel_button.setFocus)
Note that:
while creating separate functions can help you to better organize your code, having a separate function that is just called once is often unnecessary (other than misleading and forcing the creation of instance attributes where they're not actually necessary); just separate code blocks with empty lines, unless those functions can be overridden by further subclasses;
setting a "Cancel" button that can be activated by Return/Enter is not a very good idea, as those keys are generally used for "Accept/Apply/Commit/Write/etc." purposes;
if you want to show a dialog as soon as its parent is shown, you shall only use a QTimer: QTimer.singleShot(0, self.run_modal); the paint event is certainly not a viable option (paint events occur very, very often, and in some systems even when the widget loses focus, which can cause recursion), nor is the showEvent() since that could happen when switching virtual desktops or unminimizing the window;

QBasicTimer can be used with threads started with QThread when selecting widget.setFocus(True)

I always get this error message.
QBasicTimer can be used with threads started with QThread when widget.setFocus()
Basically, I have a class Rotary which is listening to GPIO.
it has myForm.dial_on_value_changed() registered as a callback to Rotary which will call dial_on_value_changed() when rotator is rotated.
If myForm.dial_on_value_changed() only prints a text or string then it is fine. But if it selected one of myForm element and change its state such as setFocus(True), it will throw the above error, smth related with QThread.
My Application is a single thread and Rotari itself works based on listening to an interrupt in a GPIO pin which will call the registered callback function.
can someone tell me or guide me what I have done wrong? Or maybe a better way to solve this problem which is "A knob which will rotate and set all GUI element to be focused"
thanks in advance.
This is my snippet code
class MyForm(QDialog):
### creating a circular list
self._vt_dial_cycle = cycle([
# tuple UI element with a function
(self.vt_textedit, self.dial_to_vt),
(self.rr_textedit, self.dial_to_rr),
(self.stop_button, None),
(self.start_button, None),
(self.ie_textedit, self.dial_to_ie)
])
def dial_to_vt(self):
print("Dial on vt")
def dial_to_rr(self):
print("Dial on rr")
def dial_to_ie(self):
print("Dial on ie")
def dial_on_value_changed(self, direction):
# get next element from circular list.
(active_widget, action) = next(self._vt_dial_cycle)
self._current_widget = (active_widget, action)
#execute action manually registered with widget
action()
if isinstance(active_widget, QTextEdit):
self.move_cursor_to_end(active_widget)
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyForm()
w.show()
# ... a rotari with a knop
ky040 = KY040(CLOCKPIN, DATAPIN, SWITCHPIN, w.dial_on_value_changed, w.dial_on_pressed)
ky040.start()

Understanding Qt5 / PyQt5 focus behavior

I have a very simple test application:
from PyQt5.QtWidgets import *
import sys
import time
class Example(QWidget):
def __init__(self):
super().__init__()
self.pbar = QProgressBar(self)
self.pbar.setGeometry(30, 40, 200, 25)
self.btn = QPushButton('Start', self)
self.btn.move(40, 80)
self.btn.clicked.connect(self.do_action)
self.txt = QLineEdit('Some info goes here', self)
self.txt.setReadOnly(True)
self.txt.move(40, 120)
self.setGeometry(300, 300, 280, 170)
self.setWindowTitle("Python")
self.show()
def do_action(self):
# setting for loop to set value of progress bar
self.btn.setDisabled(True)
for i in range(101):
time.sleep(0.05)
self.pbar.setValue(i)
self.btn.setEnabled(True)
if __name__ == '__main__':
App = QApplication(sys.argv)
window = Example()
sys.exit(App.exec())
I have two, possibly related, problems with this code:
If I click on btn it dutifully starts QProgressBar updating and disables itself, but if I click on it twice I will see two iterations of the pbar; shouldn't clicks on a disabled widget be ignored?
As soon as btn is disabled txt contents are selected, in spite of it being ReadOnly; is there some way to prevent this "focusing next" behavior? Leaving everything unfocused till next click would be best.
Is this behavior considered "normal"?
The first issue is due to the fact that you used a blocking function (which should never happen) in event-driven systems like ui frameworks. What happens is that the for loop with the sleep function prevents Qt to correctly process events, including input events: your second click gets "queued" and can only be processed as soon as the control is returned to the event manager (when the function finally returns), and since, at that point, you've re-enabled the button, only then the previously queud event gets finally processed (and the function is called again).
The solution is simple: avoid any situation like this, if you need a time-based iteration, use a QTimer, if you need parallel and non blocking processing, use a QThread.

Check if it's possible to scroll down with RSelenium

I'm using RSelenium to automatically scroll down a social media website and save posts. Sometimes I get to the bottom of the webpage and no more posts can be loaded as no more data is available. I just want to be able to check if this is the case so I can stop trying to scroll.
How can I tell if it's possible to continue scrolling in RSelenium? The code below illustrates what I'm trying to do - I think I just need help with the "if" statement.
FYI there's a solution for doing this in Python here (essentially checking if page height changes between iterations), but I can't figure out how to implement it (or any another solution) in R.
# Open webpage
library(RSelenium)
rD = rsDriver(browser = "firefox")
remDr = rD[["client"]]
url = "https://stocktwits.com/symbol/NZDCHF"
remDr$navigate(url)
# Keep scrolling down page, loading new content each time.
ptm = proc.time()
repeat {
remDr$executeScript("window.scrollTo(0,document.body.scrollHeight);")
Sys.sleep(3) #delay by 3sec to give chance to load.
# Here's where i need help
if([INSERT CONDITION TO CHECK IF SCROLL DOWN IS POSSIBLE]) {
break
}
}
Stumbled across a way to do this in Python here and modified it to work in R. Below is a now-working update of the original code I posted above.
# Open webpage
library(RSelenium)
rD = rsDriver(browser = "firefox")
remDr = rD[["client"]]
url = "https://stocktwits.com/symbol/NZDCHF"
remDr$navigate(url)
# Keep scrolling down page, loading new content each time.
last_height = 0 #
repeat {
remDr$executeScript("window.scrollTo(0,document.body.scrollHeight);")
Sys.sleep(3) #delay by 3sec to give chance to load.
# Updated if statement which breaks if we can't scroll further
new_height = remDr$executeScript("return document.body.scrollHeight")
if(unlist(last_height) == unlist(new_height)) {
break
} else {
last_height = new_height
}
}

showandwait changing variable value

I'm having a problem with a variable I'm using to track the status of a user activity. In a GUI I have a button that, on clicking the button launches a second GUI. In that GUI, the user can either complete the activity started in the first GUI or not.
If the user cancels the second GUI, then the idea is to go back to the first GUI, leaving all variables and lists with their current values. If the second GUI completes the activity of the first GUI, then all variables and lists should be reset.
To track this, I have a variable (Boolean complete) initially set to FALSE. In the second GUI, when the "OK" button is clicked (rather than the "Cancel" button), the second GUI calls a method in the first GUI, changing the value of "complete" to TRUE.
To see what the heck is going on, I have System.out.println at several points allowing me to see the value of "complete" along the way. What I see is this:
Launching first GUI - complete = FALSE
Launching second GUI - complete = FALSE
Clicking "OK" in second GUI - complete = TRUE
Second GUI closes itself, returning to complete first GUI activity
First GUI finishes activity with complete = FALSE
I'm assuming it is because I am launching the second GUI with a showandwait, and when the method containing the showandwait begins, the value of "complete" = FALSE. The value changes in the WAIT part of show and wait, then the method continues and that is where I get the value still being FALSE, though it was changed to TRUE.
Here is a summary of the code in question (if you need exact code, it's longer, but I can post on request):
completeButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
try {
System.out.println("b4 calc = " + complete); // complete = FALSE
// all the code to create the calcStage
calcStage.showAndWait(); // second GUI, which calls a method in THIS
// class that changes complete to TRUE. That method
// (in THIS file) also has a println that shows the change.
getComplete(); // tried adding this method to check the value of
// "complete" after the change made by the calcStage
// (which calls a method in this same file)
System.out.println("Complete? " + complete);
// this shows complete = FALSE,
// though in the calcStage it was changed to TRUE
if (salecomplete) {
// code that should reset all variables and lists if the activity was completed
}
}
}
}
The question here is why does the second GUI successfully change the value of "complete", but when I return to the first GUI it still sees complete as FALSE? And how can I get around this?
Try having the controller of the second GUI calling a method in the first GUI's controller to modify that complete variable
For example:
// Code to handle the OK button being pressed
#Override
public void handle(ActionEvent t) {
// Do validation and work
//reference to the first controller object
firstController.setComplete(true);
}